from typing import List, Optional

from ...domain.repositories.consultor_repository import ConsultorRepository
from ...domain.entities.consultor import Consultor
from ..dtos.consultor_dto import (
    ConsultorResumoDTO,
    ConsultorDetalhadoDTO,
    PeriodoDTO,
    CoordenacaoCapesDTO,
    ConsultoriaDTO,
    IESDTO,
    VinculoConsultoriaDTO,
    InscricaoDTO,
    AvaliacaoComissaoDTO,
    PremiacaoDTO,
    BolsaCNPQDTO,
    ParticipacaoDTO,
    OrientacaoDTO,
    MembroBancaDTO,
    PontuacaoAtuacaoDTO,
    PontuacaoBlocoDTO,
    PontuacaoCompletaDTO,
)


class ObterRankingUseCase:
    def __init__(self, repository: ConsultorRepository):
        self.repository = repository

    async def executar(
        self, limite: int = 100, componente: Optional[str] = None
    ) -> List[ConsultorResumoDTO]:
        consultores = await self.repository.buscar_ranking(limite=limite, componente=componente)

        return [
            ConsultorResumoDTO(
                id_pessoa=c.id_pessoa,
                nome=c.nome,
                anos_atuacao=c.anos_atuacao,
                ativo=c.ativo,
                veterano=c.veterano,
                pontuacao_total=c.pontuacao_total,
                bloco_a=c.pontuacao_bloco_a,
                bloco_c=c.pontuacao_bloco_c,
                bloco_d=c.pontuacao_bloco_d,
                rank=idx + 1,
            )
            for idx, c in enumerate(consultores)
        ]

    async def executar_detalhado(
        self, limite: int = 100, componente: Optional[str] = None
    ) -> List[ConsultorDetalhadoDTO]:
        consultores = await self.repository.buscar_ranking(limite=limite, componente=componente)
        return [self._converter_para_dto_detalhado(c, idx + 1) for idx, c in enumerate(consultores)]

    def _converter_para_dto_detalhado(
        self, consultor: Consultor, rank: int
    ) -> ConsultorDetalhadoDTO:
        return ConsultorDetalhadoDTO(
            id_pessoa=consultor.id_pessoa,
            nome=consultor.nome,
            anos_atuacao=consultor.anos_atuacao,
            ativo=consultor.ativo,
            veterano=consultor.veterano,
            coordenador_ppg=consultor.coordenador_ppg,
            coordenacoes_capes=[
                CoordenacaoCapesDTO(
                    codigo=cc.codigo,
                    tipo=cc.tipo,
                    area_avaliacao=cc.area_avaliacao,
                    periodo=PeriodoDTO(
                        inicio=cc.periodo.inicio.isoformat() if cc.periodo.inicio else "",
                        fim=cc.periodo.fim.isoformat() if cc.periodo.fim else None,
                        ativo=cc.periodo.ativo,
                        anos_decorridos=cc.periodo.anos_decorridos,
                    ),
                    areas_adicionais=cc.areas_adicionais,
                    ja_coordenou_antes=cc.ja_coordenou_antes,
                    presidente=cc.presidente,
                )
                for cc in consultor.coordenacoes_capes
            ],
            consultoria=ConsultoriaDTO(
                codigo=consultor.consultoria.codigo,
                situacao=consultor.consultoria.situacao,
                periodo=PeriodoDTO(
                    inicio=consultor.consultoria.periodo.inicio.isoformat() if consultor.consultoria.periodo.inicio else "",
                    fim=consultor.consultoria.periodo.fim.isoformat() if consultor.consultoria.periodo.fim else None,
                    ativo=consultor.consultoria.periodo.ativo,
                    anos_decorridos=consultor.consultoria.periodo.anos_decorridos,
                ),
                areas=consultor.consultoria.areas,
                anos_consecutivos=consultor.consultoria.anos_consecutivos,
                retornos=consultor.consultoria.retornos,
                vinculos=[
                    VinculoConsultoriaDTO(
                        periodo=PeriodoDTO(
                            inicio=v.periodo.inicio.isoformat() if v.periodo.inicio else "",
                            fim=v.periodo.fim.isoformat() if v.periodo.fim else None,
                            ativo=v.periodo.ativo,
                            anos_decorridos=v.periodo.anos_decorridos,
                        ),
                        ies=IESDTO(
                            id=v.ies.id,
                            nome=v.ies.nome,
                            sigla=v.ies.sigla,
                        ) if v.ies else None,
                        situacao=v.situacao,
                    )
                    for v in consultor.consultoria.vinculos
                ],
            ) if consultor.consultoria else None,
            inscricoes=[
                InscricaoDTO(
                    codigo=i.codigo,
                    tipo=i.tipo,
                    premio=i.premio,
                    ano=i.ano,
                    situacao=i.situacao,
                )
                for i in consultor.inscricoes
            ],
            avaliacoes_comissao=[
                AvaliacaoComissaoDTO(
                    codigo=a.codigo,
                    tipo=a.tipo,
                    premio=a.premio,
                    ano=a.ano,
                    comissao_tipo=a.comissao_tipo,
                    nome_comissao=a.nome_comissao,
                )
                for a in consultor.avaliacoes_comissao
            ],
            premiacoes=[
                PremiacaoDTO(
                    codigo=p.codigo,
                    tipo=p.tipo,
                    nome_premio=p.nome_premio,
                    ano=p.ano,
                    papel=p.papel,
                )
                for p in consultor.premiacoes
            ],
            bolsas_cnpq=[
                BolsaCNPQDTO(
                    codigo=b.codigo,
                    nivel=b.nivel,
                    area=b.area,
                )
                for b in consultor.bolsas_cnpq
            ],
            participacoes=[
                ParticipacaoDTO(
                    codigo=p.codigo,
                    tipo=p.tipo,
                    descricao=p.descricao,
                    ano=p.ano,
                )
                for p in consultor.participacoes
            ],
            orientacoes=[
                OrientacaoDTO(
                    codigo=o.codigo,
                    tipo=o.tipo,
                    nivel=o.nivel,
                    ano=o.ano,
                    coorientacao=o.coorientacao,
                    premiada=o.premiada,
                    premiacao_tipo=o.premiacao_tipo,
                )
                for o in consultor.orientacoes
            ],
            membros_banca=[
                MembroBancaDTO(
                    codigo=m.codigo,
                    tipo=m.tipo,
                    nivel=m.nivel,
                    ano=m.ano,
                )
                for m in consultor.membros_banca
            ],
            pontuacao=PontuacaoCompletaDTO(
                bloco_a=PontuacaoBlocoDTO(
                    bloco="A",
                    total=consultor.pontuacao.bloco_a.total,
                    atuacoes=[
                        PontuacaoAtuacaoDTO(
                            codigo=a.codigo,
                            base=a.base,
                            tempo=a.tempo,
                            bonus=a.bonus,
                            total=a.total,
                            quantidade=a.quantidade,
                        )
                        for a in consultor.pontuacao.bloco_a.atuacoes
                    ],
                ),
                bloco_c=PontuacaoBlocoDTO(
                    bloco="C",
                    total=consultor.pontuacao.bloco_c.total,
                    atuacoes=[
                        PontuacaoAtuacaoDTO(
                            codigo=a.codigo,
                            base=a.base,
                            tempo=a.tempo,
                            bonus=a.bonus,
                            total=a.total,
                            quantidade=a.quantidade,
                        )
                        for a in consultor.pontuacao.bloco_c.atuacoes
                    ],
                ),
                bloco_d=PontuacaoBlocoDTO(
                    bloco="D",
                    total=consultor.pontuacao.bloco_d.total,
                    atuacoes=[
                        PontuacaoAtuacaoDTO(
                            codigo=a.codigo,
                            base=a.base,
                            tempo=a.tempo,
                            bonus=a.bonus,
                            total=a.total,
                            quantidade=a.quantidade,
                        )
                        for a in consultor.pontuacao.bloco_d.atuacoes
                    ],
                ),
                pontuacao_total=consultor.pontuacao.total,
            ),
            rank=rank,
        )
