"""
Эндпоинты для мониторинга ТАР
"""
import logging
from fastapi import APIRouter, File, UploadFile, HTTPException, status
from fastapi.responses import JSONResponse

from adapters.storage import MinIOStorageAdapter
from adapters.parsers import MonitoringTarParser
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.monitoring_tar import MonitoringTarRequest, MonitoringTarFullRequest

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("/monitoring_tar/upload", tags=[MonitoringTarParser.name],
          summary="Загрузка файла отчета мониторинга ТАР",
          response_model=UploadResponse,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def upload_monitoring_tar(
    file: UploadFile = File(..., description="Excel файл мониторинга ТАР (.xlsx, .xlsm, .xls)")
):
    """Загрузка и обработка отчета мониторинга ТАР"""
    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='monitoring_tar',
            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("/monitoring_tar/get_data", tags=[MonitoringTarParser.name],
          summary="Получение данных из отчета мониторинга ТАР")
async def get_monitoring_tar_data(
    request_data: MonitoringTarRequest
):
    """Получение данных из отчета мониторинга ТАР"""
    report_service = get_report_service()

    try:
        request_dict = request_data.model_dump()
        request = DataRequest(
            report_type='monitoring_tar',
            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("/monitoring_tar/get_full_data", tags=[MonitoringTarParser.name],
          summary="Получение полных данных из отчета мониторинга ТАР")
async def get_monitoring_tar_full_data(
    request_data: MonitoringTarFullRequest
):
    """Получение полных данных из отчета мониторинга ТАР"""
    report_service = get_report_service()

    try:
        request_dict = request_data.model_dump()
        request = DataRequest(
            report_type='monitoring_tar',
            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/monitoring_tar/upload", tags=[MonitoringTarParser.name],
          summary="Асинхронная загрузка файла отчета мониторинга ТАР",
          response_model=UploadResponse,
          include_in_schema=False,
          responses={
              400: {"model": UploadErrorResponse, "description": "Неверный формат файла"},
              500: {"model": UploadErrorResponse, "description": "Внутренняя ошибка сервера"}
          },)
async def async_upload_monitoring_tar(
    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='monitoring_tar',
            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()
        )