import Button from "@/components/Forms/Button";
import InputGroup from "@/components/Forms/InputGroup";
import InputSelectComponent from "@/components/Forms/InputSelect";
import ModalComponente from "@/components/Modal/ModalComponente";
import ReactTable from "@/components/ReactTable/ReactTable";
import { DateRangePicker } from "@/components/dateRangePicker";
import { detalheQuadroGerencial } from "@/requests/CRM/Metas/listarMetas";
import { useCallback, useEffect, useMemo, useState } from "react";
import { DateRange } from "react-day-picker";

// Status da proposta (mesmos rótulos usados no Kanban de Projetos)
const STATUS_PROPOSTA: Record<string, string> = {
  "0": "Proposta Gerada",
  "1": "Aprovada",
  "2": "Inativa",
  "3": "Cancelada",
};

const formatarNumero = (valor: any): string =>
  Number(valor || 0).toLocaleString("pt-BR");

const formatarMoeda = (valor: any): string =>
  Number(valor || 0).toLocaleString("pt-BR", {
    style: "currency",
    currency: "BRL",
  });

// Ids nulos/zerados (registro sem loja, sem vendedor etc.) exibem "-"
const exibirId = (valor: any): string =>
  valor === null || valor === undefined || Number(valor) <= 0
    ? "-"
    : String(valor);

const exibirTexto = (valor: any): string =>
  valor === null || valor === undefined || String(valor).trim() === ""
    ? "-"
    : String(valor);

// Aceita "AAAA-MM-DD" e "AAAA-MM-DD HH:MM:SS"
const formatarData = (valor: any): string => {
  if (!valor) return "-";
  const [data] = String(valor).split(" ");
  const [ano, mes, dia] = data.split("-");
  if (!dia) return String(valor);
  return `${dia}/${mes}/${ano}`;
};

const toYMD = (d: Date): string => {
  const dt = new Date(d);
  const y = dt.getFullYear();
  const m = String(dt.getMonth() + 1).padStart(2, "0");
  const day = String(dt.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
};

type Coluna = {
  header: string;
  valor: (row: any) => string;
  soma?: "quantidade" | "valor";
};

const COLUNAS_ENTIDADE: Coluna[] = [
  { header: "ID Loja", valor: (r) => exibirId(r.id_loja) },
  { header: "Loja", valor: (r) => exibirTexto(r.nome_loja) },
  { header: "ID Tipo Negócio", valor: (r) => exibirId(r.id_tipo_negocio) },
  { header: "Tipo de Negócio", valor: (r) => exibirTexto(r.nome_tipo_negocio) },
  { header: "ID Perfil", valor: (r) => exibirId(r.id_perfil) },
  { header: "Perfil de Usuário", valor: (r) => exibirTexto(r.nome_perfil) },
  { header: "ID Usuário", valor: (r) => exibirId(r.id_usuario) },
  { header: "Usuário", valor: (r) => exibirTexto(r.nome_usuario) },
];

const COLUNAS_LEAD: Coluna[] = [
  { header: "ID Lead", valor: (r) => exibirId(r.id_lead) },
  { header: "Nome do Lead", valor: (r) => exibirTexto(r.nome_lead) },
  { header: "Data Cadastro do Lead", valor: (r) => formatarData(r.data_lead) },
];

const COLUNAS_PROJETO_LEAD: Coluna[] = [
  { header: "Nro do Projeto", valor: (r) => exibirId(r.nro_projeto) },
  {
    header: "Data Criação do Projeto",
    valor: (r) => formatarData(r.data_projeto),
  },
];

const COLUNAS_PROJETO: Coluna[] = [
  { header: "Nro Projeto", valor: (r) => exibirId(r.nro_projeto) },
  {
    header: "Data Criação do Projeto",
    valor: (r) => formatarData(r.data_projeto),
  },
  {
    header: "Status do Projeto",
    valor: (r) => exibirTexto(r.pendencia_projeto ?? r.status_projeto),
  },
];

const COLUNA_PROPOSTA_NUMERO: Coluna = {
  header: "Nro da Proposta",
  valor: (r) => exibirId(r.nro_proposta),
};

const COLUNA_PROPOSTA_DATA: Coluna = {
  header: "Data Geração da Proposta",
  valor: (r) => formatarData(r.data_proposta),
};

const COLUNA_PROPOSTA_APROVACAO: Coluna = {
  header: "Data Aprovação",
  valor: (r) => formatarData(r.data_aprovacao),
};

const COLUNA_PROPOSTA_VALOR: Coluna = {
  header: "Valor Proposta",
  valor: (r) => formatarMoeda(r.valor),
  soma: "valor",
};

const COLUNA_PROPOSTA_STATUS: Coluna = {
  header: "Status da Proposta",
  valor: (r) =>
    r.status_proposta === null || r.status_proposta === undefined
      ? "-"
      : (STATUS_PROPOSTA[String(r.status_proposta)] ??
        String(r.status_proposta)),
};

const COLUNA_VENDA: Coluna = {
  header: "Data Finalização da Venda",
  valor: (r) => formatarData(r.data_venda),
};

const COLUNAS_PROPOSTA: Coluna[] = [
  COLUNA_PROPOSTA_NUMERO,
  COLUNA_PROPOSTA_DATA,
  COLUNA_PROPOSTA_VALOR,
  COLUNA_PROPOSTA_STATUS,
];

const COLUNAS_PROPOSTA_APROVADA: Coluna[] = [
  COLUNA_PROPOSTA_NUMERO,
  COLUNA_PROPOSTA_DATA,
  COLUNA_PROPOSTA_APROVACAO,
  COLUNA_PROPOSTA_VALOR,
  COLUNA_PROPOSTA_STATUS,
];

const COLUNAS_POR_TIPO: Record<string, Coluna[]> = {
  leads: [...COLUNAS_ENTIDADE, ...COLUNAS_LEAD, ...COLUNAS_PROJETO_LEAD],
  agendamentos: [
    ...COLUNAS_ENTIDADE,
    { header: "ID Agendamento", valor: (r) => exibirId(r.id_agendamento) },
    {
      header: "Nome do Agendamento",
      valor: (r) => exibirTexto(r.nome_agendamento),
    },
    {
      header: "Data do Agendamento",
      valor: (r) => formatarData(r.data_agendamento),
    },
  ],
  propostasGeradas: [
    ...COLUNAS_ENTIDADE,
    ...COLUNAS_PROJETO,
    ...COLUNAS_PROPOSTA,
  ],
  propostasAprovadas: [
    ...COLUNAS_ENTIDADE,
    ...COLUNAS_PROJETO,
    ...COLUNAS_PROPOSTA_APROVADA,
  ],
  vendas: [
    ...COLUNAS_ENTIDADE,
    ...COLUNAS_PROJETO,
    ...COLUNAS_PROPOSTA_APROVADA,
    COLUNA_VENDA,
  ],
  taxaConversao: [
    ...COLUNAS_ENTIDADE,
    ...COLUNAS_LEAD,
    ...COLUNAS_PROJETO,
    ...COLUNAS_PROPOSTA_APROVADA,
    COLUNA_VENDA,
  ],
};

// Item 02: data pela qual o período de cada quadro é filtrado. Fica na label do
// filtro para não restar dúvida de qual data está sendo considerada.
const DATA_PERIODO_POR_TIPO: Record<string, string> = {
  leads: "Data de Cadastro do Lead",
  agendamentos: "Data do Agendamento",
  propostasGeradas: "Data de Geração da Proposta",
  propostasAprovadas: "Data de Aprovação da Proposta",
  vendas: "Data de Finalização da Venda",
  taxaConversao: "Data de Cadastro do Lead",
};

type Opcao = { label: string; value: string };

const DetalheQuadro = ({
  titulo,
  tipo,
  filtrosIniciais,
  lojas,
  tiposNegocio,
  perfis,
  usuarios,
  onClose,
}: {
  titulo: string;
  tipo: string;
  filtrosIniciais?: any;
  lojas: any[];
  tiposNegocio: any[];
  perfis: any[];
  usuarios: any[];
  onClose: () => void;
}) => {
  const [linhas, setLinhas] = useState<any[]>([]);
  const [truncado, setTruncado] = useState(false);
  const [limite, setLimite] = useState(0);
  const [isLoading, setIsLoading] = useState(false);

  const [filtroLoja, setFiltroLoja] = useState<string[]>(
    filtrosIniciais?.lojas ?? [],
  );
  const [filtroTipoNegocio, setFiltroTipoNegocio] = useState<string[]>(
    filtrosIniciais?.tiposNegocio ?? [],
  );
  const [filtroPerfil, setFiltroPerfil] = useState<string[]>(
    filtrosIniciais?.perfis ?? [],
  );
  const [filtroUsuario, setFiltroUsuario] = useState<string[]>(
    filtrosIniciais?.usuarios ?? [],
  );
  const [dataInicio, setDataInicio] = useState<string>(
    filtrosIniciais?.dataInicio ?? "",
  );
  const [dataFim, setDataFim] = useState<string>(
    filtrosIniciais?.dataFim ?? "",
  );
  const [range, setRange] = useState<DateRange | string | undefined>(
    filtrosIniciais?.dataInicio && filtrosIniciais?.dataFim
      ? {
        from: new Date(`${filtrosIniciais.dataInicio}T00:00:00`),
        to: new Date(`${filtrosIniciais.dataFim}T00:00:00`),
      }
      : "*",
  );

  const colunas = useMemo(() => COLUNAS_POR_TIPO[tipo] ?? [], [tipo]);

  // Item 02: data usada no filtro de período deste quadro
  const dataPeriodo = DATA_PERIODO_POR_TIPO[tipo] ?? "Data do Cadastro";

  // Detalhe em ReactTable: cada coluna vira um campo texto da linha, para que
  // pesquisa, ordenação, paginação e exportação funcionem.
  const colunasTabela = useMemo(
    () =>
      colunas.map((coluna, i) => ({
        header: coluna.header,
        accessorKey: `coluna_${i}`,
      })),
    [colunas],
  );

  const dadosTabela = useMemo(
    () =>
      linhas.map((row: any) => {
        const linha: any = {};
        colunas.forEach((coluna, i) => {
          linha[`coluna_${i}`] = coluna.valor(row);
        });
        return linha;
      }),
    [linhas, colunas],
  );

  const buscar = useCallback(
    (filtros: any) => {
      setIsLoading(true);
      detalheQuadroGerencial({ ...filtros, tipo })
        .then((res: any) => {
          setLinhas(Array.isArray(res?.linhas) ? res.linhas : []);
          setTruncado(Boolean(res?.truncado));
          setLimite(Number(res?.limite ?? 0));
        })
        .catch((error) => {
          console.error("Erro ao carregar detalhe do quadro:", error);
          setLinhas([]);
          setTruncado(false);
        })
        .finally(() => setIsLoading(false));
    },
    [tipo],
  );

  useEffect(() => {
    buscar({
      dataInicio: filtrosIniciais?.dataInicio ?? "",
      dataFim: filtrosIniciais?.dataFim ?? "",
      lojas: filtrosIniciais?.lojas ?? [],
      tiposNegocio: filtrosIniciais?.tiposNegocio ?? [],
      perfis: filtrosIniciais?.perfis ?? [],
      usuarios: filtrosIniciais?.usuarios ?? [],
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tipo]);

  const handleRangeChange = (r: DateRange | string | undefined) => {
    setRange(r);
    if (!r || r === "*" || typeof r === "string") {
      setDataInicio("");
      setDataFim("");
      return;
    }
    setDataInicio(r.from ? toYMD(r.from) : "");
    setDataFim(r.to ? toYMD(r.to) : "");
  };

  const aplicarFiltro = () =>
    buscar({
      dataInicio,
      dataFim,
      lojas: filtroLoja,
      tiposNegocio: filtroTipoNegocio,
      perfis: filtroPerfil,
      usuarios: filtroUsuario,
    });

  const totais = useMemo(() => {
    const somaValor = colunas.some((c) => c.soma === "valor");
    return {
      quantidade: linhas.length,
      valor: somaValor
        ? linhas.reduce((acc, r) => acc + Number(r.valor || 0), 0)
        : null,
    };
  }, [linhas, colunas]);

  const opcoes = (lista: any[], idKey: string, nomeKey: string): Opcao[] => [
    { value: "*", label: "Todos" },
    ...lista.map((a: any) => ({
      label: a[nomeKey],
      value: String(a[idKey]),
    })),
  ];

  const paraFiltro = (value: any): string[] =>
    value ? value.map((a: any) => a.value) : [];

  return (
    <ModalComponente
      hasForm={false}
      hasSaveButton={false}
      defaultW="w-[95vw]"
      header={titulo}
      opened
      onClose={onClose}
    >
      <div className="p-4">
        <div className="mb-4 rounded-md border border-stroke p-3 dark:border-strokedark">
          <InputGroup>
            <div>
              {/* Item 02: a label diz qual data delimita o período */}
              <h1 className="mb-2 text-black dark:text-white">
                Período por {dataPeriodo}
              </h1>
              <DateRangePicker
                value={range}
                onChange={handleRangeChange}
                label={`Selecione o período (${dataPeriodo})`}
              />
            </div>

            <InputSelectComponent
              label="Loja"
              isMulti
              defaultValue={filtroLoja.join(",") || "*"}
              options={opcoes(lojas, "id_loja", "nome_loja")}
              onChange={(value: any) => setFiltroLoja(paraFiltro(value))}
            />

            <InputSelectComponent
              label="Tipo de Negócio"
              isMulti
              defaultValue={filtroTipoNegocio.join(",") || "*"}
              options={opcoes(
                tiposNegocio,
                "id_tipo_negocio",
                "nome_tipo_negocio",
              )}
              onChange={(value: any) => setFiltroTipoNegocio(paraFiltro(value))}
            />

            <InputSelectComponent
              label="Perfil de Usuário"
              isMulti
              defaultValue={filtroPerfil.join(",") || "*"}
              options={opcoes(perfis, "id_perfil", "nome_perfil")}
              onChange={(value: any) => setFiltroPerfil(paraFiltro(value))}
            />

            <InputSelectComponent
              label="Usuários"
              isMulti
              defaultValue={filtroUsuario.join(",") || "*"}
              options={opcoes(usuarios, "id_usuario", "nome_usuario")}
              onChange={(value: any) => setFiltroUsuario(paraFiltro(value))}
            />
          </InputGroup>

          <InputGroup align="center">
            <Button
              type="button"
              loading={isLoading}
              className="bg-success px-9 text-sm"
              onClick={aplicarFiltro}
            >
              Filtrar
            </Button>
          </InputGroup>
        </div>

        {truncado && (
          <div className="mb-3 rounded-md border border-[#fdf0c2] bg-[#fdf0c2] px-3 py-2 text-sm text-[#8e4b10]">
            Exibindo apenas os primeiros <b>{formatarNumero(limite)}</b>{" "}
            registros. Refine os filtros para ver o restante.
          </div>
        )}

        {isLoading ? (
          <div className="p-6 text-center text-body dark:text-bodydark">
            Carregando...
          </div>
        ) : (
          <ReactTable
            pageName={titulo}
            columns={colunasTabela}
            data={dadosTabela}
            listFunction={async () => dadosTabela}
            tfoot={
              <tfoot className="sticky bottom-0 bg-white dark:bg-boxdark">
                <tr className="border-t-2 border-stroke font-semibold dark:border-strokedark">
                  <td className="p-2" colSpan={colunas.length}>
                    Total de registros:{" "}
                    <span className="text-[#266c94]">
                      {formatarNumero(totais.quantidade)}
                    </span>
                    {totais.valor !== null && (
                      <>
                        {" · "}Valor total:{" "}
                        <span className="text-[#429e12]">
                          {formatarMoeda(totais.valor)}
                        </span>
                      </>
                    )}
                  </td>
                </tr>
              </tfoot>
            }
          />
        )}
      </div>
    </ModalComponente>
  );
};

export default DetalheQuadro;
