import { listarMotivoNegocioRestaurado } from "@/requests/CRUD/NegociosRestaurado/listarMotivoNegocioRestaurado";
import { listarTodosKanbans } from "@/requests/CRM/kanban";
import { GetForm } from "@/utils";
import { useEffect, useMemo, useState } from "react";
import { toast } from "react-toastify";
import * as yup from "yup";
import Button from "../Forms/Button";
import InputSelectComponent from "../Forms/InputSelect";
import ModalComponente from "./ModalComponente";

type ModalRestauracaoProps = {
  onSubmitRestaurar: (
    motivo: string,
    descrMotivo: string,
    destino?: { funil_destino: string; etapa_destino: string },
  ) => Promise<any>;
  closeFuncion: (ev?: any) => void;
  openModalRestaurar: boolean;
  dadosCard?: any;
  isColeta?: boolean;
};

const funilAceitaTipoNegocio = (funil: any, tipoNegocioCard: any) => {
  const tipoNegocioFunil = funil?.tipo_negocio_funil;
  if (!tipoNegocioFunil || tipoNegocioFunil === "" || tipoNegocioFunil === "*") {
    return true;
  }
  const tiposAceitos = String(tipoNegocioFunil)
    .split(",")
    .map((tipo: string) => tipo.trim());
  return tiposAceitos.includes(String(tipoNegocioCard));
};

const ModalRestauracao = ({
  onSubmitRestaurar,
  closeFuncion,
  openModalRestaurar,
  dadosCard,
}: ModalRestauracaoProps) => {
  const [motivosRestauracao, setMotivosRestauracao] = useState<any[]>([]);
  const [motivoSelecionado, setMotivoSelecionado] = useState<string>("");
  const [descrMotivoSelecionado, setDescrMotivoSelecionado] =
    useState<string>("");
  const [allFunis, setAllFunis] = useState<any[]>([]);
  const [funilDestino, setFunilDestino] = useState<string>("");
  const [etapaDestino, setEtapaDestino] = useState<string>("");
  const [yupSchemaRestaurar, setYupSchemaRestaurar] = useState<
    yup.ObjectSchema<{}, yup.AnyObject, {}, "">
  >(yup.object().shape({}));
  const [isLoading, setIsLoading] = useState(false);
  const [isLoadingFunis, setIsLoadingFunis] = useState(false);

  const { handleSubmit, ...formRestaurar } = GetForm(
    yupSchemaRestaurar,
    setYupSchemaRestaurar,
  );

  const funilOrigemInformado = String(dadosCard?.funil_card ?? "");
  const etapaOrigem = String(
    dadosCard?.id_lista ??
      dadosCard?.id_lista_card ??
      (Array.isArray(dadosCard?.etapas_coleta)
        ? dadosCard.etapas_coleta[0]
        : String(dadosCard?.etapas_coleta || "").split(",")[0] || ""),
  );
  const tipoNegocioCard = dadosCard?.tipoNegocio_coleta;

  const funisDisponiveis = useMemo(() => {
    return (allFunis || [])
      .filter(
        (funil) =>
          String(funil.id_funil) !== "0" &&
          String(funil.status_funil) !== "0" &&
          funilAceitaTipoNegocio(funil, tipoNegocioCard),
      )
      .sort((a: any, b: any) =>
        String(a.titulo_funil).localeCompare(String(b.titulo_funil), undefined, {
          numeric: true,
        }),
      );
  }, [allFunis, tipoNegocioCard]);

  const funilOrigem = useMemo(() => {
    if (funilOrigemInformado) return funilOrigemInformado;
    if (!etapaOrigem) return "";
    const funil = funisDisponiveis.find((f) =>
      (f.listas_kanban || []).some(
        (e: any) => String(e.id_etapa_funil) === etapaOrigem,
      ),
    );
    return funil ? String(funil.id_funil) : "";
  }, [funilOrigemInformado, etapaOrigem, funisDisponiveis]);

  const etapasDisponiveis = useMemo(() => {
    const funil = funisDisponiveis.find(
      (f) => String(f.id_funil) === String(funilDestino),
    );
    return (funil?.listas_kanban || [])
      .filter((etapa: any) => String(etapa.status_etapa_funil ?? "1") !== "0")
      .sort((a: any, b: any) =>
        String(a.index_etapa_funil).localeCompare(
          String(b.index_etapa_funil),
          undefined,
          { numeric: true },
        ),
      );
  }, [funisDisponiveis, funilDestino]);

  const origemFunilExiste = funisDisponiveis.some(
    (f) => String(f.id_funil) === funilOrigem,
  );
  const origemEtapaExiste =
    origemFunilExiste &&
    (funisDisponiveis
      .find((f) => String(f.id_funil) === funilOrigem)
      ?.listas_kanban || []
    ).some((e: any) => String(e.id_etapa_funil) === etapaOrigem);

  useEffect(() => {
    listarMotivoNegocioRestaurado().then((res) => {
      setMotivosRestauracao(
        res.filter((motivo: any) => motivo.status_restaurado == "1"),
      );
    });
  }, []);

  useEffect(() => {
    if (!openModalRestaurar) return;
    setIsLoadingFunis(true);
    listarTodosKanbans()
      .then((res) => setAllFunis(res || []))
      .finally(() => setIsLoadingFunis(false));
  }, [openModalRestaurar]);

  useEffect(() => {
    if (!openModalRestaurar || isLoadingFunis || funisDisponiveis.length === 0) {
      return;
    }

    if (origemFunilExiste) {
      setFunilDestino(funilOrigem);
      if (origemEtapaExiste) {
        setEtapaDestino(etapaOrigem);
      } else {
        setEtapaDestino("");
      }
    } else if (!funilDestino) {
      setFunilDestino(String(funisDisponiveis[0]?.id_funil ?? ""));
      setEtapaDestino("");
    }
  }, [
    openModalRestaurar,
    isLoadingFunis,
    funisDisponiveis,
    origemFunilExiste,
    origemEtapaExiste,
    funilOrigem,
    etapaOrigem,
  ]);

  const validarDestino = () => {
    if (!funilDestino || !etapaDestino) {
      toast.error("Selecione o fluxo e a etapa de destino.");
      return false;
    }

    const funil = funisDisponiveis.find(
      (f) => String(f.id_funil) === String(funilDestino),
    );
    if (!funil) {
      toast.error("Fluxo de destino inválido ou incompatível com o tipo de negócio.");
      return false;
    }

    const etapa = etapasDisponiveis.find(
      (e: any) => String(e.id_etapa_funil) === String(etapaDestino),
    );
    if (!etapa) {
      toast.error("Etapa de destino inválida para o fluxo selecionado.");
      return false;
    }

    return true;
  };

  const handleSubmitRestaurar = () => {
    if (!validarDestino()) return;

    setIsLoading(true);
    onSubmitRestaurar(motivoSelecionado, descrMotivoSelecionado, {
      funil_destino: String(funilDestino),
      etapa_destino: String(etapaDestino),
    }).finally(() => setIsLoading(false));
  };

  return (
    <ModalComponente
      hasForm={false}
      header="Restauração"
      defaultW="w-[480px]"
      opened={openModalRestaurar}
      onClose={closeFuncion}
      hasSaveButton={false}
    >
      <div className="mt-5">
        <div className="w-full text-center pb-4">
          <span className=" text-black-2 dark:text-white text-xl">
            <strong>Confirma Restauração do Negócio? </strong>
          </span>
        </div>

        <div className="bg-secondaryMenu bg-opacity-30 text-black-2 dark:text-white rounded-lg text-center text-lg mb-5 p-3">
          <span>
            Informe o motivo da{" "}
            <strong className="text-danger">
              <i>Restauração</i>
            </strong>{" "}
            e escolha o <strong>fluxo</strong> e a <strong>etapa</strong> de
            destino.
            {origemFunilExiste && origemEtapaExiste ? (
              <>
                <br />
                Origem sugerida:{" "}
                <strong>
                  {dadosCard?.titulo_funil_origem || "Fluxo de origem"}
                </strong>{" "}
                /{" "}
                <strong>
                  {dadosCard?.titulo_etapa_origem || "Etapa de origem"}
                </strong>
              </>
            ) : (
              <>
                <br />
                O fluxo/etapa de origem não estão mais disponíveis. Selecione um
                novo destino.
              </>
            )}
          </span>
        </div>

        <form
          className="flex flex-col gap-5"
          onSubmit={handleSubmit(handleSubmitRestaurar)}
        >
          <InputSelectComponent
            formulario={formRestaurar}
            label="Motivo Restauração"
            name="motivo_restauracao"
            required
            error="Escolha Algum Motivo"
            options={motivosRestauracao.map((res: any) => ({
              label: `${res.motivo_restaurado}`,
              value: `${res.id_restaurado}`,
            }))}
            onChange={(e: any) => {
              setMotivoSelecionado(e.value);
              setDescrMotivoSelecionado(e.label);
            }}
          />

          <InputSelectComponent
            formulario={formRestaurar}
            label="Fluxo Destino"
            name="funil_destino"
            required
            error="Selecione um fluxo"
            defaultValue={funilDestino}
            options={funisDisponiveis.map((funil: any) => ({
              label: funil.titulo_funil,
              value: String(funil.id_funil),
            }))}
            onChange={(e: any) => {
              setFunilDestino(String(e.value));
              setEtapaDestino("");
              formRestaurar.setValue?.("etapa_destino", "");
            }}
          />

          <InputSelectComponent
            formulario={formRestaurar}
            label="Etapa Destino"
            name="etapa_destino"
            required
            error="Selecione uma etapa"
            defaultValue={etapaDestino}
            options={etapasDisponiveis.map((etapa: any) => ({
              label: etapa.titulo_etapa_funil,
              value: String(etapa.id_etapa_funil),
            }))}
            onChange={(e: any) => {
              setEtapaDestino(String(e.value));
            }}
          />

          <Button loading={isLoading} className="w-full bg-primary mt-5">
            Salvar
          </Button>
        </form>
      </div>
    </ModalComponente>
  );
};

export default ModalRestauracao;
