"""
Эндпоинты для сводки СА
"""
import logging
from fastapi import APIRouter, File, UploadFile, HTTPException, status
from fastapi.responses import JSONResponse

from adapters.storage import MinIOStorageAdapter
from adapters.parsers import SvodkaCAParser
from core.models import UploadRequest, DataRequest
from core.services import ReportService
from core.async_services import AsyncReportService
from app.schemas import UploadResponse, UploadErrorResponse, SvodkaCARequest

logger = logging.getLogger(__name__)

# Создаем роутер для сводки СА
router = APIRouter()


def get_report_service() -> ReportService:
    """Получение экземпляра сервиса отчетов"""
    storage_adapter = MinIOStorageAdapter()
    return ReportService(storage_adapter)


def get_async_report_service() -> AsyncReportService:
    """Получение экземпляра асинхронного сервиса отчетов"""
    from core.services import ReportService
    storage_adapter = MinIOStorageAdapter()
    report_service = ReportService(storage_adapter)
    return AsyncReportService(report_service)


@router.post("/svodka_ca/upload", tags=[SvodkaCAParser.name],
          summary="Загрузка файла отчета сводки СА",
          response_model=UploadResponse,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def upload_svodka_ca(
    file: UploadFile = File(..., description="Excel файл сводки СА (.xlsx, .xlsm, .xls)")
):
    """Загрузка и обработка отчета сводки СА

    ### Поддерживаемые форматы:
    - **Excel файлы** (.xlsx, .xlsm, .xls)

    ### Структура данных:
    - Обрабатывает Excel файлы с данными по режимам и таблицам
    - Извлекает данные по указанным режимам (plan, fact, normativ)
    - Возвращает агрегированные данные по таблицам

    ### Пример использования:
    1. Подготовьте Excel файл сводки СА
    2. Загрузите файл через этот эндпоинт
    3. Используйте полученный `object_id` для запросов данных
    """
    report_service = get_report_service()

    try:
        # Проверяем тип файла
        if not file.filename.endswith(('.xlsx', '.xlsm', '.xls')):
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content=UploadErrorResponse(
                    message="Поддерживаются только Excel файлы (.xlsx, .xlsm, .xls)",
                    error_code="INVALID_FILE_TYPE",
                    details={
                        "expected_formats": [".xlsx", ".xlsm", ".xls"],
                        "received_format": file.filename.split('.')[-1] if '.' in file.filename else "unknown"
                    }
                ).model_dump()
            )

        # Читаем содержимое файла
        file_content = await file.read()

        # Создаем запрос
        request = UploadRequest(
            report_type='svodka_ca',
            file_content=file_content,
            file_name=file.filename
        )

        # Загружаем отчет
        result = report_service.upload_report(request)

        if result.success:
            return UploadResponse(
                success=True,
                message=result.message,
                object_id=result.object_id
            )
        else:
            return JSONResponse(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                content=UploadErrorResponse(
                    message=result.message,
                    error_code="ERR_UPLOAD"
                ).model_dump(),
            )

    except HTTPException:
        raise
    except Exception as e:
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content=UploadErrorResponse(
                message=f"Внутренняя ошибка сервера: {str(e)}",
                error_code="INTERNAL_SERVER_ERROR"
            ).model_dump()
        )


@router.post("/svodka_ca/get_data", tags=[SvodkaCAParser.name],
          summary="Получение данных из отчета сводки СА")
async def get_svodka_ca_data(
    request_data: SvodkaCARequest
):
    """Получение данных из отчета сводки СА по указанным режимам и таблицам

    ### Структура параметров:
    - `modes`: **Массив кодов** режимов - `plan`, `fact` или `normativ` (обязательный)
    - `tables`: **Массив названий** таблиц как есть (обязательный)

    ### Пример тела запроса:
    ```json
    {
        "modes": ["plan", "fact"],
        "tables": ["ТиП, %", "Топливо итого, тонн", "Топливо итого, %", "Потери итого, тонн"]
    }
    ```
    """
    report_service = get_report_service()

    try:
        # Создаем запрос
        request_dict = request_data.model_dump()
        request = DataRequest(
            report_type='svodka_ca',
            get_params=request_dict
        )

        # Получаем данные
        result = report_service.get_data(request)

        if result.success:
            return {
                "success": True,
                "data": result.data
            }
        else:
            raise HTTPException(status_code=404, detail=result.message)

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Внутренняя ошибка сервера: {str(e)}")


@router.post("/async/svodka_ca/upload", tags=[SvodkaCAParser.name],
          summary="Асинхронная загрузка файла отчета сводки СА",
          response_model=UploadResponse,
          include_in_schema=False,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def async_upload_svodka_ca(
    file: UploadFile = File(..., description="Excel файл сводки СА (.xlsx, .xlsm, .xls)")
):
    """Асинхронная загрузка и обработка отчета сводки СА"""
    async_service = get_async_report_service()
    try:
        # Проверяем тип файла
        if not file.filename.endswith(('.xlsx', '.xlsm', '.xls')):
            return JSONResponse(
                status_code=status.HTTP_400_BAD_REQUEST,
                content=UploadErrorResponse(
                    message="Поддерживаются только Excel файлы (.xlsx, .xlsm, .xls)",
                    error_code="INVALID_FILE_TYPE",
                    details={
                        "expected_formats": [".xlsx", ".xlsm", ".xls"],
                        "received_format": file.filename.split('.')[-1] if '.' in file.filename else "unknown"
                    }
                ).model_dump()
            )

        # Читаем содержимое файла
        file_content = await file.read()

        # Создаем запрос
        request = UploadRequest(
            report_type='svodka_ca',
            file_content=file_content,
            file_name=file.filename
        )

        # Загружаем отчет асинхронно
        result = await async_service.upload_report_async(request)

        if result.success:
            return UploadResponse(
                success=True,
                message=result.message,
                object_id=result.object_id
            )
        else:
            return JSONResponse(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                content=UploadErrorResponse(
                    message=result.message,
                    error_code="ERR_UPLOAD"
                ).model_dump(),
            )

    except Exception as e:
        logger.error(f"Ошибка при асинхронной загрузке сводки СА: {str(e)}")
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content=UploadErrorResponse(
                message=f"Внутренняя ошибка сервера: {str(e)}",
                error_code="INTERNAL_SERVER_ERROR"
            ).model_dump()
        )