from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from typing import Optional, List
from . import repository
from .schema import BusCreate, BusUpdate, BusResponse


def create_bus(db: Session, data: BusCreate) -> BusResponse:
    existing_bus = repository.get_by_bus_number(db, data.bus_number)
    if existing_bus:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Bus with number {data.bus_number} already exists"
        )
    
    bus_data = data.model_dump()
    bus = repository.create(db, bus_data)
    
    db.commit()
    db.refresh(bus)
    
    return BusResponse.model_validate(bus)


def get_bus(db: Session, bus_id: str) -> BusResponse:
    bus = repository.get_by_id(db, bus_id)
    if not bus:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Bus with ID {bus_id} not found"
        )
    
    return BusResponse.model_validate(bus)


def list_buses(
    db: Session,
    limit: int,
    offset: int,
    bus_type: Optional[str] = None,
    is_active: Optional[bool] = None,
) -> List[BusResponse]:
    buses = repository.list_all(db, limit, offset, bus_type, is_active)
    return [BusResponse.model_validate(bus) for bus in buses]


def update_bus(db: Session, bus_id: str, data: BusUpdate) -> BusResponse:
    bus = repository.get_by_id(db, bus_id)
    if not bus:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Bus with ID {bus_id} not found"
        )
    
    update_data = data.model_dump(exclude_unset=True)
    
    if "bus_number" in update_data and update_data["bus_number"] != bus.bus_number:
        existing_bus = repository.get_by_bus_number(db, update_data["bus_number"])
        if existing_bus:
            raise HTTPException(
                status_code=status.HTTP_409_CONFLICT,
                detail=f"Bus with number {update_data['bus_number']} already exists"
            )
    
    if not update_data:
        return BusResponse.model_validate(bus)
    
    updated_bus = repository.update(db, bus_id, update_data)
    
    db.commit()
    db.refresh(updated_bus)
    
    return BusResponse.model_validate(updated_bus)


def delete_bus(db: Session, bus_id: str) -> dict:
    bus = repository.get_by_id(db, bus_id)
    if not bus:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Bus with ID {bus_id} not found"
        )
    
    success = repository.delete(db, bus_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to delete bus"
        )
    
    db.commit()
    
    return {"message": "Bus deleted successfully"}