import axios from "axios";

import { buildCommanderHeaders, resolveCommanderBaseUrl } from "./commanderHttp";

export type CompetenciaStatus = "em_aberto" | "concluido";

export type CompetenciaItem = {
  id: string;
  mes: number;
  ano: number;
  status: CompetenciaStatus;
  quantidadeFechamentos: number;
  criadoEm: string;
  atualizadoEm: string;
};

export type FechamentoDaCompetenciaItem = {
  id: string;
  competenciaId: string;
  parceiroId: string;
  parceiroNome: string;
  parceiroCodinome: string | null;
  parceiroLogoUrl: string | null;
  horasTotal: number;
  status: "em_aberto" | "fechado";
  pontuacaoTotalEntregue: number;
  pontuacaoMeta: number;
  pontuacaoPaga: number;
  pontuacaoBanco: number;
  exportadoFinanceiro: boolean;
  fechadoEm: string | null;
  criadoEm: string;
  atualizadoEm: string;
};

type ListarCompetenciasResponse = {
  data: CompetenciaItem[];
};

type ListarFechamentosDaCompetenciaResponse = {
  data: FechamentoDaCompetenciaItem[];
};

type CriarCompetenciaResponse = {
  data: CompetenciaItem;
};

type ConcluirCompetenciaResponse = {
  data: CompetenciaItem & {
    concluidoPorNome: string | null;
  };
};

type ReabrirCompetenciaResponse = {
  data: CompetenciaItem & {
    reabertoPorNome: string | null;
  };
};

type ImportarCompetenciaResponse = {
  data: {
    competenciaId: string;
    tarefasRecebidas: number;
    tarefasImportadas: number;
    fechamentosCriados: number;
    tarefasIgnoradasSemParceiro: number;
    chamadasSubtarefasAsana: number;
  };
};

export type ImportacaoAsanaModo =
  | "reprocessar_tudo"
  | "reprocessar_alguns"
  | "buscar_novos_fechamentos";

type ApiErrorShape = {
  error?: {
    message?: string;
  };
};

class FechamentoCompetenciasService {
  private handleAxiosError(error: unknown, fallback: string): never {
    if (axios.isAxiosError(error)) {
      if (!error.response) {
        throw new Error(
          "Não foi possível conectar na API do Commander. Verifique VITE_API_BASE_URL_COMMANDER e se o backend está acessível.",
        );
      }
      const message = ((error.response.data as ApiErrorShape | undefined)?.error?.message ??
        error.message ??
        fallback) as string;
      throw new Error(message);
    }
    throw new Error(fallback);
  }

  async listarCompetencias(params: { ano?: number; status?: CompetenciaStatus }): Promise<CompetenciaItem[]> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.get<ListarCompetenciasResponse>(`${baseUrl}/competencias`, {
        headers,
        params: {
          ano: params.ano,
          status: params.status,
        },
      });
      return response.data.data ?? [];
    } catch (error) {
      this.handleAxiosError(error, "Erro ao listar competências.");
    }
  }

  async listarFechamentosDaCompetencia(competenciaId: string): Promise<FechamentoDaCompetenciaItem[]> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.get<ListarFechamentosDaCompetenciaResponse>(
        `${baseUrl}/competencias/${competenciaId}/fechamentos`,
        { headers },
      );
      return response.data.data ?? [];
    } catch (error) {
      this.handleAxiosError(error, "Erro ao listar fechamentos da competência.");
    }
  }

  async criarCompetencia(input: { mes: number; ano: number }): Promise<CompetenciaItem> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.post<CriarCompetenciaResponse>(
        `${baseUrl}/competencias`,
        { mes: input.mes, ano: input.ano },
        { headers },
      );
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao criar competência.");
    }
  }

  async concluirCompetencia(competenciaId: string, concluidoPorId: string): Promise<ConcluirCompetenciaResponse["data"]> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.post<ConcluirCompetenciaResponse>(
        `${baseUrl}/competencias/${competenciaId}/concluir`,
        { concluido_por_id: concluidoPorId },
        { headers },
      );
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao concluir competência.");
    }
  }

  async reabrirCompetencia(
    competenciaId: string,
    reabertoPorId: string,
    motivo?: string,
  ): Promise<ReabrirCompetenciaResponse["data"]> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.post<ReabrirCompetenciaResponse>(
        `${baseUrl}/competencias/${competenciaId}/reabrir`,
        { reaberto_por_id: reabertoPorId, motivo },
        { headers },
      );
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao reabrir competência.");
    }
  }

  async importarDoAsana(
    competenciaId: string,
    opcoes?: { modo?: ImportacaoAsanaModo; parceiroIds?: string[] },
  ): Promise<{ tarefasRecebidas: number; tarefasImportadas: number; fechamentosCriados: number; tarefasIgnoradasSemParceiro: number }> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.post<ImportarCompetenciaResponse>(
        `${baseUrl}/competencias/${competenciaId}/importar`,
        {
          modo: opcoes?.modo ?? "reprocessar_tudo",
          parceiroIds: opcoes?.parceiroIds,
        },
        { headers },
      );
      return {
        tarefasRecebidas: response.data.data.tarefasRecebidas,
        tarefasImportadas: response.data.data.tarefasImportadas,
        fechamentosCriados: response.data.data.fechamentosCriados,
        tarefasIgnoradasSemParceiro: response.data.data.tarefasIgnoradasSemParceiro,
      };
    } catch (error) {
      this.handleAxiosError(error, "Erro ao importar tasks do Asana.");
    }
  }
}

export const fechamentoCompetenciasService = new FechamentoCompetenciasService();
