from sqlalchemy.orm import Session
from db.crud import LancamentoReceita as CrudLancamentoReceita, LancamentoDespesa as CrudLancamentoDespesa
from db.schemas.Schemas import Estatisticas, LancamentoReceita, LancamentoDespesa, ItemGrafico, LancamentoParaValidacao
from datetime import datetime

def verificar_existencia_de_mes_no_grafico(data: datetime, grafico: list[ItemGrafico]) -> int:
    index_mes = -1
    
    for i, item in enumerate(grafico):
        if item.data.month == data.month:
            index_mes = i
            break

    return index_mes

def get_estatisticas(session: Session):
    grafico: list[ItemGrafico] = []
    total_de_despesas_este_mes = 0
    proximas_despesas: list[LancamentoDespesa] = []
    lancamentos_para_validacao: list[LancamentoParaValidacao] = []

    lancamentos = CrudLancamentoDespesa.get_lancamentos_validacao(session)
    for lancamento in lancamentos:
        lancamentos_para_validacao.append(LancamentoParaValidacao(
            id=lancamento.id,
            data_lancamento=lancamento.data_lancamento.strftime("%Y-%m-%dT%H:%M:%S"),
            nome_despesa=lancamento.despesa.nome
        ))

    despesas = CrudLancamentoDespesa.get_todos_os_lancamentos(session)
    for despesa in despesas:
        index = verificar_existencia_de_mes_no_grafico(despesa.data_lancamento, grafico)
        if index >= 0:
            grafico[index].total -= despesa.valor
        else:
            grafico.append(ItemGrafico(
                data=datetime(year=despesa.data_lancamento.year,month=despesa.data_lancamento.month,day=1,hour=0,minute=0,second=0),
                total=despesa.valor * -1
            ))

        if despesa.data_lancamento.month == datetime.now().month:
            total_de_despesas_este_mes += despesa.valor

        if despesa.data_lancamento > datetime.now():
            proximas_despesas.append(LancamentoDespesa(
                id=despesa.id,
                despesa_id=despesa.despesa_id,
                data_lancamento=despesa.data_lancamento.strftime("%Y-%m-%dT%H:%M:%S"),
                valor=despesa.valor,
                variavel_validado=despesa.variavel_validado,
                nome_despesa=despesa.despesa.nome
            ))

    total_de_receitas_este_mes = 0
    proximas_receitas: list[LancamentoReceita] = []
    receitas = CrudLancamentoReceita.get_todos_os_lancamentos(session)

    for receita in receitas:
        index = verificar_existencia_de_mes_no_grafico(receita.data, grafico)
        if index >= 0:
            grafico[index].total += receita.valor
        else:
            grafico.append(ItemGrafico(
                data=datetime(year=receita.data.year,month=receita.data.month,day=1,hour=0,minute=0,second=0),
                total=receita.valor
            ))

        if receita.data.month == datetime.now().month:
            total_de_receitas_este_mes += receita.valor

        if receita.data > datetime.now():
            proximas_receitas.append(LancamentoReceita(
                id=receita.id,
                orcamento_id=receita.orcamento_id,
                data=receita.data.strftime("%Y-%m-%dT%H:%M:%S"),
                valor=receita.valor,
                nome_orcamento=f"Orcamento {receita.orcamento.id}"
            ))

    return Estatisticas(
        total_de_despesas_este_mes=total_de_despesas_este_mes,
        total_de_receitas_este_mes=total_de_receitas_este_mes,
        proximas_despesas=proximas_despesas,
        proximas_receitas=proximas_receitas,
        grafico=grafico,
        lancamentos_para_validacao=lancamentos_para_validacao
    )
