import Button from "@/components/Forms/Button";
import Input from "@/components/Forms/Input";
import InputGroup from "@/components/Forms/InputGroup";
import InputSelectComponent from "@/components/Forms/InputSelect";
import { listarUsuarios } from "@/requests/CRM/Dashboard/listarDashboard";
import {
  listarNiveldeMetas,
  listarObjetivosMetas,
  listarPeriodosMetas,
} from "@/requests/CRM/Metas/listarMetas";
import { listarLojas } from "@/requests/CRUD/Lojas/listarLojas";
import { listarPerfis } from "@/requests/CRUD/Perfil/listarPerfis";
import { listarTiposNegocios } from "@/requests/CRUD/TiposNegocios/listarTiposNegocios";
import { GetForm } from "@/utils";
import { useEffect, useState } from "react";
import * as yup from "yup";
const FormEditarMeta = ({
  defaultValues,
  onEditFunction,
  isLoading,
  ...rest
}: any) => {
  const [yupSchema, setYupSchema] = useState<
    yup.ObjectSchema<{}, yup.AnyObject, {}, "">
  >(yup.object().shape({}));
  const { handleSubmit, ...form } = GetForm(yupSchema, setYupSchema);

  const [nivelSelecionado, setNivelSelecionado] = useState<number>(
    defaultValues?.nivel_meta_politica || 0,
  );
  const [inicioMeta, setInicioMeta] = useState<string>(
    defaultValues["dataInicial_meta_politica"],
  );
  const [selectedObjetivoTipo, setSelectedObjetivoTipo] = useState<number>(0);
  const [validadeLabel, setValidadeLabel] = useState<string>("Quantidade ");
  const [selectedPeriodo, setSelectedPeriodo] = useState<string>(
    defaultValues["periodo_meta_politica"],
  );
  const [sugerirEdicao, setSugerirEdicao] = useState(true);

  const [limiteAceitavel, setLimiteAceitavel] = useState<number>(0);
  const [limiteCritico, setLimiteCritico] = useState<number>(0);
  const [objetivoMeta, setObjetivosMeta] = useState<any[]>([]);
  const [tiposNegocio, setTiposNegocio] = useState<any[]>([]);
  const [validadeMeta, setValidadeMeta] = useState<number>();
  const [periodoMeta, setPeriodosMeta] = useState<any[]>([]);
  const [nivelMeta, setNivelMeta] = useState<any[]>([]);
  const [usuarios, setUsuarios] = useState<any[]>([]);
  const [perfils, setPerfils] = useState<any[]>([]);
  const [lojas, setLojas] = useState<any[]>([]);

  const handlePeriodoChange = (value: string) => {
    setSelectedPeriodo(value);
    switch (value) {
      case "1":
        setValidadeLabel("Quantidade de semanas");
        break;
      case "2":
        setValidadeLabel("Quantidade de Quinzenas");
        break;
      case "3":
        setValidadeLabel("Quantidade de Meses");
        break;
      case "4":
        setValidadeLabel("Quantidade de Trimestres");
        break;
      case "5":
        setValidadeLabel("Quantidade de Semestres");
        break;
      case "6":
        setValidadeLabel("Quantidade de Anos");
        break;
      default:
        setValidadeLabel("Validade Meta");
        break;
    }
  };

  const handleValidadeChange = (value: string) => {
    setValidadeMeta(Number(value));
  };

  const handleInicioMetaChange = (value: string) => {
    setInicioMeta(value);
  };

  const handleNivelChange = (value: any) => {
    setNivelSelecionado(Number(value));
  };

  const handleLimiteCriticoChange = (value: string) => {
    let numValue = parseInt(value);

    if (numValue > 100) {
      form.setValue("limiteCritico_meta_politica", 99);
      numValue = 99;
    }

    setLimiteCritico(numValue);

    if (numValue == 99) {
      form.setValue("limiteAceitavel_meta_politica", "-", {
        shouldDirty: true,
      });
    }
  };

  const handleLimiteAceitavelChange = (value: string) => {
    let numValue = parseInt(value);

    if (numValue > 100) {
      form.setValue("limiteAceitavel_meta_politica", 99);
      numValue = 99;
    }

    setLimiteAceitavel(numValue);
  };

  useEffect(() => {
    listarPeriodosMetas().then((res) => {
      setPeriodosMeta(res);
    });
  }, []);
  function formatDateToLocalISO(date: Date) {
    const tzOffset = date.getTimezoneOffset() * 60000; // offset in ms
    const localISO = new Date(date.getTime() - tzOffset)
      .toISOString()
      .split("T")[0];
    return localISO;
  }

  const calcularFimMeta = () => {
    const validadeMeta = Number(
      form.control._formValues["quantidade_meta_politica"],
    );
    const inicioMeta = form.control._formValues["dataInicial_meta_politica"];
    if (inicioMeta && validadeMeta && selectedPeriodo) {
      const [ano, mes, dia] = inicioMeta.split("-").map(Number);
      const inicio = new Date(ano, mes - 1, dia); // mês começa do zero

      let fim: Date;

      switch (selectedPeriodo) {
        case "1": // Semanal
          fim = new Date(
            inicio.setDate(inicio.getDate() + validadeMeta * 7 - 1),
          );
          break;
        case "2": // Quinzenal
          fim = new Date(
            inicio.setDate(inicio.getDate() + validadeMeta * 15 - 1),
          );
          break;
        case "3": // Mensal
          const dataFimCalculada = new Date(inicio);
          dataFimCalculada.setMonth(dataFimCalculada.getMonth() + validadeMeta);

          dataFimCalculada.setDate(dataFimCalculada.getDate() - 1);

          fim = dataFimCalculada;

          break;
        case "4": // Trimestral
          const dataFimTriCalculada = new Date(inicio);
          dataFimTriCalculada.setMonth(
            dataFimTriCalculada.getMonth() + validadeMeta * 3,
          );
          dataFimTriCalculada.setDate(dataFimTriCalculada.getDate() - 1);
          fim = dataFimTriCalculada;
          break;
        case "5": // Semestral
          const dataFimSemCalculada = new Date(inicio);
          dataFimSemCalculada.setMonth(
            dataFimSemCalculada.getMonth() + validadeMeta * 6,
          );
          dataFimSemCalculada.setDate(dataFimSemCalculada.getDate() - 1);
          fim = dataFimSemCalculada;
          // fim = new Date(inicio.setMonth(inicio.getMonth() + validadeMeta * 6));
          break;
        case "6": // Anual
          const dataFimAnualCalculada = new Date(inicio);
          dataFimAnualCalculada.setFullYear(
            inicio.getFullYear() + validadeMeta,
          );

          dataFimAnualCalculada.setDate(dataFimAnualCalculada.getDate() - 1);
          fim = dataFimAnualCalculada;
          break;
        default:
          return;
      }

      form.setValue("dataFinal_meta_politica", formatDateToLocalISO(fim));
    }
  };

  useEffect(() => {
    listarObjetivosMetas().then((res) => {
      setObjetivosMeta(res);
    });
  }, []);

  useEffect(() => {
    listarNiveldeMetas().then((res) => {
      setNivelMeta(res);
    });
    listarLojas().then((res) => setLojas(res));
    listarTiposNegocios().then((res) => setTiposNegocio(res));
    listarPerfis().then((res) => setPerfils(res));
    listarUsuarios().then((res) => setUsuarios(res));
  }, []);

  useEffect(() => {
    calcularFimMeta();
  }, [inicioMeta, validadeMeta, selectedPeriodo]);

  useEffect(() => {
    if (defaultValues?.valorObjetivo_meta_politica) {
      let formattedValue = defaultValues.valorObjetivo_meta_politica;

      switch (selectedObjetivoTipo) {
        case 0: // Numérico
          formattedValue = Number(formattedValue).toLocaleString("pt-BR", {
            maximumFractionDigits: 0,
          });
          break;
        case 1: // Monetário
          formattedValue = Number(formattedValue)
            .toLocaleString("pt-BR", {
              minimumFractionDigits: 2,
              maximumFractionDigits: 2,
            })
            .replace(".", ",");
          break;
        case 2: // Porcentagem
          formattedValue =
            `${Number(formattedValue)
              .toLocaleString("pt-BR", {
                minimumFractionDigits: 2,
                maximumFractionDigits: 2,
              })
              .replace(".", ",")}` + "%";
          break;
      }

      form.setValue("valorObjetivo_meta_politica", formattedValue);
    }
  }, [selectedObjetivoTipo]);
  useEffect(() => {
    if (defaultValues && defaultValues["dataFinal_meta_politica"]) {
      form.setValue(
        "dataFinal_meta_politica",
        defaultValues["dataFinal_meta_politica"],
      );
    }
  }, []);

  useEffect(() => {
    if (!sugerirEdicao) return;

    const nome = form.watch("nome_meta_politica" as any);
    const nivel = form.watch("nivel_meta_politica" as any);
    const periodo = form.watch("periodo_meta_politica" as any);

    const descricaoGerada = gerarDescricao(nome, nivel, periodo);

    if (descricaoGerada) {
      form.setValue("descricao_meta_politica", descricaoGerada);
    }
  }, [
    form.watch("nome_meta_politica" as any),
    form.watch("nivel_meta_politica" as any),
    form.watch("periodo_meta_politica" as any),
    sugerirEdicao,
  ]);
  function gerarDescricao(nome: any, nivel: any, periodo: any) {
    if (!nome || !nivel || !periodo) return "";

    return `Meta ${nome} de ${nivel} com o período ${periodo}`;
  }

  const lojasSelecionadas = form.watch("lojas_meta_politica" as any) || [];
  const tiposNegocioSelecionados =
    form.watch("tiposNegocio_meta_politica" as any) || [];
  const perfisSelecionados = form.watch("perfis_meta_politica" as any) || [];
  const usuariosSelecionados = form.watch("usuarios_meta_politica" as any) || [];
  return (
    <form onSubmit={handleSubmit(onEditFunction)}>
      <InputGroup className=" mb-5">
        <Input
          name="nome_meta_politica"
          formulario={form}
          label="Nome da Meta"
          width="xl:w-1/2"
          required
          error="Preencha esse campo"
          defaultValue={defaultValues && defaultValues["nome_meta_politica"]}
        />
        <InputSelectComponent
          label="Período Meta"
          name="periodo_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          options={periodoMeta.map((e) => ({
            label: e.nome_metas_periodo,
            value: e.id_metas_periodo,
          }))}
          value={selectedPeriodo}
          onChange={(e: any) => {
            const value = e?.target?.value || e?.value;
            handlePeriodoChange(value);
            if (["3", "4", "5", "6"].includes(value)) {
              const dataInici =
                form.control._formValues["dataInicial_meta_politica"];
              if (dataInici) {
                const [year] = dataInici.split("-").map(Number);
                let selectedDate;

                if (value === "6") {
                  // Sempre 01/01 do ano selecionado
                  selectedDate = new Date(year, 0, 1);
                } else {
                  // Primeiro dia do mês selecionado
                  const [, month] = dataInici.split("-").map(Number);
                  selectedDate = new Date(year, month - 1, 1);
                }

                form.setValue(
                  "dataInicial_meta_politica",
                  formatDateToLocalISO(selectedDate),
                );
              }
            }
          }}
          required
          error="Preencha esse campo"
          defaultValue={defaultValues && defaultValues["periodo_meta_politica"]}
        />
      </InputGroup>

      <InputGroup>
        <Input
          name="quantidade_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          label={validadeLabel}
          mascara="numerico"
          required
          error="Preencha esse campo"
          onChange={(e) => handleValidadeChange(e.target.value)}
          defaultValue={
            defaultValues && defaultValues["quantidade_meta_politica"]
          }
        />

        <Input
          name="dataInicial_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          label="Início da Meta"
          error="Preencha esse campo"
          onChange={(e) => {
            if (["3", "4", "5", "6"].includes(selectedPeriodo)) {
              const [year] = e.target.value.split("-").map(Number);
              let selectedDate;

              if (selectedPeriodo === "6") {
                // Sempre 01/01 do ano selecionado
                selectedDate = new Date(year, 0, 1);
              } else {
                // Primeiro dia do mês selecionado
                const [, month] = e.target.value.split("-").map(Number);
                selectedDate = new Date(year, month - 1, 1);
              }

              form.setValue(
                "dataInicial_meta_politica",
                formatDateToLocalISO(selectedDate),
              );
            }

            handleInicioMetaChange(e.target.value);
          }}
          type="date"
          defaultValue={
            defaultValues && defaultValues["dataInicial_meta_politica"]
          }
        />

        <Input
          name="dataFinal_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          label="Fim da Meta"
          error="Preencha esse campo"
          type="date"
          disabled
        />
      </InputGroup>

      <InputGroup>
        <InputSelectComponent
          label="Objetivo da Meta"
          name="objetivo_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          options={objetivoMeta.map((e) => ({
            label: e.nome_objetivo_meta,
            value: e.id_objetivo_meta,
          }))}
          onChange={(e: any) => {
            const value = e?.target?.value || e?.value;
            const objetivo = objetivoMeta.find(
              (obj) => obj.id_objetivo_meta === value,
            );
            setSelectedObjetivoTipo(objetivo?.tipo_objetivo_meta || 0);
          }}
          required
          error="Preencha esse campo"
          defaultValue={
            defaultValues && defaultValues["objetivo_meta_politica"]
          }
        />

        <Input
          name="valorObjetivo_meta_politica"
          width="xl:w-1/2"
          formulario={form}
          label="Valor Objetivo da Meta"
          required
          error="Preencha esse campo"
          mascara={
            selectedObjetivoTipo == 0
              ? "numerico"
              : selectedObjetivoTipo == 1
                ? "monetario"
                : selectedObjetivoTipo == 2
                  ? "porcentagem"
                  : "letrasNumeros"
          }
          defaultValue={
            defaultValues && defaultValues["valorObjetivo_meta_politica"]
          }
        />
      </InputGroup>

      <InputGroup>
        <InputSelectComponent
          label="Nivel da meta"
          width="xl:w-1/2"
          name="nivel_meta_politica"
          formulario={form}
          options={nivelMeta.map((e) => ({
            label: e.nome_nivel_meta,
            value: e.id_nivel_meta,
          }))}
          onChange={(e: any) => {
            const value = e?.target?.value || e?.value;
            handleNivelChange(value);
          }}
          required
          error="Preencha esse campo"
          defaultValue={defaultValues && defaultValues["nivel_meta_politica"]}
        />
        {nivelSelecionado == 1 && (
          <InputSelectComponent
            label={`Selecione as Lojas (${lojasSelecionadas.length})`}
            name="lojas_meta_politica"
            width="xl:w-1/2"
            formulario={form}
            isMulti
            options={[
              { value: String("*"), label: "Todos" },
              ...lojas.map((e) => ({
                label: e.nome_loja,
                value: e.id_loja,
              })),
            ]}
            onChange={(selectedOptions: any) => {
              const hasAllSelected = selectedOptions.some(
                (option: any) => option.value == "*",
              );

              form.setValue(
                "lojas_meta_politica" as never,
                (
                  hasAllSelected
                    ? [{ label: "Todas", value: "*" }]
                    : selectedOptions
                ) as never,
              );
            }}
            required
            error="Preencha esse campo"
            defaultValue={defaultValues?.["lojas_meta_politica"]}
          />
        )}

        {nivelSelecionado == 2 && (
          <InputSelectComponent
            label={`Selecione os Tipos de Negócio (${tiposNegocioSelecionados.length})`}
            name="tiposNegocio_meta_politica"
            width="xl:w-1/2"
            formulario={form}
            isMulti
            options={[
              { value: String("*"), label: "Todos" },
              ...tiposNegocio.map((e) => ({
                label: e.nome_tipo_negocio,
                value: e.id_tipo_negocio,
              })),
            ]}
            onChange={(selectedOptions: any) => {
              const hasAllSelected = selectedOptions.some(
                (option: any) => option.value == "*",
              );

              form.setValue(
                "tiposNegocio_meta_politica" as never,
                (
                  hasAllSelected
                    ? [{ label: "Todos", value: "*" }]
                    : selectedOptions
                ) as never,
              );
            }}
            required
            error="Preencha esse campo"
            defaultValue={defaultValues?.["tiposNegocio_meta_politica"]}
          />
        )}

        {nivelSelecionado == 3 && (
          <InputSelectComponent
            label={`Selecione os Perfis (${perfisSelecionados.length})`}
            name="perfis_meta_politica"
            width="xl:w-1/2"
            formulario={form}
            isMulti
            options={[
              { value: String("*"), label: "Todos" },
              ...perfils.map((e) => ({
                label: e.nome_perfil,
                value: e.id_perfil,
              })),
            ]}
            onChange={(selectedOptions: any) => {
              const hasAllSelected = selectedOptions.some(
                (option: any) => option.value == "*",
              );

              form.setValue(
                "perfis_meta_politica" as never,
                (
                  hasAllSelected
                    ? [{ label: "Todos", value: "*" }]
                    : selectedOptions
                ) as never,
              );
            }}
            required
            error="Preencha esse campo"
            defaultValue={defaultValues?.["perfis_meta_politica"]}
          />
        )}

        {nivelSelecionado == 4 && (
          <InputSelectComponent
            label={`Selecione os Usuários (${usuariosSelecionados.length})`}
            name="usuarios_meta_politica"
            isMulti
            width="xl:w-1/2"
            formulario={form}
            options={[
              { value: String("*"), label: "Todos" },
              ...usuarios.map((e) => ({
                label: e.nome_usuario,
                value: e.id_usuario,
              })),
            ]}
            onChange={(selectedOptions: any) => {
              const hasAllSelected = selectedOptions.some(
                (option: any) => option.value == "*",
              );

              form.setValue(
                "usuarios_meta_politica" as never,
                (
                  hasAllSelected
                    ? [{ label: "Todos", value: "*" }]
                    : selectedOptions
                ) as never,
              );
            }}
            required
            error="Preencha esse campo"
            defaultValue={defaultValues?.["usuarios_meta_politica"]}
          />
        )}
      </InputGroup>
      <InputGroup>
        <Input
          type="checkbox"
          checked={sugerirEdicao}
          label="Sugerir descrição"
          onChange={(e) => {
            setSugerirEdicao(!sugerirEdicao);
          }}
        />
      </InputGroup>
      <InputGroup>
        <Input
          label="Descrição"
          name="descricao_meta_politica"
          formulario={form}
          type="textarea"
          defaultValue={
            defaultValues && defaultValues["descricao_meta_politica"]
          }
          required
          error={"Preencha a Descrição"}
        />
      </InputGroup>
      <div className="mt-4 mb-4 text-center font-black text-lg">
        <p> Limites Percentuais de Atingimento (%) </p>
      </div>
      <InputGroup>
        <Input
          name="limiteCritico_meta_politica"
          formulario={form}
          label="Limite Crítico (%)"
          width="xl:w-1/2"
          required
          error="Preencha esse campo"
          mascara="numero"
          onChange={(e) => handleLimiteCriticoChange(e.target.value)}
          defaultValue={
            defaultValues && defaultValues["limiteCritico_meta_politica"]
          }
          max={100}
        />
        <Input
          name="limiteAceitavel_meta_politica"
          formulario={form}
          width="xl:w-1/2"
          label={"Limite Aceitável (%)"}
          required
          error="Preencha esse campo"
          mascara="numero"
          onChange={(e) => handleLimiteAceitavelChange(e.target.value)}
          defaultValue={
            defaultValues && defaultValues["limiteAceitavel_meta_politica"]
          }
          max={100}
        />
      </InputGroup>
      <div className="flex flex-col justify-center items-center">
        <Button loading={isLoading}>Confirmar</Button>
      </div>
    </form>
  );
};

export default FormEditarMeta;
