import Button from "@/components/Forms/Button";
import LoaderSun from "@/components/common/Loader/LoaderSun";
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
import { cn } from "@/lib/utils";
import {
  listarCamposPersonalizados,
  listarTipoCampoPersonalizado,
} from "@/requests/CRUD/CamposPersonalizados/listarCamposPersonalizados";
import { useAuth } from "@/src/contexts/authContext";
import { GetForm } from "@/utils";
import {
  getNomeCampoPersonalizado,
  nomeLegivel,
  validarCamposPersonalizadosObrigatorios,
} from "@/utils/validarCamposPersonalizados";
import { Tooltip } from "@mui/material";
import { Info } from "lucide-react";
import {
  Children,
  cloneElement,
  FormEvent,
  isValidElement,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { toast } from "react-toastify";
import CampoPersonalizadoComponente from "./campoPersonalizadoComponente";

function formatarTituloCampo(nome: string) {
  return nome
    .replace(/[-_]/g, " ")
    .trim()
    .split(/\s+/)
    .map((palavra) =>
      palavra
        ? palavra.charAt(0).toLocaleUpperCase("pt-BR") +
          palavra.slice(1).toLocaleLowerCase("pt-BR")
        : palavra
    )
    .join(" ");
}

const CamposPersonalizados = ({
  dataCard,
  key,
  blockEditCard,
  eachTopic,
  localCampo,
  locaisProposta,
  customIndex,
  classNameProps,
  customName,
  itensCompra,
  showTabs = true,
  formulario,
  localAtualProposta,
  handleSubmit,
  onSubmitFunction,
  children,
  idLoja,
  tipoNegocio,
  manualCampos,
  pendenciaID,
  mostrarBotaoSalvar = false, // 👈 default seguro
  textoBotaoSalvar = "Salvar",
  showBorderContainer = false,
  showAccordion,
  onHasCampos,
  ignorarValoresGravados = false,
}: {
  dataCard?: any;
  key?: any;
  showTabs?: boolean;
  customIndex?: any;
  blockEditCard?: boolean;
  classNameProps?: string;
  customName?: string;
  eachTopic?: string;
  itensCompra?: any;
  manualCampos?: any;
  localCampo: string;
  formulario?: any;
  locaisProposta?: any;
  handleSubmit?: any;
  localAtualProposta?: any;
  onSubmitFunction?: any;
  children?: any;
  idLoja?: any;
  tipoNegocio?: any;
  pendenciaID?: number;
  mostrarBotaoSalvar?: boolean;
  textoBotaoSalvar?: string;
  showBorderContainer?: boolean;
  showAccordion?: boolean;
  onHasCampos?: (hasCampos: boolean) => void;
  ignorarValoresGravados?: boolean;
}) => {
  const [camposPersonalizados, setCamposPersonalizados] = useState([]);
  const { valuesSession, perfil } = useAuth();
  const [imagemFile, setImagemFile] = useState<[File | null | any, string]>([
    null,
    "",
  ]);
  const [tipoCamposPersonalizados, setTipoCamposPersonalizados] = useState<any>(
    []
  );
  const [activeTab, setActiveTab] = useState("");
  const [isSalvando, setIsSalvando] = useState(false);
  const array = [
    { a: "lojas_campo_personalizado", b: "id_loja_coleta" },
    { a: "tipoNegocio_campo_personalizado", b: "tipoNegocio_coleta" },
    { a: "perfisVisualizar_campo_personalizado" },
  ];
  const isFirstRender = useRef(true);

  const formObrigatorios = GetForm();

  useEffect(() => {
    if (!pendenciaID) return;
    if (isFirstRender.current) {
      isFirstRender.current = false;
      return;
    }
    formulario.reset({});
  }, [pendenciaID]);

  useEffect(() => {
    if (manualCampos) {
      setCamposPersonalizados(ordenarCampos(manualCampos));
    } else {
      obterCamposPersonalizados();
    }

    listarTipoCampoPersonalizado().then((res) => {
      setTipoCamposPersonalizados(res);
    });
  }, []);
  useEffect(() => {
    if (manualCampos) {
      setCamposPersonalizados(ordenarCampos(manualCampos));
    }
  }, [manualCampos]);

  async function obterCamposPersonalizados() {
    return listarCamposPersonalizados({
      id_coleta: dataCard?.id_coleta_cliente,
      id_pendencia: pendenciaID,
    }).then((res) => {
      const filtrados = res.filter(
        (a: any) => a.status_campo_personalizado == "1"
      );
      setCamposPersonalizados(ordenarCampos(filtrados));
    });
  }

  const verificarConformidade = (campo: any, verifyField?: boolean) => {
    if (verifyField && activeTab && campo.id_campo_personalizado !== activeTab)
      return false;

    const lojaAtual = String(idLoja ?? dataCard?.id_loja_coleta ?? "");

    if (
      campo.lojas_campo_personalizado !== "*" &&
      lojaAtual &&
      !campo.lojas_campo_personalizado.split(",").includes(lojaAtual)
    ) {
      return false;
    }

    const tipoNegocioAtual = String(
      tipoNegocio ?? dataCard?.tipoNegocio_coleta ?? ""
    );

    if (
      tipoNegocioAtual &&
      tipoNegocioAtual !== "*" &&
      campo.tipoNegocio_campo_personalizado !== "*" &&
      !campo.tipoNegocio_campo_personalizado
        .split(",")
        .map((v: string) => v.trim())
        .includes(tipoNegocioAtual)
    ) {
      return false;
    }

    if ([2, 10, 11].includes(Number(localCampo))) {
      return campo.local_campo_personalizado == localCampo;
    }

    if (!dataCard) {
      return false;
    }

    const campoLocal = Number(campo.local_campo_personalizado ?? -1);
    const local = Number(localCampo ?? -1);

    if (campoLocal !== local) {
      return false;
    }

    if (localCampo === "3" && localAtualProposta) {
      return (
        localAtualProposta.id_documento_personalizado ===
        campo.etapaDocs_campo_personalizado
      );
    }

    if (localCampo === "6") {
      //Pendencias
      return (
        campo.cadaTopico_campo_personalizado === eachTopic &&
        campo.dados_gravacao_personalizado
      );
    }
    if (localCampo === "5") {
      return (
        campo.local_campo_personalizado == localCampo &&
        (campo.pendencia_campo_personalizado === "*" ||
          campo.pendencia_campo_personalizado
            .split(",")
            .some((i: string) => Number(i) === Number(pendenciaID)))
      );
    }

    if (localCampo === "1") {
      const stepNome = (
        locaisProposta[localAtualProposta!]?.nome ??
        locaisProposta[localAtualProposta!]?.name ??
        ""
      ).toLowerCase();
      const descricao = (
        campo.descricao_proposta_personalizado ?? ""
      ).toLowerCase();
      const etapa = (
        campo.etapaProposta_campo_personalizado ?? ""
      ).toLowerCase();
      return (
        campo.local_campo_personalizado == localCampo &&
        ((descricao !== "" && stepNome.includes(descricao)) ||
          (etapa !== "" && stepNome.includes(etapa)))
      );
    }

    const canVisualizar =
      campo.perfisVisualizar_campo_personalizado === "*"
        ? true
        : campo.perfisVisualizar_campo_personalizado
            ?.split(",")
            ?.includes(perfil?.id_perfil) || perfil?.cargo_perfil === "-1";

    const conditionsIncome = array
      .filter((ar) => campo[ar.a] !== "" && campo[ar.a] !== null)
      .map((arr) => {
        const fieldValue = campo[arr.a];

        if (fieldValue === "*") return ["*"];

        return fieldValue
          ? fieldValue.split(",").map((id: string) => id.trim())
          : [];
      });
    const valuesToCheck = array.map((arr) =>
      arr.b ? dataCard?.[arr.b] : null
    );
    const funis = campo.fluxos
      ? campo.fluxos.map(
          (fluxo: any) => fluxo?.fluxo_etapas_campo_personalizado
        )
      : [];

    const conditionsB = conditionsIncome.map((res, index) => {
      const valueToCheck = valuesToCheck[index];

      if (res.includes("*")) return true;

      return valueToCheck ? res.includes(String(valueToCheck)) : true;
    });

    const isHidden =
      campo.fluxos?.length > 0
        ? !campo.fluxos?.some(
            (fluxo: any) =>
              (fluxo.fluxo_etapas_campo_personalizado == "*" ||
                fluxo.fluxo_etapas_campo_personalizado ==
                  dataCard?.funil_card) &&
              (fluxo.visualizar_etapas_campo_personalizado == "*" ||
                fluxo.visualizar_etapas_campo_personalizado
                  ?.split(",")
                  ?.includes(dataCard?.id_lista))
          )
        : false;

    const canEdit =
      campo.fluxos?.length == 0 ||
      campo.fluxos?.some(
        (fluxo: any) =>
          (fluxo.fluxo_etapas_campo_personalizado == "*" ||
            fluxo.fluxo_etapas_campo_personalizado == dataCard?.funil_card) &&
          (fluxo.editar_etapas_campo_personalizado == "*" ||
            fluxo.editar_etapas_campo_personalizado
              ?.split(",")
              ?.includes(dataCard?.id_lista))
      );

    const isOnFunnel =
      funis.length == 0 ||
      funis.includes("*") ||
      (funis.length == 0
        ? false
        : funis.includes(String(dataCard?.funil_card)));

    return (
      conditionsB.every((condition) => condition) &&
      (!isHidden || canEdit) &&
      isOnFunnel &&
      canVisualizar &&
      campo.local_campo_personalizado == localCampo
    );
  };
  const ordenarCampos = (campos: any) => {
    const prioridade = [5, 6];
    return campos.sort((a: any, b: any) => {
      const ordemA =
        a.ordem_campo_personalizado !== null &&
        a.ordem_campo_personalizado !== ""
          ? Number(a.ordem_campo_personalizado)
          : null;
      const ordemB =
        b.ordem_campo_personalizado !== null &&
        b.ordem_campo_personalizado !== ""
          ? Number(b.ordem_campo_personalizado)
          : null;

      if (ordemA !== null && ordemB !== null) {
        if (ordemA !== ordemB) {
          return ordemA - ordemB;
        }
      } else if (ordemA !== null) {
        return -1;
      } else if (ordemB !== null) {
        return 1;
      }

      const tipoA = Number(a.tipo_campo_personalizado);
      const tipoB = Number(b.tipo_campo_personalizado);

      const prioridadeA = prioridade.includes(tipoA) ? 0 : tipoA === 1 ? 2 : 1;
      const prioridadeB = prioridade.includes(tipoB) ? 0 : tipoB === 1 ? 2 : 1;

      if (prioridadeA !== prioridadeB) {
        return prioridadeA - prioridadeB;
      }
      return tipoA - tipoB;
    });
  };
  async function onSubmitCamposPersonalizados(data: any) {
    if (!onSubmitFunction) return;

    if (imagemFile[0]) {
      data["img^" + imagemFile[1]] = imagemFile[0];
    }

    Object.keys(data).forEach((key) => {
      if (Array.isArray(data[key]) && data[key]?.length === 0) {
        data[key] = "";
      }
    });

    setIsSalvando(true);
    try {
      await onSubmitFunction(data);
      await obterCamposPersonalizados();
      toast.success("Campo salvo com sucesso!");
    } catch {
      toast.error("Erro ao salvar o campo. Tente novamente.");
    } finally {
      setIsSalvando(false);
    }
  }

  // Deduplica por id_campo_personalizado após filtrar
  const filtroCamposPersonalizados: any = useMemo(() => {
    const filtrados = camposPersonalizados.filter((campo) =>
      verificarConformidade(campo, false)
    );

    // Remove duplicatas mantendo apenas o primeiro de cada id
    const seen = new Set();
    const semDuplicados = filtrados.filter((campo: any) => {
      if (seen.has(campo.id_campo_personalizado)) return false;
      seen.add(campo.id_campo_personalizado);
      return true;
    });

    return ordenarCampos(semDuplicados);
  }, [
    camposPersonalizados,
    localCampo,
    localAtualProposta,
    locaisProposta,
    activeTab,
    idLoja,
    tipoNegocio,
    dataCard,
  ]);

  useEffect(() => {
    if (!showTabs || filtroCamposPersonalizados.length === 0) return;

    const firstTabId = filtroCamposPersonalizados[0].id_campo_personalizado;
    setActiveTab((current) => {
      const currentStillValid = filtroCamposPersonalizados.some(
        (tab: any) => tab.id_campo_personalizado === current
      );
      return current && currentStillValid ? current : firstTabId;
    });
  }, [filtroCamposPersonalizados, showTabs]);

  if (filtroCamposPersonalizados.length === 0) return null;

  const deveValidarSomenteAbaAtiva =
    showTabs && filtroCamposPersonalizados.length > 1 && !!activeTab;

  const obterCampoAtivo = () =>
    filtroCamposPersonalizados.find(
      (campo: any) => campo.id_campo_personalizado === activeTab
    );

  const obterNomesCampoAtivo = (campo: any) => {
    const fieldName = getNomeCampoPersonalizado(campo, localCampo, customIndex);
    if (String(campo.tipo_campo_personalizado) === "5") {
      const nomeChecklist = fieldName.includes("^")
        ? fieldName.split("^")[1]
        : fieldName;
      return [fieldName, `checkboxes.${nomeChecklist}`];
    }
    return [fieldName];
  };

  async function handleFormSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (isSalvando) return;

    if (!handleSubmit) {
      return onSubmitCamposPersonalizados(formulario?.getValues?.() ?? {});
    }

    if (deveValidarSomenteAbaAtiva) {
      const campoAtivo = obterCampoAtivo();
      if (!campoAtivo) return;

      const nomesCampoAtivo = obterNomesCampoAtivo(campoAtivo);
      const isValid = await formulario.trigger(nomesCampoAtivo);
      if (!isValid) return;

      const formValues = formulario.getValues();
      const { valido, camposVazios } = validarCamposPersonalizadosObrigatorios(
        formValues,
        nomesCampoAtivo
      );

      if (!valido) {
        toast.warn(
          `Preencha o campo obrigatório: ${nomeLegivel(camposVazios[0])}`
        );
        return;
      }

      return onSubmitCamposPersonalizados(formValues);
    }

    return handleSubmit(onSubmitCamposPersonalizados)(event);
  }

  const isTabActive = (tabId: string) =>
    activeTab
      ? activeTab === tabId
      : tabId === filtroCamposPersonalizados[0]?.id_campo_personalizado;

  const usaLayoutCard =
    showTabs && filtroCamposPersonalizados.length > 1 && !!activeTab;

  const campoAtivoExibicao = usaLayoutCard
    ? filtroCamposPersonalizados.find(
        (campo: any) => campo.id_campo_personalizado === activeTab
      )
    : null;

  const temBotaoSalvar = mostrarBotaoSalvar || !!children;

  const conteudo = (
    <div className="w-full min-w-0">
      {showTabs && filtroCamposPersonalizados.length > 1 && (
        <div className="mb-4 w-full min-w-0 rounded-lg border border-stroke bg-slate-50/90 p-3 dark:border-strokedark dark:bg-meta-4/20">
          <div className="mb-2.5 flex items-center justify-between gap-2">
            <span className="text-xs font-semibold uppercase tracking-wide text-bodydark2">
              Campos disponíveis
            </span>
            <span className="flex shrink-0 items-center gap-1.5">
              <span className="rounded-full bg-white px-2 py-0.5 text-[11px] font-medium text-bodydark2 shadow-sm dark:bg-boxdark">
                {filtroCamposPersonalizados.length}
              </span>
              <Tooltip
                title="Total de Campos Personalizados cadastrados para a 'Aba Campos Personalizados'"
                placement="top"
              >
                <button
                  type="button"
                  className="rounded-full p-0.5 text-bodydark2 transition-colors hover:text-primary"
                  aria-label="Informação sobre total de campos"
                >
                  <Info size={15} />
                </button>
              </Tooltip>
            </span>
          </div>
          <div className="flex max-h-36 flex-wrap gap-2 overflow-y-auto pr-1 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-slate-300 dark:scrollbar-thumb-slate-600">
            {filtroCamposPersonalizados.map((tab: any) => {
              const selected = isTabActive(tab.id_campo_personalizado);
              return (
                <button
                  key={tab.id_campo_personalizado}
                  type="button"
                  title={tab.nome_campo_personalizado}
                  className={cn(
                    "inline-flex max-w-full items-center rounded-full border px-3 py-1.5 text-xs font-medium transition-all duration-150 sm:text-sm",
                    selected
                      ? "border-primary bg-primary text-white shadow-sm ring-2 ring-primary/20"
                      : "border-stroke bg-white text-bodydark hover:border-primary/40 hover:bg-primary/5 dark:border-strokedark dark:bg-boxdark dark:text-bodydark1 dark:hover:bg-primary/10"
                  )}
                  onClick={() => setActiveTab(tab.id_campo_personalizado)}
                  disabled={isSalvando}
                >
                  <span className="truncate">
                    {tab.nome_campo_personalizado}
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}

      <form
        onSubmit={handleFormSubmit}
        key={formulario?.key}
        className="relative w-full min-w-0"
      >
        <div
          className={cn(
            "relative overflow-hidden rounded-lg border border-stroke bg-white shadow-sm dark:border-strokedark dark:bg-boxdark",
            isSalvando && "pointer-events-none"
          )}
        >
          {isSalvando && (
            <div className="absolute inset-0 z-20 flex flex-col items-center justify-center gap-2 bg-white/85 backdrop-blur-[2px] dark:bg-boxdark/85">
              <LoaderSun height={56} />
              <span className="text-sm font-medium text-bodydark2">
                Salvando campo...
              </span>
            </div>
          )}

          {usaLayoutCard && campoAtivoExibicao && (
            <div className="border-b border-stroke bg-gradient-to-r from-slate-50 to-white px-5 py-4 dark:border-strokedark dark:from-meta-4/30 dark:to-boxdark">
              <div className="flex flex-wrap items-center gap-2">
                <h3 className="text-base font-semibold text-black dark:text-white">
                  {formatarTituloCampo(
                    campoAtivoExibicao.nome_campo_personalizado
                  )}
                </h3>
                {campoAtivoExibicao.obrigatorio_campo_personalizado === "1" && (
                  <span className="rounded-full bg-red-50 px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide text-red-600 dark:bg-red-900/20 dark:text-red-400">
                    Obrigatório
                  </span>
                )}
              </div>
              <p className="mt-1 text-xs text-bodydark2">
                Preencha o campo selecionado e clique em salvar.
              </p>
            </div>
          )}

          <div
            className={cn(
              "px-5 py-5",
              isSalvando && "opacity-60",
              classNameProps
            )}
          >
            {camposPersonalizados
              .filter((campo) => verificarConformidade(campo, false))
              .map((b: any) => {
                const isCampoAtivo =
                  !showTabs ||
                  !activeTab ||
                  activeTab === b.id_campo_personalizado;

                if (!isCampoAtivo) return null;

                return (
                  <div key={+b?.id_campo_personalizado}>
                    <CampoPersonalizadoComponente
                      formulario={formulario}
                      customIndex={customIndex}
                      dadosCampo={b}
                      localCampo={localCampo}
                      blockEditCard={blockEditCard}
                      setImagemFile={setImagemFile}
                      dataCard={dataCard}
                      idEtapa={dataCard?.id_lista}
                      idFluxo={dataCard?.funil_card}
                      idColeta={dataCard?.id_coleta_cliente}
                      pendenciaID={pendenciaID}
                      hideLabel={usaLayoutCard}
                      ignorarValoresGravados={ignorarValoresGravados}
                    />
                  </div>
                );
              })}
          </div>

          {temBotaoSalvar && (
            <div className="flex justify-end gap-2 border-t border-stroke bg-slate-50/70 px-5 py-3 dark:border-strokedark dark:bg-meta-4/10">
              {mostrarBotaoSalvar && (
                <Button
                  type="submit"
                  loading={isSalvando}
                  disabled={isSalvando || blockEditCard}
                >
                  {isSalvando ? "Salvando..." : textoBotaoSalvar}
                </Button>
              )}
              {children &&
                Children.map(children, (child) => {
                  if (!isValidElement(child)) return child;

                  const childProps = child.props as {
                    disabled?: boolean;
                  };

                  return cloneElement(child, {
                    loading: isSalvando,
                    disabled: isSalvando || childProps.disabled,
                    className: cn(
                      "px-5 xl:w-fit",
                      (child.props as { className?: string }).className
                    ),
                  } as any);
                })}
            </div>
          )}
        </div>
      </form>
    </div>
  );

  if (showBorderContainer) {
    return (
      <div className="relative mb-2 block rounded-lg border border-stroke p-2 pt-5">
        <span className="absolute -top-3 left-3 bg-white px-1 text-sm">
          Campos Personalizados
        </span>
        {conteudo}
      </div>
    );
  }
  if (showAccordion) {
    return (
      <Accordion
        type="single"
        className="my-5"
        collapsible
        defaultValue="filtros"
      >
        <AccordionItem value="filtros">
          <AccordionTrigger className="justify-center rounded-md bg-white pl-4 text-sm hover:text-black dark:bg-boxdark">
            <span className="flex items-center gap-2">
              Campos personalizados
            </span>
          </AccordionTrigger>
          <AccordionContent>{conteudo}</AccordionContent>
        </AccordionItem>
      </Accordion>
    );
  }

  return conteudo;
};

export default CamposPersonalizados;
