import Input from "@/components/Forms/Input";
import InputGroup from "@/components/Forms/InputGroup";
import { handleSweetAlert } from "@/components/Modal/SweetAlertConfirm";
import { Button } from "@/components/ui/button";
import { FormatFields, GetForm } from "@/utils";
import { Info, Plus, X } from "lucide-react";
import {
  Dispatch,
  Fragment,
  SetStateAction,
  useCallback,
  useEffect,
  useMemo,
  useState,
} from "react";
import { BsPatchCheckFill } from "react-icons/bs";
import { toast } from "react-toastify";
import Swal from "sweetalert2";

// Tipos locais (mantém forma externa das UCs)
type TipoValor = "Média" | "Mensal";

type UC = {
  key: number;
  id_uc_coleta?: string;
  uc?: string;
  nome: string;
  valor: number | (string | number)[]; // mantém compatibilidade
  tipoValor: TipoValor;
  cosip_uc_coleta?: string | number;
  outros_custos_uc_coleta?: string | number;
  porcentagem_uc_coleta?: string | number;
  distribuicao_uc_coleta?: string | number;
  defaultOutrosCustos?: number;
  isAmpliacao_uc_coleta?: number;
};

type Props = {
  ucs: UC[];
  setUcs: Dispatch<SetStateAction<UC[]>>;
  dadosCard: any;
  parametros: any;
  semNumeroUc?: boolean;
  onChangeUcAtual?: (key: number) => void;
  porcentagens?: any;
  setPorcentagens: Dispatch<SetStateAction<Record<number, number>>>;
  setDistribuicaoManual?: Dispatch<SetStateAction<Record<number, number>>>;
  isDisabled?: boolean;
  blockEditCard?: boolean;
  [x: string]: any;
};

const MESES = [
  "Janeiro",
  "Fevereiro",
  "Março",
  "Abril",
  "Maio",
  "Junho",
  "Julho",
  "Agosto",
  "Setembro",
  "Outubro",
  "Novembro",
  "Dezembro",
];

// Helpers de cálculo
const toNum = (v: any): number | null => {
  if (v === null || v === undefined || v === "") return null;
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
};

const getMediaMensal = (valores: UC["valor"]): number => {
  if (!Array.isArray(valores)) return 0;
  const nums = valores
    .map(toNum)
    .filter((v): v is number => v !== null && Number.isFinite(v));
  if (!nums.length) return 0;
  return Math.round(nums.reduce((a, b) => a + b, 0) / nums.length);
};

const getConsumoRepresentativo = (uc: UC): number => {
  if (uc.tipoValor === "Mensal") {
    return getMediaMensal(uc.valor);
  }
  const n = toNum(uc.valor);
  return n ?? 0;
};

const UcsManager = ({
  ucs,
  setUcs,
  classificacao,
  dadosCard,
  parametros,
  cosipValue,
  semNumeroUc = false,
  onChangeUcAtual,
  setPorcentagens,
  setDistribuicaoManual,
  isDisabled = false,
  blockEditCard = false,
}: Props) => {
  // Seleção atual baseada em key (não índice)
  const [ucAtualKey, setUcAtualKey] = useState<number>(ucs?.[0]?.key ?? 0);

  // Garante que ao mudar a lista a seleção aponte para uma UC válida
  useEffect(() => {
    if (!ucs?.length) return;
    const exists = ucs.some((u) => u.key === ucAtualKey);
    if (!exists) {
      setUcAtualKey(ucs[ucs.length - 1]?.key);
    }
  }, [ucs, ucAtualKey]);

  const ucAtualIndex = useMemo(
    () => ucs.findIndex((u) => u.key === ucAtualKey),
    [ucs, ucAtualKey],
  );
  const ucAtual = ucAtualIndex >= 0 ? ucs[ucAtualIndex] : undefined;

  useEffect(() => {
    if (onChangeUcAtual && ucAtualKey !== undefined) {
      onChangeUcAtual(ucAtualKey);
    }
  }, [ucAtualKey, onChangeUcAtual]);

  const formMediaManager = GetForm();

  const obrigatorioMensal =
    parametros?.obrigado_digitar_consumo_mes_a_mes_parametro === "1";

  // Atualiza o form "media_uc" quando a UC atual for Mensal
  useEffect(() => {
    if (!ucAtual) return;
    if (ucAtual.tipoValor === "Mensal") {
      if (
        formMediaManager.getValues("media_uc" as never) !=
        String(getMediaMensal(ucAtual.valor))
      ) {
        formMediaManager.setValue(
          "media_uc",
          String(getMediaMensal(ucAtual.valor)),
        );
      }
    } else {
      if (formMediaManager.getValues("media_uc" as never) != "") {
        formMediaManager.setValue("media_uc", "");
      }
    }
  }, [ucAtual, formMediaManager]);

  // Validação
  const validarUcs = useCallback((lista: UC[]) => {
    const erros: { index: number; nome: string; erros: string[] }[] = [];

    lista.forEach((uc, index) => {
      const ucErros: string[] = [];

      if (!uc.uc && index > 0) {
        ucErros.push("não possui número de UC");
      }

      const consumoVazio =
        uc.tipoValor === "Média"
          ? !(toNum(uc.valor) && toNum(uc.valor)! > 0)
          : !(
              Array.isArray(uc.valor) &&
              uc.valor.some((v) => {
                const n = toNum(v);
                return n !== null && n > 0;
              })
            );

      if (consumoVazio) {
        ucErros.push("não possui consumo");
      }

      const repetida = lista.some(
        (u, i) => i !== index && u.uc && uc.uc && u.uc === uc.uc,
      );
      if (repetida) {
        ucErros.push("se repete");
      }

      // if (uc && uc.valor != null) {
      //   const n = toNum(uc.valor);
      //   if (n !== null && n > 100) {
      //     ucErros.push("não pode ser maior que 100%");
      //   }
      // }

      if (ucErros.length) {
        erros.push({ index, nome: uc.nome, erros: ucErros });
      }
    });

    return erros;
  }, []);

  const calcTotalConsumo = useMemo(() => {
    const total = ucs.reduce((acc, u) => acc + getConsumoRepresentativo(u), 0);
    return String(Math.round(total));
  }, [ucs]);

  const porcentagensFinais = useMemo(() => {
    const total = ucs.reduce((acc, u) => acc + getConsumoRepresentativo(u), 0);
    if (!total) return ucs.map(() => 0);
    return ucs.map(
      (u) => +((getConsumoRepresentativo(u) / total) * 100).toFixed(2),
    );
  }, [ucs]);

  const distribuicoesFinais = useMemo(() => {
    return ucs.map((uc) => {
      const val = parseFloat(String(uc.distribuicao_uc_coleta || 0));
      return isNaN(val) ? 0 : val;
    });
  }, [ucs]);

  // Propaga porcentagens para o pai
  useEffect(() => {
    const obj: Record<number, number> = {};
    porcentagensFinais.forEach((p, i) => (obj[i] = p));
    setPorcentagens(obj);
  }, [porcentagensFinais, setPorcentagens]);

  // Propaga distribuições manuais para o pai
  useEffect(() => {
    if (setDistribuicaoManual) {
      const obj: Record<number, number> = {};
      distribuicoesFinais.forEach((d, i) => (obj[i] = d));
      setDistribuicaoManual(obj);
    }
  }, [distribuicoesFinais, setDistribuicaoManual]);

  // Garante que UG sempre tenha 100% de distribuição
  useEffect(() => {
    setUcs((prev) => {
      const needsUpdate = prev.some(
        (uc: any) =>
          uc.isGeradora_uc_coleta == 1 && uc.distribuicao_uc_coleta !== "100",
      );

      if (!needsUpdate) return prev;

      return prev.map((uc: any) => {
        if (uc.isGeradora_uc_coleta == 1) {
          return {
            ...uc,
            distribuicao_uc_coleta: "100",
          };
        }
        return uc;
      });
    });
  }, [ucs]);

  // Classes auxiliares
  const classConsumo =
    "flex cursor-pointer relative dark:text-white rounded-md text-black border-primary text-lg border-[1px] py-1 px-4";
  const classSelecionada = `bg-primary ${classConsumo} text-white`;

  // Ações
  const handleAddUcBeneficiaria = () => {
    const erros = validarUcs(ucs);
    if (erros.length) {
      erros.forEach((e) => toast.error(`${e.nome} ${e.erros.join(", ")}`));
      return;
    }

    const lastKey = ucs.length ? ucs[ucs.length - 1].key : -1;
    const newKey = lastKey + 1;

    const novo: UC = {
      id_uc_coleta: "",
      uc: "",
      nome: "UB ",
      key: newKey,
      valor: obrigatorioMensal ? Array(12).fill("") : 0,
      tipoValor: obrigatorioMensal ? ("Mensal" as const) : ("Média" as const),
      cosip_uc_coleta: "",
      outros_custos_uc_coleta: ucs[0]?.defaultOutrosCustos,
      porcentagem_uc_coleta: "",
      distribuicao_uc_coleta: "",
    };

    setUcs((prev) => [...prev, novo]);
    setUcAtualKey(newKey);
  };

  const handleRemoveUcByIndex = (index: number) => {
    setUcs((prev) => {
      const next = prev.filter((_, i) => i !== index);
      // Ajusta seleção
      if (prev[index]?.key === ucAtualKey) {
        if (next.length) {
          const novoIndex = Math.min(index, next.length - 1);
          setUcAtualKey(next[novoIndex].key);
        }
      }
      return next;
    });
  };

  const alterarTipoConsumo = (uc: UC, media: TipoValor) => {
    setUcs((prev) => {
      const next = [...prev];
      const idx = next.findIndex((u) => u.key === uc.key);
      if (idx < 0) return prev;

      if (media === "Média") {
        const mediaCalc =
          uc.tipoValor === "Mensal"
            ? getMediaMensal(uc.valor)
            : (toNum(uc.valor) ?? 0);
        next[idx] = {
          ...uc,
          tipoValor: "Média",
          valor: mediaCalc,
        };
      } else {
        next[idx] = {
          ...uc,
          tipoValor: "Mensal",
          valor: Array(12).fill(""),
        };
      }
      return next;
    });
  };

  // Render
  return (
    <div>
      {/* {!semNumeroUc && ( */}
      <>
        <div className="w-full flex flex-col justify-center items-center">
          <div className="font-semibold text-primary">
            Média de Consumo de Todas as UCs informadas:{" "}
            <span>{calcTotalConsumo}</span>
          </div>
        </div>

        <div className="flex flex-row flex-wrap items-center gap-2 my-2">
          {ucs.map((uc, index) => {
            const last = ucs.length - 1;
            const isSelected = uc.key === ucAtualKey;
            return (
              <div
                key={uc.key}
                className="flex items-center gap-3 cursor-pointer"
              >
                <div
                  onClick={() => setUcAtualKey(uc.key)}
                  className={`${
                    isSelected
                      ? " bg-primary text-white"
                      : "border border-primary text-black dark:text-white"
                  } py-1 pl-3 pr-2 w-fit rounded-md flex flex-row items-center gap-1`}
                >
                  <p>{uc.nome}</p>
                  {!semNumeroUc && index > 0 && !isDisabled ? (
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        handleRemoveUcByIndex(index);
                      }}
                      className={`p-1 rounded ${isSelected ? "" : "bg-error"}`}
                    >
                      <X size={15} color="white" />
                    </button>
                  ) : null}
                </div>
                {!semNumeroUc && last === index && !isDisabled && (
                  <div
                    onClick={handleAddUcBeneficiaria}
                    className="text-primary hover:bg-primary hover:text-white rounded-md"
                  >
                    <Plus />
                  </div>
                )}
              </div>
            );
          })}
        </div>
      </>
      {/* )} */}

      {ucs.map((uc: any, indexUc) => {
        const isCurrent = uc.key === ucAtualKey;
        if (!isCurrent) return null;

        const mediaAtual =
          uc.tipoValor === "Mensal"
            ? getMediaMensal(uc.valor)
            : (toNum(uc.valor) ?? 0);

        const valorCosip = cosipValue?.find(
          (c: any) =>
            +mediaAtual >= Number(c.de_consumo_cosip) &&
            +mediaAtual <= Number(c.ate_consumo_cosip),
        );

        if (valorCosip) {
          if (classificacao?.value == 1) {
            uc.cosip_uc_coleta = valorCosip?.valor_residencial_cosip;
          } else {
            uc.cosip_uc_coleta = valorCosip?.valor_nao_residencial_cosip;
          }
        }
        return (
          <div key={uc.key} className={`${semNumeroUc ? "mt-5" : ""} w-full`}>
            <InputGroup className="max-sm:mt-2 justify-center ">
              {!semNumeroUc && (
                <Input
                  name=""
                  label={
                    uc.isGeradora_uc_coleta == "1" ? (
                      "Número da UC "
                    ) : (
                      <span className="w-fit flex flex-row gap-1">
                        Número da UC
                        <div className="px-1">
                          <Button
                            type="button"
                            className={` bg-primary flex flex-row gap-2 h-fit w-fit justify-center rounded-full p-1`}
                            onClick={(e: any) => {
                              e.stopPropagation();
                              handleSweetAlert({
                                icon: "info",
                                // title: "Cálculo Markup",
                                showDenyButton: false,
                                confirmButtonText: "Ok",
                                html: `A mesma UC Beneficiária poderá ser usada em mais de um projeto!`,
                              });
                            }}
                          >
                            <Info size={17} />
                          </Button>
                        </div>
                      </span>
                    )
                  }
                  mascara="numerico"
                  onChange={(e) => {
                    const value = e.target.value;
                    setUcs((prev) => {
                      const next = [...prev];
                      next[indexUc] = {
                        ...next[indexUc],
                        uc: value,
                        nome: indexUc === 0 ? `UG ${value}` : `UB ${value}`,
                      };
                      return next;
                    });
                  }}
                  value={uc.uc ?? ""}
                  disabled={blockEditCard}
                />
              )}

              {uc.tipoValor === "Mensal" ? (
                <Input
                  label={`Média Consumo ${semNumeroUc ? " Atual" : ""}`}
                  mascara="numerico"
                  error="Digite o Consumo Médio"
                  name={`media_uc`}
                  formulario={formMediaManager}
                  disabled
                  value={String(mediaAtual || "")}
                  key={1}
                />
              ) : (
                <Input
                  label={`Média Consumo ${semNumeroUc ? " Atual" : ""}`}
                  mascara="numerico"
                  error="Digite o Consumo Médio"
                  onChange={(e) => {
                    const v = e.target.value;
                    setUcs((prev) => {
                      const next = [...prev];
                      next[indexUc] = {
                        ...next[indexUc],
                        valor: v === "" ? 0 : Number(v),
                      };
                      return next;
                    });
                  }}
                  name={``}
                  value={String(uc.valor ?? "")}
                  disabled={isDisabled || obrigatorioMensal}
                  key={2}
                />
              )}

              {dadosCard?.tipoNegocio_coleta !== "3" && (
                <>
                  <Input
                    name=""
                    label="Valor médio da COSIP"
                    mascara="monetario"
                    prefix={"R$"}
                    onChange={(e) => {
                      setUcs((prev) => {
                        const next = [...prev];
                        next[indexUc] = {
                          ...next[indexUc],
                          cosip_uc_coleta: FormatFields.desformatarNumeros(
                            e.target.value,
                          ),
                        };
                        return next;
                      });
                    }}
                    value={String(uc.cosip_uc_coleta ?? "")}
                    disabled={blockEditCard}
                    clearBtn
                  />
                  <Input
                    name=""
                    label="Valor médio de outros custos"
                    mascara="monetario"
                    prefix={"R$"}
                    onChange={(e) => {
                      setUcs((prev) => {
                        const next = [...prev];
                        next[indexUc] = {
                          ...next[indexUc],
                          outros_custos_uc_coleta:
                            FormatFields.desformatarNumeros(e.target.value),
                        };
                        return next;
                      });
                    }}
                    value={String(uc.outros_custos_uc_coleta ?? "")}
                    disabled={blockEditCard}
                    clearBtn
                  />
                </>
              )}

              <div className="justify-center flex gap-4">
                {(obrigatorioMensal ? ["Mensal"] : ["Média", "Mensal"]).map(
                  (media: any, idx) => {
                    const selected = uc.tipoValor === media;
                    return (
                      <button
                        key={`${media}-${idx}`}
                        type="button"
                        onClick={() => {
                          if (uc.tipoValor === media) return;

                          if (uc.tipoValor === "Mensal" && media === "Média") {
                            Swal.fire({
                              title:
                                "Tem certeza que deseja alterar para média?",
                              icon: "warning",
                              html: "O consumo mensal individual será perdido!",
                              confirmButtonText: "Sim",
                              confirmButtonColor: "#4CAF50",
                              showDenyButton: true,
                              denyButtonText: "Não",
                            }).then((res) => {
                              if (res.isConfirmed) {
                                alterarTipoConsumo(uc, media);
                              }
                            });
                          } else if (
                            uc.tipoValor === "Média" &&
                            media === "Mensal"
                          ) {
                            Swal.fire({
                              title:
                                "Tem certeza que deseja alterar para o consumo mensal?",
                              icon: "warning",
                              html: "O consumo médio será perdido!",
                              confirmButtonText: "Sim",
                              confirmButtonColor: "#4CAF50",
                              showDenyButton: true,
                              denyButtonText: "Não",
                            }).then((res) => {
                              if (res.isConfirmed) {
                                alterarTipoConsumo(uc, media);
                              }
                            });
                          } else {
                            alterarTipoConsumo(uc, media);
                          }
                        }}
                        className={`${selected ? classSelecionada : classConsumo} ${isDisabled && "opacity-60"} max-sm:text-sm`}
                        disabled={isDisabled}
                      >
                        <span className="absolute top-0 right-0 transform translate-x-[30%] -translate-y-1/2 text-[#1e2661] text-xl bg-white rounded-xl p-[1px]">
                          {selected && <BsPatchCheckFill size={23} />}
                        </span>
                        {media === "Média"
                          ? "Média de Consumo"
                          : "Consumo Mensal"}
                      </button>
                    );
                  },
                )}
              </div>
            </InputGroup>

            {uc.tipoValor === "Mensal" && (
              <Fragment>
                <div className="flex justify-center my-4">
                  <p className="text-lg font-medium max-sm:text-sm uppercase">
                    Consumo Mensal
                  </p>
                </div>
                <InputGroup className="items-center grid justify-center md:grid-cols-3">
                  {MESES.map((mes, idxMes) => {
                    const arr = Array.isArray(uc.valor)
                      ? uc.valor
                      : Array(12).fill("");
                    const valueStr =
                      arr[idxMes] === null || arr[idxMes] === undefined
                        ? ""
                        : String(arr[idxMes]);

                    return (
                      <div
                        key={idxMes}
                        className="relative border-[1px] border-opacity-25 m-3 border-primary rounded-md p-4"
                      >
                        <span className="absolute top-0 left-0 transform translate-x-[20%] -translate-y-1/2 px-1 bg-white dark:bg-boxdark">
                          {mes}
                        </span>
                        <Input
                          mascara="numerico"
                          name=""
                          width="px-6"
                          onChange={(e) => {
                            const val = e.target.value;
                            setUcs((prev) => {
                              const next = [...prev];
                              const atual = next[indexUc];
                              const currentArr = Array.isArray(atual.valor)
                                ? [...atual.valor]
                                : Array(12).fill("");

                              currentArr[idxMes] = val;
                              next[indexUc] = {
                                ...atual,
                                valor: currentArr,
                              };
                              return next;
                            });
                          }}
                          value={valueStr}
                          disabled={isDisabled}
                        />
                      </div>
                    );
                  })}
                </InputGroup>
                <span className="w-full flex justify-center text-primary gap-2 font-semibold">
                  <span>Média de consumo:</span> {getMediaMensal(uc.valor)}
                </span>
              </Fragment>
            )}
          </div>
        );
      })}

      {!semNumeroUc && (
        <div className="flex w-full justify-center">
          <table className="w-auto table-auto self-center border-collapse text-left">
            <thead>
              <tr className="border-b">
                <th className="p-2">UC</th>
                <th className="p-2">% Consumo Geral</th>
                <th className="p-2">% Distribuição na Concessionária</th>
              </tr>
            </thead>
            <tbody>
              {ucs.map((uc: any, index) => (
                <tr key={uc.key} className="border-b">
                  <td className="p-2">{uc.nome || `UC ${index + 1}`}</td>
                  <td className="p-2">
                    <input
                      type="number"
                      className="w-full border rounded px-2 py-1"
                      value={porcentagensFinais[index] ?? 0}
                      disabled
                      max={100}
                      min={0}
                    />
                  </td>
                  <td className="p-2">
                    <input
                      type="number"
                      className="w-full border rounded px-2 py-1 dark:bg-boxdark dark:text-white"
                      value={uc.distribuicao_uc_coleta ?? ""}
                      onChange={(e) => {
                        const value = e.target.value;
                        setUcs((prev) => {
                          const next = [...prev];
                          next[index] = {
                            ...next[index],
                            distribuicao_uc_coleta: value === "" ? "" : value,
                          };
                          return next;
                        });
                      }}
                      onBlur={(e) => {
                        const value = e.target.value;
                        const numValue = parseFloat(value);

                        // Validação: não permitir valores maiores que 100
                        if (numValue > 100) {
                          toast.error("O valor não pode ser maior que 100%");
                          setUcs((prev) => {
                            const next = [...prev];
                            next[index] = {
                              ...next[index],
                              distribuicao_uc_coleta: "",
                            };
                            return next;
                          });
                          return;
                        }
                        // Calcula o total atual sem o valor da UC sendo editada
                        const totalOutrasUcs = ucs
                          .filter(
                            (u: any) =>
                              u.isGeradora_uc_coleta != 1 &&
                              uc.id_uc_coleta != u.id_uc_coleta,
                          )
                          .reduce((acc, u, i) => {
                            if (i === index) return acc; // Pula a UC atual
                            const val = parseFloat(
                              String(u.distribuicao_uc_coleta || 0),
                            );
                            return acc + (isNaN(val) ? 0 : val);
                          }, 0);

                        // Calcula o novo total com o valor digitado
                        const novoTotal =
                          totalOutrasUcs + (isNaN(numValue) ? 0 : numValue);

                        // Validação: não permitir que o total ultrapasse 100%
                        if (novoTotal > 100) {
                          const valorMaximoPermitido = 100 - totalOutrasUcs;
                          toast.error(
                            `O total não pode ultrapassar 100%. Valor máximo permitido para esta UC: ${valorMaximoPermitido.toFixed(2)}%`,
                          );
                          setUcs((prev) => {
                            const next = [...prev];
                            next[index] = {
                              ...next[index],
                              distribuicao_uc_coleta: "",
                            };
                            return next;
                          });
                          return;
                        }
                      }}
                      max={100}
                      min={0}
                      disabled={
                        (uc.isGeradora_uc_coleta == 1 && true) || blockEditCard
                      }
                    />
                  </td>
                </tr>
              ))}
            </tbody>
            <tfoot>
              <tr className="border-b">
                <td className="p-2">Quantidade: {ucs.length}</td>
                <td className="p-2">
                  Total:{" "}
                  {porcentagensFinais.reduce((a, b) => a + b, 0).toFixed(2)} %
                </td>
                <td className="p-2">
                  Total UBs:{" "}
                  {ucs
                    .filter((uc: any) => uc.isGeradora_uc_coleta != 1)
                    .reduce((acc, uc) => {
                      const val = parseFloat(
                        String(uc.distribuicao_uc_coleta || 0),
                      );
                      return acc + (isNaN(val) ? 0 : val);
                    }, 0)
                    .toFixed(2)}{" "}
                  % (da sobra da UG)
                </td>
              </tr>
            </tfoot>
          </table>
        </div>
      )}
    </div>
  );
};

export default UcsManager;
