from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from typing import List
from odoo import http
from odoo.addons.fastapi.dependencies import odoo_env

router = APIRouter(tags=["logistics"])


class LogisticsNodeResponse(BaseModel):
    uuid: str
    name: str
    latitude: float
    longitude: float
    country: str
    country_code: str
    transport_types: List[str]  # ['auto', 'rail', 'air', 'sea']


def get_node_transport_types(node) -> List[str]:
    """Получить список типов транспорта для узла из его соединений"""
    types = set()
    for conn in node.connection_ids:
        if conn.transport_category_id and conn.transport_category_id.code:
            types.add(conn.transport_category_id.code)
    return list(types)


class LogisticsRouteResponse(BaseModel):
    uuid: str
    name: str
    departure_node_uuid: str
    departure_node_name: str
    arrival_node_uuid: str
    arrival_node_name: str
    transport_type: str
    distance_km: float | None
    travel_time_hours: float
    active: bool


class LogisticsScheduleResponse(BaseModel):
    uuid: str
    name: str
    departure_node_uuid: str
    departure_node_name: str
    arrival_node_uuid: str
    arrival_node_name: str
    route_uuid: str | None
    transport_type: str
    departure_time: float
    frequency: str
    travel_time_hours: float | None
    active: bool


@router.get("/nodes")
def get_logistics_nodes(env=Depends(odoo_env)) -> List[LogisticsNodeResponse]:
    """Получить список всех логистических узлов"""

    LogisticsNode = env['logistics.node']
    nodes = LogisticsNode.search([])

    result = []
    for node in nodes:
        result.append(LogisticsNodeResponse(
            uuid=node.uuid,
            name=node.name,
            latitude=node.latitude,
            longitude=node.longitude,
            country=node.country_id.name if node.country_id else '',
            country_code=node.country_id.code if node.country_id else '',
            transport_types=get_node_transport_types(node)
        ))

    return result


@router.get("/nodes/{node_uuid}")
def get_logistics_node(node_uuid: str, env=Depends(odoo_env)) -> LogisticsNodeResponse:
    """Получить логистический узел по UUID"""

    LogisticsNode = env['logistics.node']
    node = LogisticsNode.search([('uuid', '=', node_uuid)], limit=1)

    if not node:
        raise HTTPException(status_code=404, detail=f"Node with UUID {node_uuid} not found")

    return LogisticsNodeResponse(
        uuid=node.uuid,
        name=node.name,
        latitude=node.latitude,
        longitude=node.longitude,
        country=node.country_id.name if node.country_id else '',
        country_code=node.country_id.code if node.country_id else '',
        transport_types=get_node_transport_types(node)
    )


@router.get("/routes")
def get_logistics_routes(env=Depends(odoo_env)) -> List[LogisticsRouteResponse]:
    """Get all active logistics routes"""

    LogisticsRoute = env['logistics.route']
    routes = LogisticsRoute.search([('active', '=', True)])

    result = []
    for route in routes:
        result.append(LogisticsRouteResponse(
            uuid=route.uuid if hasattr(route, 'uuid') else str(route.id),
            name=route.name,
            departure_node_uuid=route.departure_node_id.uuid,
            departure_node_name=route.departure_node_id.name,
            arrival_node_uuid=route.arrival_node_id.uuid,
            arrival_node_name=route.arrival_node_id.name,
            transport_type=route.transport_type,
            distance_km=route.distance_km,
            travel_time_hours=route.travel_time_hours,
            active=route.active
        ))

    return result


@router.get("/routes/{route_uuid}")
def get_logistics_route(route_uuid: str, env=Depends(odoo_env)) -> LogisticsRouteResponse:
    """Get logistics route by UUID"""

    LogisticsRoute = env['logistics.route']

    # Try to find by uuid field first, fallback to id
    route = LogisticsRoute.search([('uuid', '=', route_uuid)], limit=1)
    if not route:
        try:
            route = LogisticsRoute.browse(int(route_uuid))
            if not route.exists():
                route = None
        except (ValueError, TypeError):
            route = None

    if not route:
        raise HTTPException(status_code=404, detail=f"Route with UUID {route_uuid} not found")

    return LogisticsRouteResponse(
        uuid=route.uuid if hasattr(route, 'uuid') else str(route.id),
        name=route.name,
        departure_node_uuid=route.departure_node_id.uuid,
        departure_node_name=route.departure_node_id.name,
        arrival_node_uuid=route.arrival_node_id.uuid,
        arrival_node_name=route.arrival_node_id.name,
        transport_type=route.transport_type,
        distance_km=route.distance_km,
        travel_time_hours=route.travel_time_hours,
        active=route.active
    )


@router.get("/schedules")
def get_logistics_schedules(env=Depends(odoo_env)) -> List[LogisticsScheduleResponse]:
    """Get all active logistics schedules"""

    LogisticsSchedule = env['logistics.schedule']
    schedules = LogisticsSchedule.search([('active', '=', True)])

    result = []
    for schedule in schedules:
        result.append(LogisticsScheduleResponse(
            uuid=schedule.uuid if hasattr(schedule, 'uuid') else str(schedule.id),
            name=schedule.name,
            departure_node_uuid=schedule.departure_node_id.uuid,
            departure_node_name=schedule.departure_node_id.name,
            arrival_node_uuid=schedule.arrival_node_id.uuid,
            arrival_node_name=schedule.arrival_node_id.name,
            route_uuid=schedule.route_id.uuid if schedule.route_id and hasattr(schedule.route_id, 'uuid') else None,
            transport_type=schedule.route_id.transport_type if schedule.route_id else 'auto',
            departure_time=schedule.departure_time,
            frequency=schedule.frequency,
            travel_time_hours=schedule.route_id.travel_time_hours if schedule.route_id else None,
            active=schedule.active
        ))

    return result


@router.get("/schedules/{schedule_uuid}")
def get_logistics_schedule(schedule_uuid: str, env=Depends(odoo_env)) -> LogisticsScheduleResponse:
    """Get logistics schedule by UUID"""

    LogisticsSchedule = env['logistics.schedule']

    # Try to find by uuid field first, fallback to id
    schedule = LogisticsSchedule.search([('uuid', '=', schedule_uuid)], limit=1)
    if not schedule:
        try:
            schedule = LogisticsSchedule.browse(int(schedule_uuid))
            if not schedule.exists():
                schedule = None
        except (ValueError, TypeError):
            schedule = None

    if not schedule:
        raise HTTPException(status_code=404, detail=f"Schedule with UUID {schedule_uuid} not found")

    return LogisticsScheduleResponse(
        uuid=schedule.uuid if hasattr(schedule, 'uuid') else str(schedule.id),
        name=schedule.name,
        departure_node_uuid=schedule.departure_node_id.uuid,
        departure_node_name=schedule.departure_node_id.name,
        arrival_node_uuid=schedule.arrival_node_id.uuid,
        arrival_node_name=schedule.arrival_node_id.name,
        route_uuid=schedule.route_id.uuid if schedule.route_id and hasattr(schedule.route_id, 'uuid') else None,
        transport_type=schedule.route_id.transport_type if schedule.route_id else 'auto',
        departure_time=schedule.departure_time,
        frequency=schedule.frequency,
        travel_time_hours=schedule.route_id.travel_time_hours if schedule.route_id else None,
        active=schedule.active
    )
