from typing import List

from api.v1.modules.a76.doc_types_dig.dto import (
    DocumentTypeDigitizationCreate,
    DocumentTypeDigitizationResponse,
    DocumentTypeDigitizationUpdate,
)
from api.v1.modules.a76.doc_types_dig.models import DocumentTypeDigitization
from core.database import get_core_db
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session

router = APIRouter(prefix="/document-types-digitization", tags=["Document Types Digitization"])


@router.get("", response_model=List[DocumentTypeDigitizationResponse])
def get_all_document_types(
    active_only: bool = True,
    db: Session = Depends(get_core_db),
):
    """
    Obtener todos los tipos de documentos para digitalización
    
    Args:
        active_only: Si es True, solo devuelve los tipos activos
    """
    query = select(DocumentTypeDigitization)
    
    if active_only:
        query = query.where(DocumentTypeDigitization.active == True)
    
    query = query.order_by(DocumentTypeDigitization.code)
    
    result = db.execute(query)
    document_types = result.scalars().all()
    
    return document_types


@router.get("/{document_type_id}", response_model=DocumentTypeDigitizationResponse)
def get_document_type(
    document_type_id: int,
    db: Session = Depends(get_core_db),
):
    """Obtener un tipo de documento por ID"""
    result = db.execute(
        select(DocumentTypeDigitization).where(DocumentTypeDigitization.id == document_type_id)
    )
    document_type = result.scalar_one_or_none()
    
    if not document_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tipo de documento con ID {document_type_id} no encontrado"
        )
    
    return document_type


@router.get("/by-code/{code}", response_model=DocumentTypeDigitizationResponse)
def get_document_type_by_code(
    code: str,
    db: Session = Depends(get_core_db),
):
    """Obtener un tipo de documento por código"""
    result = db.execute(
        select(DocumentTypeDigitization).where(DocumentTypeDigitization.code == code)
    )
    document_type = result.scalar_one_or_none()
    
    if not document_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tipo de documento con código {code} no encontrado"
        )
    
    return document_type


@router.post("", response_model=DocumentTypeDigitizationResponse, status_code=status.HTTP_201_CREATED)
def create_document_type(
    document_type_data: DocumentTypeDigitizationCreate,
    db: Session = Depends(get_core_db),
):
    """Crear un nuevo tipo de documento"""
    # Verificar si el código ya existe
    result = db.execute(
        select(DocumentTypeDigitization).where(DocumentTypeDigitization.code == document_type_data.code)
    )
    existing = result.scalar_one_or_none()
    
    if existing:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"Ya existe un tipo de documento con el código {document_type_data.code}"
        )
    
    new_document_type = DocumentTypeDigitization(**document_type_data.model_dump())
    db.add(new_document_type)
    db.commit()
    db.refresh(new_document_type)
    
    return new_document_type


@router.put("/{document_type_id}", response_model=DocumentTypeDigitizationResponse)
def update_document_type(
    document_type_id: int,
    document_type_data: DocumentTypeDigitizationUpdate,
    db: Session = Depends(get_core_db),
):
    """Actualizar un tipo de documento existente"""
    result = db.execute(
        select(DocumentTypeDigitization).where(DocumentTypeDigitization.id == document_type_id)
    )
    document_type = result.scalar_one_or_none()
    
    if not document_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tipo de documento con ID {document_type_id} no encontrado"
        )
    
    # Actualizar solo los campos proporcionados
    update_data = document_type_data.model_dump(exclude_unset=True)
    
    # Verificar si el nuevo código ya existe (si se está actualizando)
    if "code" in update_data and update_data["code"] != document_type.code:
        result = db.execute(
            select(DocumentTypeDigitization).where(DocumentTypeDigitization.code == update_data["code"])
        )
        existing = result.scalar_one_or_none()
        if existing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"Ya existe un tipo de documento con el código {update_data['code']}"
            )
    
    for field, value in update_data.items():
        setattr(document_type, field, value)
    
    db.commit()
    db.refresh(document_type)
    
    return document_type


@router.delete("/{document_type_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_document_type(
    document_type_id: int,
    db: Session = Depends(get_core_db),
):
    """Eliminar un tipo de documento (soft delete, marca como inactivo)"""
    result = db.execute(
        select(DocumentTypeDigitization).where(DocumentTypeDigitization.id == document_type_id)
    )
    document_type = result.scalar_one_or_none()
    
    if not document_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Tipo de documento con ID {document_type_id} no encontrado"
        )
    
    # Soft delete - solo marcar como inactivo
    document_type.active = False
    db.commit()
    
    return None
