from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware

from new_parser_test import parse_request
from geocoder import validate_address
from database import search_database
from route import build_route
from ouput_chat import RouteDescriber

app = FastAPI(title="AI API")

# ======== FASTAPI СХЕМЫ ==========

class ChatRequest(BaseModel):
    user_input: str
    conversation_history: list | None = None

class ChatResponse(BaseModel):
    success: bool
    need_more_info: bool
    # result теперь может содержать как промежуточные данные парсера,
    # так и финальный маршрут с описанием
    result: dict
    conversation_history: list
    error: str | None = None

# =================================

@app.post("/chat", response_model=ChatResponse)
def chat_endpoint(request: ChatRequest):
    try:
        # 1. Вызываем парсер, чтобы извлечь информацию из диалога
        parser_response = parse_request(request.user_input, request.conversation_history)

        # 2. Проверяем условие: парсер отработал успешно и больше информации не нужно
        if parser_response["success"] and not parser_response["need_more_info"]:
            # --- Логика построения маршрута ---

            parsed_data = parser_response["result"]
            tags = parsed_data.get("tags")
            print(tags)
            user_address = parsed_data.get("user_location")
            print(user_address)
            user_time = parsed_data.get("time")
            print(user_time)
            conversation_history = parser_response["conversation_history"]

            # Валидация адреса
            val_output = validate_address('addresses.sqlite', user_address)
            if not val_output or not val_output['valid']:
                return ChatResponse(
                    success=False,
                    need_more_info=False,
                    result={},
                    conversation_history=conversation_history,
                    error=f"Не удалось распознать адрес: {user_address}. Пожалуйста, попробуйте указать его точнее."
                )

            user_position = [
                val_output['coordinates']['lat'],
                val_output['coordinates']['lon']
            ]

            # Поиск точек в базе данных
            found_points, mapping = search_database('output.json', tags)
            if not found_points:
                return ChatResponse(
                    success=False,
                    need_more_info=False,
                    result={},
                    conversation_history=conversation_history,
                    error="К сожалению, я не смог найти подходящих мест по вашему запросу."
                )

            print(mapping)

            # Построение маршрута
            n_nodes = len(mapping)
            allow_extend = any(v[1] for v in mapping.values())

            route_otp = None
            if allow_extend:
                while n_nodes <= 5 and (route_otp := build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random') or route_otp): n_nodes += 1
            else:
                route_otp= build_route(found_points, mapping, user_position, user_time, n_nodes,strategy='random')

            if not route_otp:
                return ChatResponse(
                    success=False,
                    need_more_info=False,
                    result={},
                    conversation_history=conversation_history,
                    error="Не удалось построить маршрут с указанными параметрами. Попробуйте изменить запрос."
                )

            route, places = route_otp
            route.insert(0, user_position)

            # Генерация описания маршрута
            describer = RouteDescriber()
            description = describer.generate_route_description(places, conversation_history)

            # Финальный успешный ответ с маршрутом
            return ChatResponse(
                success=True,
                need_more_info=False,
                result={
                    "route": route,
                    "description": description,
                    "places": places
                },
                conversation_history=conversation_history,
                error=None
            )

        else:
            # 3. Если парсеру нужно больше информации или он завершился неуспешно,
            # просто возвращаем его ответ пользователю.
            # `ChatResponse` и словарь от `parse_request` имеют одинаковую структуру.
            return ChatResponse(**parser_response)

    except Exception as e:
        # Отлавливаем любые другие непредвиденные ошибки
        # В рабочей среде здесь лучше добавить логирование
        print(f"An unexpected error occurred: {e}")
        raise HTTPException(status_code=500, detail="Произошла внутренняя ошибка сервера.")


origins = [
    "http://localhost",
    "http://localhost:5173",
    "https://4zoh-p9j8-3c1z.gw-1a.dockhost.net",
    "https://leadership.unn.nikidze.ru"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
    max_age=3600
)
