import Input from "@/components/Forms/Input";
import { FormatFields, GetForm } from "@/utils";
import { useEffect } from "react";
import * as yup from "yup";

function getMesAnoEsperado(dataBase: string, mesesAAdicionar: number) {
  if (!dataBase) return null;
  const baseDate = new Date(`${dataBase}T00:00:00`);
  const alvo = new Date(
    baseDate.getFullYear(),
    baseDate.getMonth() + mesesAAdicionar,
    1
  );
  return { ano: alvo.getFullYear(), mes: alvo.getMonth() };
}

function getRangeMesEsperado(dataBase: string, mesesAAdicionar: number) {
  const esperado = getMesAnoEsperado(dataBase, mesesAAdicionar);
  if (!esperado) return { min: undefined, max: undefined };
  const { ano, mes } = esperado;
  const ultimoDia = new Date(ano, mes + 1, 0).getDate();
  const pad = (n: number) => String(n).padStart(2, "0");
  return {
    min: `${ano}-${pad(mes + 1)}-01`,
    max: `${ano}-${pad(mes + 1)}-${pad(ultimoDia)}`,
  };
}

export default function InputParcelaPersonalizada({
  numParcela,
  parcela,
  // tipoCondicao,
  condicao,
  dataBase,
  dataParcelaAnterior,
  diasDisponiveisCondicao,
  avisarIntervaloDias,
  onChange,
  setHandleSubmits,
}: any) {
  const formParcela = GetForm();
  const watchParcela = formParcela.watch();
  const cleanValues = formParcela.cleanValues;

  const intervaloDiasEmExcesso = (() => {
    if (
      !avisarIntervaloDias ||
      !cleanValues.data_parcela_proposta ||
      !dataParcelaAnterior
    )
      return undefined;

    const diffDias = Math.round(
      (new Date(`${cleanValues.data_parcela_proposta}T00:00:00`).getTime() -
        new Date(`${dataParcelaAnterior}T00:00:00`).getTime()) /
        (1000 * 60 * 60 * 24)
    );

    return diffDias > 15 ? diffDias : undefined;
  })();

  useEffect(() => {
    onChange(numParcela, {
      data_parcela_proposta: cleanValues.data_parcela_proposta,
      valor_parcela_proposta: cleanValues.valor_parcela_proposta,
    });
  }, [cleanValues.data_parcela_proposta, cleanValues.valor_parcela_proposta]);

  // Registra o handleSubmit dessa parcela no pai, pra ele conseguir validar
  // todos os mini-forms (um GetForm por parcela) antes do submit final.
  useEffect(() => {
    setHandleSubmits?.((prev: any[]) => {
      const novosHandleSubmits = [...prev];
      novosHandleSubmits.splice(numParcela, 1, formParcela.handleSubmit);
      return novosHandleSubmits;
    });
  }, [formParcela.handleSubmit, numParcela]);

  // Permite que o pai (botões de preencher parcelas iguais / fechar dívida)
  // empurre um novo valor pro campo já montado.
  useEffect(() => {
    if (parcela.valor_parcela_proposta) {
      formParcela.setValue(
        "valor_parcela_proposta",
        FormatFields.formatarNumero(parcela.valor_parcela_proposta)
      );
    }
  }, [parcela.valor_parcela_proposta]);

  // Permite que o pai (seletor de "Dia do Vencimento") empurre uma nova data
  // pro campo já montado, sem precisar desmontar essa parcela.
  useEffect(() => {
    if (parcela.data_parcela_proposta) {
      formParcela.setValue(
        "data_parcela_proposta",
        parcela.data_parcela_proposta
      );
    }
  }, [parcela.data_parcela_proposta]);

  // const isMensal = tipoCondicao == "2";
  const { min, max } =
    // isMensal
    // ? getRangeMesEsperado(dataBase, numParcela + 1)
    // :
    { min: dataParcelaAnterior, max: undefined };

  const dataSchema = yup
    .string()
    .required("Informe a data")
    // .test("mes-correto", function (value) {
    //   if (
    //     // !isMensal ||
    //     !value ||
    //     !dataBase
    //   )
    //     return true;
    //   const esperado = getMesAnoEsperado(dataBase, numParcela + 1);
    //   if (!esperado) return true;
    //   const [ano, mes] = value.split("-").map(Number);
    //   if (ano == esperado.ano && mes == esperado.mes + 1) return true;
    //   const pad = (n: number) => String(n).padStart(2, "0");
    //   return this.createError({
    //     message: `Data deve ser um dia de ${pad(esperado.mes + 1)}/${esperado.ano}`,
    //   });
    // })
    .test("dia-liberado", function (value) {
      if (
        // !isMensal ||
        !value ||
        !diasDisponiveisCondicao?.length
      )
        return true;
      const dia = Number(value.split("-")[2]);
      if (diasDisponiveisCondicao.includes(dia)) return true;
      return this.createError({
        message: `Dia deve ser um dos liberados: ${diasDisponiveisCondicao.join(", ")}`,
      });
    })
    .test("data-sequencial", function (value) {
      if (!value || !dataParcelaAnterior) return true;
      // Comparação de string funciona pois a data está no formato ISO (YYYY-MM-DD).
      if (value >= dataParcelaAnterior) return true;
      return this.createError({
        message: `Data não pode ser anterior a ${FormatFields.formatarDataCalendar(
          new Date(dataParcelaAnterior.split("-") as any)
        )}`,
      });
    });

  return (
    <div className="flex flex-row items-center gap-3 flex-wrap">
      <div>{`Parcela ${numParcela + 1}`}</div>
      <Input
        // O schema de validação depende de tipoCondicao/diasDisponiveisCondicao,
        // mas Input só registra o schema na montagem — trocar a key força
        // remontar (e reregistrar) quando essas condições mudam sem desmontar
        // o InputParcelaPersonalizada em si.
        // key={`data_parcela_proposta-${tipoCondicao}-${diasDisponiveisCondicao?.join(",")}`}
        key={`data_parcela_proposta-${condicao}-${diasDisponiveisCondicao?.join(",")}-${dataParcelaAnterior}`}
        name="data_parcela_proposta"
        label="Data"
        formulario={formParcela}
        type="date"
        required
        error="Informe a data"
        width={"w-fit"}
        min={min}
        max={max}
        schema={dataSchema}
        defaultValue={parcela.data_parcela_proposta}
      />
      <Input
        name="valor_parcela_proposta"
        label="Valor"
        formulario={formParcela}
        mascara="numero"
        prefix={"R$"}
        required
        error="Informe o valor"
        width={"w-fit"}
        defaultValue={parcela.valor_parcela_proposta}
      />
      {intervaloDiasEmExcesso !== undefined && (
        <span className="text-xs text-orange-500">
          Atenção: {intervaloDiasEmExcesso} dias desde a data anterior (mais de
          15 dias)
        </span>
      )}
    </div>
  );
}
