"use client";

import Input from "@/components/Forms/Input";
import InputGroup from "@/components/Forms/InputGroup";
import InputSelectComponent from "@/components/Forms/InputSelect";
import { handleSweetAlert } from "@/components/Modal/SweetAlertConfirm";
import {
  FormatFields,
  GetForm,
  intersect,
  proximoNumero,
  proximoNumeroFloat,
} from "@/utils";
import { useEffect, useState } from "react";
import { FieldValues } from "react-hook-form";
import { toast } from "react-toastify";
import { IPoliticaPreco } from ".";

const FormPoliticaPreco = ({
  onSubmitFunction,
  defaultValues,
  disabledFields,
  children,
  columns: politicasDePreco,
  vincularPotencia,
  listdata,
  distribuidores,
  tiposTelhados,
  tiposNegocios,
  todosTiposNegocios,
  ...rest
}: {
  columns: IPoliticaPreco[];
  distribuidores: any[];
  tiposTelhados: any[];
  tiposNegocios: any[];
  todosTiposNegocios: any[];
  [x: string]: any;
}) => {
  const [hiddenFields, setHiddenFields] = useState<any[]>([]);
  const [disabledFieldsState, setDisabledFieldsState] = useState<any[]>([]);
  // const [openConfirm, setOpenConfirm] = useState(false);
  // const [confirmData, setConfirmData] = useState<any>({});
  // const [canConfirm, setCanConfirm] = useState(false);
  const [minRange, maxRange] = vincularPotencia
    ? ["potencia_min_variacao_politica", "potencia_max_variacao_politica"]
    : [
        "qtd_modulos_min_variacao_politica",
        "qtd_modulos_max_variacao_politica",
      ];
  const columnsPrecos = [
    ...politicasDePreco
      .filter((politica) => politica.columns)
      .filter((politica, indexPolitica) => indexPolitica > 0)
      .map((politica) => politica.columns),
  ].flat();

  const { handleSubmit, ...form } = GetForm();

  function onSubmitFormPoliticaPreco(data: FieldValues) {
    if (Number(data[minRange]) >= Number(data[maxRange])) {
      return toast.error(
        "O valor mínimo não pode ser maior que o valor máximo!"
      );
    }

    // Coleta os valores dos campos multiSelect antes da validação
    const telhadosSelecionados: string[] = [];
    const negociosSelecionados: string[] = [];
    const distribuidoresSelecionados: string[] = [];
    politicasDePreco.map((politica) => {
      if (politica.columns) {
        politica.columns.map((column) => {
          if (column.type == "multiSelect") {
            const val = data[column.accessorKey];
            // Normaliza para array de strings
            const arr: string[] = Array.isArray(val)
              ? val.map((v: any) => (typeof v === "object" ? v.value : v))
              : val
                ? [typeof val === "object" ? val.value : val]
                : [];

            if (column.accessorKey === "telhados_variacao_politica") {
              telhadosSelecionados.push(...arr);
            }
            if (column.accessorKey === "tipo_negocio_politica") {
              negociosSelecionados.push(...arr);
            }
            if (column.accessorKey === "distribuidores_variacao_politica") {
              distribuidoresSelecionados.push(...arr);
            }

            data[column.accessorKey] = arr.join(",");
          }
        });
      }
    });

    // Fix 01 – Validação obrigatória: Tipo de Telhado e Tipo de Negócio
    if (telhadosSelecionados.length === 0) {
      return toast.error("É obrigatório informar ao menos um Tipo de Telhado!");
    }
    if (negociosSelecionados.length === 0) {
      return toast.error("É obrigatório informar ao menos um Tipo de Negócio!");
    }
    if (distribuidoresSelecionados.length === 0) {
      return toast.error("É obrigatório informar ao menos um Distribuidor!");
    }

    if (validarDistribuidoresTelhados(listdata, data)) {
      if (
        columnsPrecos.every((column) => Number(data[column!.accessorKey]) == 0)
      ) {
        return toast.error("Todos os valores dos preços estão vazios");
      }
      return onSubmitFunction(data);
    }
  }

  function validarDistribuidoresTelhados(
    politicasDePreco: any[],
    novaPoliticaDePreco: any
  ) {
    for (const politicaDePrecoKey in politicasDePreco) {
      const politicaDePreco = politicasDePreco[politicaDePrecoKey];
      // if (!politicaDePreco.ativo) continue;
      const rangeAtual = [
        Number(politicaDePreco[minRange]),
        Number(politicaDePreco[maxRange]),
      ];
      const negociosAtual =
        politicaDePreco.tipo_negocio_politica == "*"
          ? tiposNegocios.map((n) => n.id_tipo_negocio)
          : politicaDePreco.tipo_negocio_politica.split(",");

      const negociosForm =
        novaPoliticaDePreco.tipo_negocio_politica == "*"
          ? tiposNegocios.map((n) => n.id_tipo_negocio)
          : novaPoliticaDePreco.tipo_negocio_politica.split(",");

      const temIntersecaoNegocio = negociosAtual.some((n: string) =>
        negociosForm.includes(n)
      );

      if (!temIntersecaoNegocio) {
        continue; // 👈 NÃO conflita, pula pra próxima política
      }

      const rangeForm = [
        Number(novaPoliticaDePreco[minRange]),
        Number(novaPoliticaDePreco[maxRange]),
      ];
      if (
        politicaDePreco.id_preco_politica != defaultValues?.id_preco_politica &&
        intersect(rangeAtual, rangeForm)
      ) {
        if (
          columnsPrecos.every(
            (column) =>
              Number(politicaDePreco[column!.accessorKey]) ==
              Number(novaPoliticaDePreco[column!.accessorKey])
          )
        ) {
          toast.error(
            "Todos os valores presentes nesta política de preço já estão presentes em outra política de preço neste mesmo range"
          );
          return false;
        }
        const distribuidoresAtual =
          politicaDePreco.distribuidores_variacao_politica == "*"
            ? distribuidores.map((distribuidor) => distribuidor.id_distribuidor)
            : politicaDePreco.distribuidores_variacao_politica.split(",");
        const distribuidoresTelhadosAtual = distribuidoresAtual.reduce(
          (acc: any, distribuidor: string) => {
            acc[distribuidor] =
              politicaDePreco.telhados_variacao_politica == "*"
                ? tiposTelhados.map((telhado) => telhado.id_telhado)
                : politicaDePreco.telhados_variacao_politica.split(",");
            return acc;
          },
          {}
        );
        const distribuidoresTelhadosEmUso = Object.keys(
          distribuidoresTelhadosAtual
        ).reduce((acc: any, distribuidor) => {
          if (
            (novaPoliticaDePreco.distribuidores_variacao_politica == "*"
              ? distribuidores.map(
                  (distribuidor) => distribuidor.id_distribuidor
                )
              : novaPoliticaDePreco.distribuidores_variacao_politica.split(",")
            ).includes(distribuidor)
          ) {
            distribuidoresTelhadosAtual[distribuidor].map((telhado: string) => {
              (novaPoliticaDePreco.telhados_variacao_politica == "*"
                ? tiposTelhados.map((telhado) => telhado.id_telhado)
                : novaPoliticaDePreco.telhados_variacao_politica.split(",")
              ).map((t: string) => {
                if (t == telhado) {
                  if (!acc[distribuidor]) {
                    acc[distribuidor] = [];
                  }
                  acc[distribuidor] = [...new Set([...acc[distribuidor], t])];
                }
              });
            });
          }
          return acc;
        }, {});
        if (Object.keys(distribuidoresTelhadosEmUso).length > 0) {
          handleSweetAlert(
            {
              icon: "warning",
              title: `Erro ao validar os distribuidores pelo tipo de telhado`,
              html: `
              <div class="max-h-[40vh] overflow-auto">
                <div>Os seguintes distribuidores já possuem os seguintes telhados neste mesmo range</div>
                <div>
                  ${Object.keys(distribuidoresTelhadosEmUso)
                    .map(
                      (distribuidor) => `
                      <fieldset class="flex flex-col border-black/25 border rounded p-2 px-3 w-full">
                        <legend class="font-bold">${distribuidores.find((d) => d.id_distribuidor == distribuidor)?.nome_distribuidor}</legend>
                        <div>${distribuidoresTelhadosEmUso[distribuidor]
                          .map(
                            (telhado: any) =>
                              tiposTelhados.find(
                                (tipoTelhado) =>
                                  tipoTelhado.id_telhado == telhado
                              )?.nome_telhado
                          )
                          .join(", ")}</div>
                      </fieldset>
                    `
                    )
                    .join("")}
                </div>
              </div>
              `,
              showDenyButton: false,
              confirmButtonText: "Ok",
            },
            () => {}
          );
          return false;
        }
      }
    }
    return true;
  }

  useEffect(() => {
    if (!defaultValues?.id_preco_politica) {
      if (vincularPotencia) {
        form.setValue(
          "potencia_min_variacao_politica",
          FormatFields.formatarNumero(
            proximoNumeroFloat(
              listdata.map((registro: any) => [
                Number(registro.potencia_min_variacao_politica),
                Number(registro.potencia_max_variacao_politica),
              ])
            )
          )
        );
      } else {
        form.setValue(
          "qtd_modulos_min_variacao_politica",
          String(
            proximoNumero(
              listdata.map((registro: any) => [
                Number(registro.qtd_modulos_min_variacao_politica),
                Number(registro.qtd_modulos_max_variacao_politica),
              ])
            )
          )
        );
      }
    }

    // Monitora calcular_imposto_projeto_politica (aplica já na montagem e em toda mudança)
    const aplicarEstadoImposto = (valor: any) => {
      // InputSelectComponent guarda a option inteira ({label, value}), não a string
      const calcularImpostoValue = valor?.value ?? valor;

      if (calcularImpostoValue === "0") {
        // Se for "Não Calcular", desabilita e zera o campo de %
        setDisabledFieldsState(["porcentagem_imposto_politica"]);
        form.setValue("porcentagem_imposto_politica" as never, "0" as never);
      } else {
        // Se for calcular, habilita o campo de %
        setDisabledFieldsState([]);
      }
    };

    aplicarEstadoImposto(form.getValues("calcular_imposto_projeto_politica"));

    const subscription = form.watch((data: any) => {
      aplicarEstadoImposto(data.calcular_imposto_projeto_politica);
    });

    return () => subscription.unsubscribe();
  }, []);

  return (
    <form
      onSubmit={handleSubmit(onSubmitFormPoliticaPreco)}
      key={form.key}
      {...rest}
    >
      {politicasDePreco.map(
        (politica, indexPolitica: number) =>
          politica.columns && (
            <InputGroup key={indexPolitica}>
              <fieldset
                className={`flex flex-col w-full border-${politica.className?.slice(3).split("/")[0]} border rounded p-2 px-3 ${politica.className} dark:border-secondary`}
                style={{
                  borderColor: politica.className?.slice(4).split("]")[0],
                }}
              >
                <legend className="px-3 text-black dark:text-white bg-white rounded dark:bg-black text-center font-bold uppercase">
                  {politica.header}
                </legend>
                <div className="flex flex-row flex-wrap gap-2 items-stretch">
                  {politica.columns?.map((column, indexField: number) =>
                    column.type ? (
                      <InputSelectComponent
                        key={indexField}
                        name={column.accessorKey}
                        label={
                          column.accessorKey === "telhados_variacao_politica" ||
                          column.accessorKey === "tipo_negocio_politica" ||
                          column.accessorKey ===
                            "distribuidores_variacao_politica"
                            ? `${column.header} *`
                            : column.header
                        }
                        width="min-w-[300px] flex-1"
                        defaultValue={
                          defaultValues && defaultValues[column.accessorKey]
                        }
                        options={
                          column.type == "multiSelect"
                            ? column.options
                              ? [
                                  ...(column.accessorKey ==
                                    "tipo_negocio_politica" &&
                                  tiposNegocios.length !=
                                    todosTiposNegocios?.length
                                    ? []
                                    : [{ label: "Todos", value: "*" }]),
                                  ...column.options,
                                ]
                              : []
                            : column.options || []
                        }
                        isMulti={column.type == "multiSelect"}
                        formulario={form}
                        disabled={disabledFields?.includes(column.accessorKey)}
                      />
                    ) : (
                      !hiddenFields.includes(column.accessorKey) && (
                        <Input
                          key={indexField}
                          name={column.accessorKey}
                          label={column.header}
                          width="min-w-[300px] flex-1"
                          defaultValue={
                            defaultValues && defaultValues[column.accessorKey]
                          }
                          mascara={column.mascara as any}
                          formulario={form}
                          disabled={disabledFieldsState.includes(
                            column.accessorKey
                          )}
                          // disabled={
                          //   politica.header == "Variações" && indexField == 0
                          // }
                          inputClassName={`bg-white/${politica.header == "Variações" && indexField == 0 ? 70 : 50}`}
                        />
                      )
                    )
                  )}
                </div>
              </fieldset>
            </InputGroup>
          )
      )}
      {children}
    </form>
  );
};

export default FormPoliticaPreco;
