from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from typing import Optional, List
from . import repository
from .schema import RouteCreate, RouteUpdate, RouteResponse


def create_route(db: Session, data: RouteCreate) -> RouteResponse:
    existing_route = repository.get_by_cities(db, data.origin_city, data.destination_city)
    if existing_route:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=f"Route from {data.origin_city} to {data.destination_city} already exists",
        )
    
    route_data = data.model_dump()
    route = repository.create(db, route_data)
    db.commit()
    db.refresh(route)
    return RouteResponse.model_validate(route)


def get_route(db: Session, route_id: str) -> RouteResponse:
    route = repository.get_by_id(db, route_id)
    if not route:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Route with id {route_id} not found",
        )
    return RouteResponse.model_validate(route)


def list_routes(
    db: Session,
    limit: int,
    offset: int,
    origin_city: Optional[str] = None,
    destination_city: Optional[str] = None,
    is_active: Optional[bool] = None,
) -> List[RouteResponse]:
    routes = repository.list_all(
        db,
        limit=limit,
        offset=offset,
        origin_city=origin_city,
        destination_city=destination_city,
        is_active=is_active,
    )
    return [RouteResponse.model_validate(route) for route in routes]


def update_route(db: Session, route_id: str, data: RouteUpdate) -> RouteResponse:
    route = repository.get_by_id(db, route_id)
    if not route:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Route with id {route_id} not found",
        )
    
    update_data = data.model_dump(exclude_unset=True)
    
    if "origin_city" in update_data or "destination_city" in update_data:
        new_origin = update_data.get("origin_city", route.origin_city)
        new_destination = update_data.get("destination_city", route.destination_city)
        
        if new_origin != route.origin_city or new_destination != route.destination_city:
            existing_route = repository.get_by_cities(db, new_origin, new_destination)
            if existing_route and existing_route.id != route_id:
                raise HTTPException(
                    status_code=status.HTTP_409_CONFLICT,
                    detail=f"Route from {new_origin} to {new_destination} already exists",
                )
    
    updated_route = repository.update(db, route_id, update_data)
    db.commit()
    db.refresh(updated_route)
    return RouteResponse.model_validate(updated_route)


def delete_route(db: Session, route_id: str) -> dict:
    route = repository.get_by_id(db, route_id)
    if not route:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Route with id {route_id} not found",
        )
    
    success = repository.delete(db, route_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to delete route",
        )
    
    db.commit()
    return {"message": "Route deleted successfully"}