import axios from "axios";

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

export type ParceiroTipoPessoa = "fisica" | "juridica";
export type ParceiroStatusFiltro = "all" | "true" | "false";

export type ParceiroItem = {
  id: string;
  nome: string;
  codinome: string | null;
  tipoPessoa: ParceiroTipoPessoa;
  cpf: string | null;
  cnpj: string | null;
  email: string;
  whatsapp: string | null;
  asanaId: string | null;
  logoUrl: string | null;
  observacoes: string | null;
  pontuacaoMeta: number;
  estaAtivo: boolean;
  criadoEm: string;
  atualizadoEm: string;
};

type MetaResponse = {
  total: number;
  paginaAtual: number;
  totalPaginas: number;
};

export type ListarParceirosResponse = {
  data: ParceiroItem[];
  meta: MetaResponse;
};

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

export type ListarParceirosParams = {
  busca?: string;
  estaAtivo?: ParceiroStatusFiltro;
  page: number;
  perPage: number;
};

export type SalvarParceiroPayload = {
  nome: string;
  codinome?: string | null;
  tipoPessoa: ParceiroTipoPessoa;
  cpf?: string | null;
  cnpj?: string | null;
  email: string;
  whatsapp?: string | null;
  asanaId?: string | null;
  logoUrl?: string | null;
  observacoes?: string | null;
  pontuacaoMeta: number;
  estaAtivo?: boolean;
};

type SalvarParceiroResponse = {
  data: ParceiroItem;
};

class FechamentoParceirosService {
  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 listarParceiros(params: ListarParceirosParams): Promise<ListarParceirosResponse> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.get<ListarParceirosResponse>(`${baseUrl}/parceiros`, {
        headers,
        params: {
          busca: params.busca || undefined,
          estaAtivo: params.estaAtivo ?? "all",
          page: params.page,
          perPage: params.perPage,
        },
      });
      return response.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao listar parceiros.");
    }
  }

  async listarParceirosAtivos(): Promise<ParceiroItem[]> {
    const response = await this.listarParceiros({
      estaAtivo: "true",
      page: 1,
      perPage: 100,
    });
    return response.data ?? [];
  }

  async criarParceiro(payload: SalvarParceiroPayload): Promise<ParceiroItem> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.post<SalvarParceiroResponse>(`${baseUrl}/parceiros`, payload, {
        headers,
      });
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao criar parceiro.");
    }
  }

  async editarParceiro(id: string, payload: Partial<SalvarParceiroPayload>): Promise<ParceiroItem> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.patch<SalvarParceiroResponse>(`${baseUrl}/parceiros/${id}`, payload, {
        headers,
      });
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao editar parceiro.");
    }
  }

  async toggleAtivoParceiro(id: string): Promise<ParceiroItem> {
    try {
      const headers = await buildCommanderHeaders();
      const baseUrl = resolveCommanderBaseUrl();
      const response = await axios.patch<SalvarParceiroResponse>(
        `${baseUrl}/parceiros/${id}/toggle-ativo`,
        {},
        {
          headers,
        },
      );
      return response.data.data;
    } catch (error) {
      this.handleAxiosError(error, "Erro ao atualizar status do parceiro.");
    }
  }
}

export const fechamentoParceirosService = new FechamentoParceirosService();
