"""
Эндпоинты для оперативной справки техпос
"""
import logging
from fastapi import APIRouter, File, UploadFile, HTTPException, status
from fastapi.responses import JSONResponse

from adapters.storage import MinIOStorageAdapter
from adapters.parsers import OperSpravkaTechPosParser
from core.models import UploadRequest, DataRequest
from core.services import ReportService
from core.async_services import AsyncReportService
from app.schemas import UploadResponse, UploadErrorResponse
from app.schemas.oper_spravka_tech_pos import OperSpravkaTechPosRequest, OperSpravkaTechPosResponse

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("/oper_spravka_tech_pos/upload", tags=[OperSpravkaTechPosParser.name],
          summary="Загрузка файла отчета оперативной справки техпос",
          response_model=UploadResponse,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def upload_oper_spravka_tech_pos(
    file: UploadFile = File(..., description="ZIP архив с файлами оперативной справки техпос (.zip)")
):
    """Загрузка и обработка отчета оперативной справки техпос"""
    report_service = get_report_service()

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

        file_content = await file.read()
        request = UploadRequest(
            report_type='oper_spravka_tech_pos',
            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("/oper_spravka_tech_pos/get_data", tags=[OperSpravkaTechPosParser.name],
          summary="Получение данных из отчета оперативной справки техпос",
          response_model=OperSpravkaTechPosResponse)
async def get_oper_spravka_tech_pos_data(
    request_data: OperSpravkaTechPosRequest
):
    """Получение данных из отчета оперативной справки техпос"""
    report_service = get_report_service()

    try:
        request_dict = request_data.model_dump()
        request = DataRequest(
            report_type='oper_spravka_tech_pos',
            get_params=request_dict
        )

        result = report_service.get_data(request)

        if result.success:
            # Извлекаем данные из result.data["value"]
            data = result.data.get("value", []) if isinstance(result.data, dict) else result.data
            return OperSpravkaTechPosResponse(
                success=True,
                data=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/oper_spravka_tech_pos/upload", tags=[OperSpravkaTechPosParser.name],
          summary="Асинхронная загрузка файла отчета оперативной справки техпос",
          response_model=UploadResponse,
          include_in_schema=False,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def async_upload_oper_spravka_tech_pos(
    file: UploadFile = File(..., description="ZIP архив с файлами оперативной справки техпос (.zip)")
):
    """Асинхронная загрузка и обработка отчета оперативной справки техпос"""
    async_service = get_async_report_service()

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

        file_content = await file.read()
        request = UploadRequest(
            report_type='oper_spravka_tech_pos',
            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_400_BAD_REQUEST,
                content=UploadErrorResponse(
                    message=result.message,
                    error_code="UPLOAD_FAILED"
                ).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_ERROR"
            ).model_dump()
        )