import logging

from datetime import date
from typing import Optional, List
from sqlalchemy.ext.asyncio import AsyncSession
from models.omie_contas_receber import OmieContaReceber
from models.omie_contas_receber_boleto import OmieContaReceberBoleto
from crud.omie_contas_receber import crud_contas_receber, crud_boletos, crud_boleto_completo

logger = logging.getLogger(__name__)

class OmieContaReceberService:
    @staticmethod
    async def listar(
        db: AsyncSession,
        *,
        cnpj: Optional[str] = None,
        data_inicio: Optional[date] = None,
        data_fim: Optional[date] = None,
        status: Optional[str] = None,
    ) -> List[OmieContaReceber]:
        """Lista contas a receber com filtros opcionais"""
        logger.debug(f"OmieContaReceberService.listar chamado")
        try:
            result = await crud_contas_receber.list(
                db, 
                cnpj=cnpj, 
                data_inicio=data_inicio, 
                data_fim=data_fim, 
                status=status
            )
            logger.debug(f"OmieContaReceberService.listar retornou {len(result)} registros")
            return result
        except Exception as e:
            logger.error(f"Erro em OmieContaReceberService.listar: {e}", exc_info=True)
            raise

class OmieContaReceberBoletoService:
    @staticmethod
    async def listar(
        db: AsyncSession,
        *,
        codigo_lancamento: Optional[str] = None,
        data_inicio: Optional[date] = None,
        data_fim: Optional[date] = None,
        status: Optional[str] = None,
    ) -> List[OmieContaReceberBoleto]:
        """Lista boletos com filtros opcionais"""
        logger.debug(f"OmieContaReceberBoletoService.listar chamado")
        try:
            result = await crud_boletos.list(
                db, 
                codigo_lancamento=codigo_lancamento, 
                data_inicio=data_inicio, 
                data_fim=data_fim, 
                status=status
            )
            logger.debug(f"OmieContaReceberBoletoService.listar retornou {len(result)} registros")
            return result
        except Exception as e:
            logger.error(f"Erro em OmieContaReceberBoletoService.listar: {e}", exc_info=True)
            raise

class OmieBoletoCompletoService:
    @staticmethod
    async def listar_completo(
        db: AsyncSession,
        *,
        cnpj: Optional[str] = None,
        data_vencimento_inicio: Optional[date] = None,
        data_vencimento_fim: Optional[date] = None,
        data_emissao_boleto_inicio: Optional[date] = None,
        data_emissao_boleto_fim: Optional[date] = None,
        status_titulo: Optional[str] = None,
        pago: Optional[bool] = None,
    ) -> List:
        """Lista boletos completos com JOIN (inclui CNPJ, data de vencimento e data de emissão do boleto)"""
        logger.debug(f"OmieBoletoCompletoService.listar_completo chamado")
        try:
            result = await crud_boleto_completo.list_completo(
                db,
                cnpj=cnpj,
                data_vencimento_inicio=data_vencimento_inicio,
                data_vencimento_fim=data_vencimento_fim,
                data_emissao_boleto_inicio=data_emissao_boleto_inicio,
                data_emissao_boleto_fim=data_emissao_boleto_fim,
                status_titulo=status_titulo,
                pago=pago,
            )
            logger.debug(f"OmieBoletoCompletoService.listar_completo retornou {len(result)} registros")
            return result
        except Exception as e:
            logger.error(f"Erro em OmieBoletoCompletoService.listar_completo: {e}", exc_info=True)
            raise