import { Button } from "@/components/ui/button";
import { listarComponentesKitByKitId } from "@/requests/CRUD/ColetaDados/cadastroColetaDados";
import { listarProductsFromCategory } from "@/requests/CRUD/ColetaDados/listarProductsFromCategory";
import { obterDistribuicaoModulos } from "@/requests/CRUD/Propostas/obterDistribuicaoModulos";
import {
  calcularDistribuicaoModulos,
  calcularMPPTsKit,
  calcularTiposInversores,
  verificarMicroInversorModulosOverload,
} from "@/utils/inversorHelpers";
import { AnimatePresence, motion } from "framer-motion";
import katex from "katex";
import "katex/dist/katex.min.css";
import { InfoIcon } from "lucide-react";
import { useEffect, useState } from "react";
import Swal from "sweetalert2";
import ResumoValoresTrocaInversor from "./ResumoValoresTrocaInversor";
const MudancaInversorProposta = ({
  loaded,
  handleChangeProposalInversor,
  proposta,
}: any) => {
  const [alteradoValor, setAlteradoValor] = useState<any>(1);
  const [newChoiceInversores, setNewChoiceInversores] = useState<any>();
  const [kitProposta, setKitProposta] = useState<any>();
  const [kit, setKit] = useState<any>();
  const [newChoiceInversoresOriginal, setNewChoiceInversoresOriginal] =
    useState<any[]>([]);
  const [overload, setOverload] = useState<any>({
    overLoadValue: 0,
    overloadReferenceMax: 0,
    overloadReferenceMin: 0,
  });
  const [modulosLimit, setModulosLimit] = useState<any>({
    minModulos: 0,
    maxModulos: 0,
  });
  let minModulosTemp = 0;
  let [modulosLimitTemp, setModulosLimitTemp] = useState<any>({
    minModulos: 0,
    maxModulos: 0,
  });
  const [qtdModulos, setQtdModulos] = useState();
  const [inversoresUsados, setInversoresUsados] = useState<any>([]); // Novo state para armazenar os inversores usados
  const [novosInversoresSelecionados, setNovosInversoresSelecionados] =
    useState<any[]>([]);

  useEffect(() => {
    if (proposta && proposta.kit_proposta) {
      async function getComponents() {
        const res = await listarComponentesKitByKitId(proposta.kit_proposta);
        setKit(res);
        setKitProposta(res.componentesKit);
        setQtdModulos(
          res.componentesKit
            ?.filter((a: any) => a.tipo_item === "9")
            ?.map((a: any) => a.qtd_item)[0],
        );
        const inversores = await listarProductsFromCategory({
          id: "8",
          distribuidor: proposta?.codDistribuidor_kit,
        });

        const descricaoInversoresProposta = res.componentesKit
          ?.filter((a: any) => a.tipo_item === "8")
          ?.map((a: any) => a.descricao_item);

        const inversoresDisponiveis = inversores.filter(
          (a: any) => !descricaoInversoresProposta?.includes(a.descricao_item),
        );

        setNewChoiceInversores(inversores);
        setNewChoiceInversoresOriginal(inversores); // salva todos
      }

      getComponents();
    }
  }, []);

  const [salvarDistribuicaoModulos, setSalvarDistribuicaoModulos] = useState<
    any[]
  >([]);
  useEffect(() => {
    obterDistribuicaoModulos(proposta.id_proposta).then(
      setSalvarDistribuicaoModulos,
    );
  }, []);
  useEffect(() => {
    if (!kit || !novosInversoresSelecionados) return;

    const potenciaModulo = kitProposta.find(
      (item: any) => item.tipo_item == 9,
    )?.potencia_item;
    let inversores = kitProposta;
    if (novosInversoresSelecionados.length > 0) {
      inversores = novosInversoresSelecionados;
    }

    const { overloadReferenceMax } = inversores.reduce(
      (
        acc: { overloadReferenceMax: number; overloadReferenceMin: number },
        inversor: any,
      ) => {
        const potencia_min = +inversor?.potenciaNominalMinima_item || 0;
        const potencia_max = +inversor?.potenciaNominalMaxima_item || 0;

        return {
          overloadReferenceMin1:
            acc.overloadReferenceMin < potencia_min
              ? acc.overloadReferenceMin
              : potencia_min,
          overloadReferenceMax:
            acc.overloadReferenceMax +
            potencia_max * +(inversor.qtd_item ?? "1"),
        };
      },
      { overloadReferenceMax: 0, overloadReferenceMin1: Infinity },
    );

    const potenciaMinList = novosInversoresSelecionados
      .map((i) => Number(i.potenciaNominalMinima_item))
      .filter((v) => !isNaN(v));

    const overloadReferenceMin = potenciaMinList.length
      ? Math.min(...potenciaMinList)
      : 0;
    let overLoadValue = kit.extras.flatMap((a: any) => a.consumo)[0];

    const mppts_kit = calcularMPPTsKit(kit.componentesKit);
    const tipos_inversores_kit = calcularTiposInversores(kit.componentesKit);
    const totalModulos = kitProposta.find(
      (item: any) => item.tipo_item === "9",
    )?.qtd;
    const hasMicroInversorModulosOverload =
      verificarMicroInversorModulosOverload(kit.componentesKit, totalModulos);
    let totalMinModulos = 0;
    let totalMaxModulos = 0;
    const inversoresAtivos = novosInversoresSelecionados.map((inversor) => {
      const { minModulos, maxModulos } = calcularDistribuicaoModulos(
        inversor,
        potenciaModulo,
      );
      totalMinModulos += minModulos;
      totalMaxModulos += maxModulos;

      return { ...inversor, minModulos, maxModulos };
    });

    setModulosLimitTemp({
      minModulos: totalMinModulos,
      maxModulos: totalMaxModulos,
    });

    setInversoresUsados(inversoresAtivos);

    setModulosLimit({
      minModulos: totalMinModulos,
      maxModulos: totalMaxModulos,
    });
    setOverload({
      overLoadValue,
      overloadReferenceMin,
      overloadReferenceMax,
    });

    if (
      mppts_kit < salvarDistribuicaoModulos.length ||
      overLoadValue > overloadReferenceMax ||
      overLoadValue < overloadReferenceMin ||
      Object.keys(tipos_inversores_kit).length > 1 ||
      tipos_inversores_kit["micro_inversor"] > 1 ||
      hasMicroInversorModulosOverload
    ) {
      if (
        overLoadValue > overloadReferenceMax ||
        overLoadValue < overloadReferenceMin
      ) {
      }
      // if (Object.keys(tipos_inversores_kit).length > 1) {
      //   // (
      //   //   "Não é possível utilizar inversor de parede e microinversor no mesmo kit"
      //   // ) ou não era;
      // }
      if (tipos_inversores_kit["micro_inversor"] > 1) {
      }
      if (hasMicroInversorModulosOverload) {
        const microInversorModulosOverload = kitProposta.find(
          (componente: any) =>
            componente.tipoInversor_item === "micro_inversor" &&
            +componente.qtd_item <
              totalModulos / +componente.qtdModulos_max_item,
        );
      }
    }
  }, [novosInversoresSelecionados, alteradoValor]);
  const [inversoresIguais, setInversoresIguais] = useState(false);
  useEffect(() => {
    const descricaoInversoresProposta = kitProposta
      ?.filter((a: any) => a.tipo_item === "8")
      ?.map((a: any) => a.descricao_item);
    const qtdItemProposta = kitProposta
      ?.filter((a: any) => a.tipo_item === "8")
      ?.map((a: any) => a.qtd_item);
    const descricaoIversoresNovos = novosInversoresSelecionados.map(
      (a: any) => a.descricao_item,
    );
    const qtdItemNovo = novosInversoresSelecionados.map((a: any) => a.qtd_item);
    const saoIguais =
      Array.isArray(descricaoIversoresNovos) &&
      Array.isArray(descricaoInversoresProposta) &&
      descricaoIversoresNovos.length === descricaoInversoresProposta.length &&
      descricaoIversoresNovos.every(
        (valor, index) =>
          valor === descricaoInversoresProposta[index] &&
          qtdItemNovo[index] === qtdItemProposta[index],
      );

    if (saoIguais) {
      setInversoresIguais(true);
    } else {
      setInversoresIguais(false);
    }
  }, [novosInversoresSelecionados, alteradoValor]);
  const overloadFunction = () => {
    const { overLoadValue, overloadReferenceMax, overloadReferenceMin } =
      overload;
    return (
      <div className="flex gap-4">
        <fieldset className="flex flex-col border-black/25 border rounded p-2 px-3 w-fit">
          <legend>Overload do inversor</legend>
          <div className="flex flex-row items-center gap-2">
            <div>{String(overloadReferenceMin)}</div>
            <div className="w-[200px] h-[20px] bg-black-2/30 rounded overflow-hidden">
              <div
                className="h-full flex flex-row items-center relative rounded " // bg-gradient-to-r from-primary to-error
                style={{
                  width:
                    (((overLoadValue - overloadReferenceMin) * 100) /
                      (overloadReferenceMax - overloadReferenceMin)) *
                      2 +
                    "px",
                  background:
                    "linear-gradient(90deg, rgba(9,9,121,1) 0, rgba(9,9,121,1) 100px, rgba(255,0,0,1) 200px)",
                }}
              >
                <div className="text-sm max-sm:text-xs text-white font-bold absolute left-[50%]">
                  {String(overLoadValue)}
                </div>
              </div>
            </div>
            <div>
              {new Intl.NumberFormat("pt-BR", {
                maximumFractionDigits: 2,
              }).format(overloadReferenceMax)}
            </div>
          </div>
        </fieldset>
        <fieldset className="border px-4 py-3 rounded shadow-sm w-fit">
          <legend>Capacidade do(s) Inversor(es)</legend>
          <div className="flex items-center gap-3 text-base-content">
            <svg
              xmlns="http://www.w3.org/2000/svg"
              className="h-6 w-6 text-primary"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"
              />
            </svg>
            <div className="flex gap-4">
              <div className="flex items-center gap-1">
                <span className="font-medium">Mínimo:</span>
                <span className="text-primary font-semibold">
                  {modulosLimit.minModulos}
                </span>
              </div>
              <div className="h-6 w-px bg-primary/20" />
              <div className="flex items-center gap-1">
                <span className="font-medium">Máximo:</span>
                <span className="text-primary font-semibold">
                  {modulosLimit.maxModulos}
                </span>
              </div>
            </div>
            <Button
              className="bg-transparent text-primary p-0"
              type="button"
              onClick={(e: any) => {
                e.stopPropagation();

                // Gerar a fórmula para cada inversor
                const formulas = inversoresUsados.map(
                  (inversor: any, index: number) => {
                    const potenciaInversorW =
                      parseFloat(inversor.potencia_item) * 1000; // kW para W
                    const underload = +inversor.underload_item / 100;
                    const overload = +inversor.overload_item / 100;
                    const potenciaModulo = kitProposta.find(
                      (modulo: any) => modulo.tipo_item == 9,
                    )?.potencia_item;

                    const qtdItem = parseInt(inversor.qtd_item) || 1;

                    // Cálculo dos módulos mínimos e máximos
                    const minModulos = Math.floor(
                      (potenciaInversorW * qtdItem * underload) /
                        potenciaModulo,
                    );
                    const maxModulos = Math.floor(
                      (potenciaInversorW * qtdItem * overload) / potenciaModulo,
                    );

                    return `
                      \\begin{array}{c}
                        \\text{${inversor.descricao_item.split(" ").slice(0, 4).join(" ")}} \\\\
                        \\begin{bmatrix}
                          \\text{Mín.} = \\frac{${potenciaInversorW} \\times ${qtdItem} \\times ${underload}}{${potenciaModulo}} = ${minModulos} \\\\
                          \\text{Máx.} = \\frac{${potenciaInversorW} \\times ${qtdItem} \\times ${overload}}{${potenciaModulo}} = ${maxModulos}
                        \\end{bmatrix}
                      \\end{array}
                    `;
                  },
                );

                // Montar o HTML para exibir as fórmulas separadamente
                const formulasHtml = formulas
                  .map((formula: any) => {
                    return `<div style="display: flex; flex-direction: column; margin-bottom: 20px; text: 10px;">${katex.renderToString(
                      formula,
                      { throwOnError: false },
                    )}</div>`;
                  })
                  .join("");

                Swal.fire({
                  icon: "info",
                  showConfirmButton: false,
                  title: "Fórmulas por Inversor",
                  html: `
                      <div style="display: flex; flex-direction: column; align-items: center; font-size: 0.9rem; padding: 10px;">
                        ${formulasHtml}
                      </div>
                    `,
                });
              }}
            >
              <InfoIcon size={24} />
            </Button>
          </div>
        </fieldset>
      </div>
    );
  };
  const canChangeInversor = (): boolean => {
    let totalMinModulos = 0;
    if (kitProposta) {
      const potenciaModulo = kitProposta.find(
        (item: any) => item.tipo_item == 9,
      )?.potencia_item;

      novosInversoresSelecionados.map((inversor) => {
        const { minModulos } = calcularDistribuicaoModulos(
          inversor,
          potenciaModulo,
        );

        totalMinModulos += minModulos;
      });
    }

    const qtdTotalModulos = +qtdModulos!;

    return totalMinModulos < qtdTotalModulos;
  };
  const [canChangeView, setCanChangeView] = useState(false);

  const handleChangeTrigger = (valorTotal: any) => {
    handleChangeProposalInversor(
      valorTotal,
      novosInversoresSelecionados,
      modulosLimit,
    );
  };
  const [qtdInversorZerada, setQtdInversorZerada] = useState(false);
  const validateQtd = () => {
    const algumComZero = novosInversoresSelecionados.some(
      (item) => Number(item.qtd_item) === 0,
    );
    setQtdInversorZerada(algumComZero);
  };

  const conteudoMudancaInversor = () => (
    <div className="flex justify-evenly">
      <div className="flex flex-col text-black  gap-10 items-center">
        <div className="border rounded-md relative px-15 p-7">
          <div className="absolute -top-3 bg-white px-4">
            Inversores atuais da proposta:
          </div>
          <div className="grid gap-3">
            {kitProposta &&
              kitProposta
                ?.filter((a: any) => a.tipo_item === "8")
                ?.map((kit: any, i: number) => (
                  <div key={i} className="flex items-center gap-2">
                    <span className="p-1 bg-stroke px-3 text-sm rounded-md">
                      {kit.qtd_item}x
                    </span>
                    <span>{kit.descricao}</span>
                  </div>
                ))}
          </div>
        </div>
        <hr />
        <div className="my-3 border rounded-md relative px-5 p-7">
          <span className="absolute -top-3 bg-white px-4">
            Inversores diponiveis pra troca
          </span>
          <div className="grid overflow-auto px-1 h-[50vh]">
            {newChoiceInversores &&
              newChoiceInversores?.map((inv: any, i: number) => {
                return (
                  <div
                    key={i}
                    className={`p-4 my-1 hover:rounded-sm hover:cursor-pointer hover:bg-opacity-30 ${newChoiceInversores.length - 1 !== i && "border-b"} hover:bg-stroke`}
                    onClick={() => {
                      setNovosInversoresSelecionados((prev) => [...prev, inv]);
                      setNewChoiceInversores((prev: any) =>
                        prev.filter(
                          (item: any) => item.id_item !== inv.id_item,
                        ),
                      );
                    }}
                  >
                    <span>{inv.descricao_item}</span>
                  </div>
                );
              })}
          </div>
        </div>
      </div>
      <div className="flex relative  flex-col text-black gap-5">
        <span className="text-lg font-semibold">
          Novos inversores selecionados
        </span>
        {overloadFunction()}
        <div className="gap-2 flex flex-col  h-[54vh] overflow-auto">
          {novosInversoresSelecionados.map((inv: any, i: number) => (
            <div className="flex items-center gap-2" key={i}>
              <div className="items">
                <input
                  key={i}
                  className={`border [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none text-center text-sm rounded-md p-2 w-14 border-stroke`}
                  type="number"
                  defaultValue={alteradoValor}
                  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                    let valorDigitado = e.target.value;
                    let novoValor = +valorDigitado;

                    setAlteradoValor(valorDigitado);

                    novosInversoresSelecionados[i].qtd_item = String(novoValor);

                    validateQtd();
                  }}
                />
              </div>
              <span>x</span>
              <div
                key={inv.id_item}
                className="flex justify-between w-full items-center border text-sm p-3 rounded-md bg-gray-50"
              >
                <span>{inv.descricao_item}</span>
                <button
                  className="text-[#e21111] hover:text-red-700 text-sm hover:bg-stroke p-2 rounded-md hover:bg-opacity-40 font-medium ml-4"
                  onClick={() => {
                    setNovosInversoresSelecionados((prev) =>
                      prev.filter((item) => item.id_item !== inv.id_item),
                    );
                    setNewChoiceInversores((prev: any) => [...prev, inv]);
                  }}
                >
                  Remover
                </button>
              </div>
            </div>
          ))}
        </div>
        {!canChangeInversor() && (
          <>
            <span className="absolute text-center text-danger font-semibold w-full bottom-10">
              A quantidade de módulos selecionada é {qtdModulos}
            </span>
          </>
        )}
        {inversoresIguais && (
          <span className="absolute text-center text-danger font-semibold w-full bottom-10">
            Não haverá troca pois não foi escolhido inversores diferentes da
            proposta atual.
          </span>
        )}
        {qtdInversorZerada && (
          <span className="absolute text-center text-danger font-semibold w-full bottom-10">
            A quantidade de inversor não pode ser 0.
          </span>
        )}

        <Button
          className="absolute bottom-0 w-full"
          type="button"
          disabled={
            novosInversoresSelecionados.length === 0 ||
            loaded ||
            qtdInversorZerada ||
            inversoresIguais ||
            !canChangeInversor()
          }
          onClick={() => {
            setCanChangeView(true);
          }}
        >
          Avançar
        </Button>
      </div>
    </div>
  );
  return !canChangeView ? (
    conteudoMudancaInversor()
  ) : (
    <AnimatePresence>
      <motion.div
        initial={{ opacity: 0, x: 100 }}
        animate={{ opacity: 1, x: 0 }}
        exit={{ opacity: 0, x: -100 }}
        transition={{ duration: 0.3 }}
        className="w-full h-full  rounded-md no-scrollbar overflow-auto"
      >
        <ResumoValoresTrocaInversor
          setCanChangeView={setCanChangeView}
          loaded={loaded}
          handleChangeTrigger={handleChangeTrigger}
          valorProposta={proposta?.valorTotal_proposta}
          novosInversoresSelecionados={novosInversoresSelecionados}
          inversoresAntigos={kitProposta}
        />
      </motion.div>
    </AnimatePresence>
  );
};
export default MudancaInversorProposta;
