import { obterKitPorBudget_id } from "@/requests/CRM/APIHelte/obterKitPorBudget_id";
import { deletarContrato } from "@/requests/CRM/Contrato/deletarContrato";
import { listarUltimoIdContrato } from "@/requests/CRM/Contrato/listarUltimoIdContrato";
import { obterTemplateContrato } from "@/requests/CRM/Contrato/obterTemplateContrato";
import { listarUcsColeta } from "@/requests/CRM/UCs/listarUcsColeta";
import { listarComponentesKitByKitId } from "@/requests/CRUD/ColetaDados/cadastroColetaDados";
import { useAuth } from "@/src/contexts/authContext";
import {
  calcularAnosEMeses,
  capitalizeMonth,
  formatarValor,
  FormatFields,
  getDateBrasil,
  getDateTimeBrasil,
} from "@/utils";
import {
  carregarDadosExpansaoItensCompostos,
  formatarComponentesTabelaKitExpandido,
} from "@/utils/formatarComponentesTabelaKit";
import { resolverProfissaoContratante } from "@/utils/resolverProfissaoContratante";
import extenso from "extenso";
import Image from "next/image";
import { FaFileUpload } from "react-icons/fa";
import { toast } from "react-toastify";

import LoaderBar from "@/components/Loader/loaderBar";
import { useGoogleAuth } from "@/hooks/useGoogleAuth";
import {
  salvarAwsContratoLink,
  salvarContrato,
} from "@/requests/CRM/Contrato/salvarContrato";
import { salvarPdfContrato } from "@/requests/CRM/Contrato/salvarPdfContrato";
import { obterFinanciadorNegocio } from "@/requests/CRUD/Cliente/obterFinanciadorNegocio";
import { addConclusaoPendencia } from "@/requests/CRUD/ConclusaoPendencia/conclusaoPendencia";
import { listarParametros } from "@/requests/CRUD/ParametrosComerciais/listarParametros";
import { deleteDoc } from "@/requests/deleteDoc";
import { generatePdf } from "@/requests/generatePdf";
import { useContractContext } from "@/src/contexts/ContractProvider";
import { useLoja } from "@/src/contexts/lojaContext";
import { useScreenContext } from "@/src/contexts/ScreenContext";
import LoaderGif from "../../../../public/images/loaders/loader2.gif";

let contratoIdTemporario = 0;
let contratoSalvo = false;

import { handleSweetAlert } from "@/components/Modal/SweetAlertConfirm";
import PDFViewer from "@/components/PdfViewer/PDFViewer";
import { useCamposPersonalizados } from "@/hooks/useCamposPersonalizados";
import { obterDistribuicaoModulos } from "@/requests/CRUD/Propostas/obterDistribuicaoModulos";
import { listarTiposEdificacao } from "@/requests/CRUD/TiposEdificacao/listarTiposEdificacao";
import { listarTiposTelhados } from "@/requests/CRUD/TiposTelhados/listarTiposTelhados";
import { listarUsuarioPeloId } from "@/requests/CRUD/Usuario/listarUsuarios";
import { formatLabelTipoEdificacao } from "@/utils/formatTipoEdificacao";
import { Info } from "lucide-react";
import { useEffect, useState } from "react";
import { IOrigemDadosDefaultContrato } from "@/utils/origemDadosDefaultContrato";

const GeracaoContrato = ({
  dadosCard,
  dataGeracaoContrato,
  dataContratoSistema,
  dadosCliente,
  proposta,
  lojas,
  ucsColeta: ucsBD,
  coletaContratos,
  reloadContratos,
  camposPersonalizados,
  setIsLoading,
  setActiveStepAtual,
  activeStep,
  usuario,
  setModalCondPagamento,
  setOpenModalContrato,
  regerarContrato = false,
  contratoExistente = null,
  origemDadosDefaultContrato,
}: any) => {
  const { filterCamposPersonalizados } = useCamposPersonalizados(
    dadosCard?.id_coleta_cliente,
    dadosCard?.id_card
  );
  const [isLoaded, setIsLoaded] = useState(false);
  const [isSavingContrato, setIsSavingContrato] = useState(false);
  const { isMobile } = useScreenContext();
  const [pdf, setPdf] = useState<any>();
  const [pdfBlob, setPdfBlob] = useState<any>();
  const { lojaAtual: dadosLoja } = useLoja();
  const [loaderStep, setLoaderStep] = useState(0);
  const [hasError, setHasError] = useState(false);
  const { connected, profile, isStatusVerifyed } = useGoogleAuth(
    dadosCard?.id_loja_coleta
  );
  const [parametros, setParametros] = useState<any>(null);
  const [contratoId, setContratoId] = useState<number | null>(null);
  const [previewContratoId, setPreviewContratoId] = useState<number | null>(
    null
  );
  const [telhadoProposta, setTelhadoProposta] = useState<string>("");
  const [orientacoes, setOrientacoes] = useState<any>({});

  const steps = [
    "Salvando contrato...",
    "Relacionando dados...",
    "Comprimindo imagens...",
    "Gerando PDF...",
    "Finalizando...",
  ];
  let camposPersonalizadosSearch: any = null;

  let camposPersonalizadosFormat: any = null;

  if (camposPersonalizados) {
    camposPersonalizadosSearch = Object.fromEntries(
      Object.entries(camposPersonalizados).filter(
        ([key, value]) =>
          (key.endsWith("_campo_personalizado") || key.endsWith("_cp")) &&
          ((typeof value === "string" && value.trim() !== "") ||
            (Array.isArray(value) &&
              value.every((v) => typeof v === "string" && v.trim() !== "")))
      )
    );

    // Passo 2: Formatando as chaves para pegar apenas a parte depois do `^`
    camposPersonalizadosFormat = Object.fromEntries(
      Object.entries(camposPersonalizadosSearch).map(([key, value]) => [
        key.split("^")[1],
        value,
      ])
    );
  }

  const { valuesSession } = useAuth();
  const { session } = valuesSession();
  // const { reListarDadosKanban } = useKanbanContext();

  const { relacionamentosContrato } = useContractContext();

  useEffect(() => {
    // if (!connected) return;
    if (isStatusVerifyed) {
      if (!connected) {
        handleSweetAlert({
          icon: "error",
          title: `Não foi possível conectar-se a conta google`,
          html: `<span>Não foi possível conectar-se a conta google para a geração do documento</span>`,
          showDenyButton: false,
          confirmButtonText: "Ok",
        });
        setModalCondPagamento(true);
        setOpenModalContrato(false);
        return;
      }
      Promise.all([
        listarParametros(),
        obterDistribuicaoModulos(proposta.id_proposta),
      ]).then(([parametrosRes, orientacoesRes]) => {
        setParametros(parametrosRes);
        const orientacoesFormatadas = {
          orientacoes_proposta: orientacoesRes
            .map((dadosDistribuicao: any) => dadosDistribuicao.nome_orientacao)
            .join(", "),
        };
        setOrientacoes(orientacoesFormatadas);

        // Evita race condition: passa os parâmetros diretamente
        gerarContrato(parametrosRes, orientacoesFormatadas);
      });
    }
  }, [connected]);

  const formatarNumero = FormatFields.formatarNumero;
  async function getKitBudget() {
    return obterKitPorBudget_id(proposta.kit_proposta).then((res) => {
      proposta.potenciaSistema_proposta = res.potency;
      return res.products.map((componente: any) => ({
        name: componente.name,
        category: componente.category.name,
        qtd: componente.qtd,
      }));
    });
  }
  async function getListComponent() {
    return listarComponentesKitByKitId(proposta.kit_proposta).then((res: any) =>
      res.componentesKit
        .filter((componente: any) => componente.descricao)
        .map((componente: any) => {
          console.log("res", componente);
          const elementos = [1, 2, 3, 4];
          return {
            ...componente,
            name: componente.descricao,
            category: componente.categoria,
            qtd:
              componente.nome == "Módulos"
                ? elementos.reduce(
                    (accumulator, currentValue) =>
                      accumulator +
                      +proposta[`qtdModulos${currentValue}_proposta`],
                    0
                  )
                : componente.qtd,
          };
        })
    );
  }
  const gerarContrato = async (
    parametrosLocal?: any,
    orientacoesLocal?: any
  ) => {
    try {
      console.time("GerarContrato-total");

      const data = {
        id_tipo_negocio: dadosCard.tipoNegocio_coleta,
        id_loja: dadosCard.id_loja_coleta,
      };

      const documentId = await obterTemplateContrato(data).then(
        (res) => res.documentId_templateContrato_loja
      );

      // Em regeneração, mantém o ID existente. Em criação, usa ID temporário para preview.
      if (regerarContrato && contratoExistente?.id_contrato) {
        contratoIdTemporario = Number(contratoExistente.id_contrato);
        contratoSalvo = true;
        setPreviewContratoId(contratoIdTemporario);
      } else {
        const ultimoIdContrato = Number(await listarUltimoIdContrato());
        contratoIdTemporario = ultimoIdContrato + 1;
        contratoSalvo = false;
        setPreviewContratoId(contratoIdTemporario);
      }

      // Busca o nome do telhado
      const telhadoNome = await listarTiposTelhados().then((res) => {
        const tipoTelhado = res.find(
          (tipo: any) => tipo.id_telhado == proposta.telhado_proposta
        );
        return tipoTelhado?.nome_telhado || "Não informado";
      });

      // Busca o nome do tipo de edificação
      const tipoEdificacaoNome = await listarTiposEdificacao().then((res) => {
        const tipoEdificacao = res.find(
          (tipo: any) =>
            tipo.id_tipo_edificacao == dadosCard.tipo_edificacao_coleta
        );
        return tipoEdificacao
          ? formatLabelTipoEdificacao(tipoEdificacao)
          : "Não informado";
      });

      const componentes = await (
        proposta.api_kit_proposta == "1" ? getKitBudget() : getListComponent()
      ).catch((err) => {
        console.error(err);
        return [];
      });

      let localizacao = dadosCard.endereco_instalacao_coleta;
      // if (dadosCard.latitude && dadosCard.longitude) {
      //   const googleMapsApiKey = "AIzaSyDGmjm0xgXvIWV8ZO6tCvTDiN3-AvGzmVc";
      //   localizacao = await axios
      //     .get(
      //       `https://maps.googleapis.com/maps/api/geocode/json?latlng=${dadosCard.latitude},${dadosCard.longitude}&key=${googleMapsApiKey}`
      //     )
      //     .then((res) => {
      //       return res.data.results[0].formatted_address;
      //     });
      // }
      const ucTable = await listarUcsColeta(dadosCard.id_coleta_cliente).then(
        (res) => {
          let ucsColeta: any = [];
          const ucsBeneficiarias = res.filter((uc: any) => {
            if (uc.isGeradora_uc_coleta != "0") {
              ucsColeta.push(uc);
            }
            return uc.isGeradora_uc_coleta == "0";
          });

          if (ucsColeta[0] == undefined) {
            ucsColeta.push({
              id_uc_coleta: "",
              codColeta_uc_coleta: dadosCard.id_coleta_cliente,
              isGeradora_uc_coleta: 1,
              numero_uc_coleta: dadosCard.uc_coleta,
              valor: 0,
            });
          }

          ucsColeta = [...ucsColeta, ...ucsBeneficiarias];

          const ucsForm = ucsColeta.map((uc: any, index: number) => {
            const valor =
              +uc.valor == +uc.valor
                ? +uc.valor
                : uc.valor.reduce(
                    (acc: number, curr: string) => acc + +curr,
                    0
                  ) /
                  uc.valor.filter((val: number | string) => val !== "").length;
            return {
              id_uc_coleta: uc.id_uc_coleta,
              uc: !uc.numero_uc_coleta ? "" : uc.numero_uc_coleta,
              nome:
                uc.isGeradora_uc_coleta == "1"
                  ? "UG " + (!uc.numero_uc_coleta ? "" : uc.numero_uc_coleta)
                  : "UB " + (!uc.numero_uc_coleta ? "" : uc.numero_uc_coleta),
              key: index,
              tipo:
                uc.isGeradora_uc_coleta == "1" ? "Geradora" : "Beneficiária",
              tipoValor: +uc.valor == +uc.valor ? "Média" : "Mensal",
              concessionaria: dadosCard.nome_concessionaria,
              valor: formatarNumero(valor) + "kWh",
              conta: formatarValor(
                valor * +proposta.precoDigitadoTarifa_proposta
              ),
            };
          });
          return ucsForm;
        }
      );
      // const dadosLoja: any = await listarLojas().then((res: any) =>
      //   res.find((loja: any) => loja.id_loja == dadosCard.id_loja_coleta)
      // );

      const financiador = await obterFinanciadorNegocio({
        id_coleta: dadosCard.id_coleta_cliente,
      });

      const lojaAtual = lojas.find(
        (loja: any) => loja.id_loja == dadosCard.id_loja_coleta
      );

      const potencia_kit = Number(proposta.potenciaSistema_proposta);

      const tagsProfissao = resolverProfissaoContratante(
        dadosCliente,
        financiador
      );

      const clienteOuFinanciador = financiador
        ? {
            ...dadosCliente,
            ...financiador,
            ...tagsProfissao,
            tipoPessoa_cliente: financiador.tipoPessoa_financiador,
            nome_cliente: financiador.nome_financiador,
            cpfcnpj_cliente: financiador.cpfcnpj_financiador,
            // id_coleta_cliente: "",
            nro_cliente: financiador.nro_financiador,
            cidade_cliente: financiador.cidade_financiador,
            estado_cliente: financiador.estado_financiador,
            cep_cliente: financiador.cep_financiador,
            rua_cliente: financiador.rua_financiador,
            bairro_cliente: financiador.bairro_financiador,
            comp_cliente: financiador.comp_financiador,
            nomeEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.nomeEmpresa_financiador
                : "Pessoa Física",
            logradouroEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.logradouroEmpresa_financiador
                : " ",
            complementoEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.complementoEmpresa_financiador
                : " ",
            bairroEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.bairroEmpresa_financiador
                : " ",
            cepEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.cepEmpresa_financiador
                : " ",
            cidadeEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.cidadeEmpresa_financiador
                : " ",
            ufEmpresa_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.ufEmpresa_financiador
                : " ",
            nomeResponsavelFisico_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.nomeResponsavelFisico_financiador
                : financiador.nome_financiador,
            cpfResponsavel_cliente:
              financiador.tipoPessoa_financiador == "J"
                ? financiador.cpfResponsavel_financiador
                : financiador.cpfcnpj_financiador,
            dataNascimento_cliente: getDateBrasil(
              undefined,
              financiador.dataNascimento_financiador
            ),
          }
        : {
            ...dadosCliente,
            ...tagsProfissao,
            dataNascimento_cliente: getDateBrasil(
              undefined,
              dadosCliente.dataNascimento_cliente
            ),
            tipoPessoa_cliente: dadosCliente.tipoPessoa_cliente,
            nomeEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.nomeEmpresa_cliente
                : "Pessoa Física",
            logradouroEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.logradouroEmpresa_cliente
                : " ",
            complementoEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.complementoEmpresa_cliente
                : " ",
            bairroEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.bairroEmpresa_cliente
                : " ",
            cepEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.cepEmpresa_cliente
                : " ",
            cidadeEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.cidadeEmpresa_cliente
                : " ",
            ufEmpresa_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.ufEmpresa_cliente
                : " ",
            nomeResponsavelFisico_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.nomeResponsavelFisico_cliente
                : dadosCliente.nome_cliente,
            cpfResponsavel_cliente:
              dadosCliente.tipoPessoa_cliente == "J"
                ? dadosCliente.cpfResponsavel_cliente
                : dadosCliente.cpfcnpj_cliente,
          };

      const formatarMensagem = (dados: any) => {
        const isPessoaFisica =
          dados.tipoPessoa_cliente === "F" ||
          dados.tipoPessoa_cliente === "f" ||
          dados.tipoPessoa_cliente === "CPF";

        const tipoCliente =
          dados.tipo_cliente || (isPessoaFisica ? "física" : "jurídica");
        const nacionalidade = dados.nacionalidade_cliente || "brasileiro(a)";
        const profissao = dados.profissao_cliente || "";

        if (isPessoaFisica) {
          const rgNumero = dados.cliente_rg || "";
          const rgExpedidor = dados.cliente_rg_expedidor || "";
          const rgTexto = rgNumero
            ? ` e RG nº: ${rgNumero}${rgExpedidor ? ` - ${rgExpedidor}` : ""}`
            : "";

          // Construir array com partes não-vazias
          const partes = [
            `${dados.nome_cliente}, pessoa: ${tipoCliente}`,
            nacionalidade,
            profissao,
          ].filter(Boolean);

          const primeiraParteTexto = partes.join(", ");

          return `${primeiraParteTexto}, inscrito(a) no CPF nº: ${dados.cliente_cpf}${rgTexto}, residente e domiciliado(a) no CEP: ${dados.cep_moradia_cliente}, Endereço: ${dados.rua_moradia_cliente}, nº: ${dados.numero_moradia_cliente}${dados.complemento_moradia_cliente ? `, ${dados.complemento_moradia_cliente}` : ""}, Bairro: ${dados.bairro_moradia_cliente}, Cidade: ${dados.cidade_moradia_cliente}, UF: ${dados.estado_moradia_cliente}.`;
        }

        const ieTexto = dados.cliente_ie
          ? ` e Inscrição Estadual: ${dados.cliente_ie}`
          : "";

        const responsavelNome =
          dados.nome_responsavel_empresa_cliente ||
          dados.nomeResponsavelFisico_cliente ||
          "Responsável não informado";

        const responsavelCpf =
          dados.cpf_responsavel_empresa_cliente ||
          dados.cpfResponsavel_cliente ||
          "CPF não informado";

        return `${dados.razao_social_cliente}, pessoa: ${tipoCliente}, inscrito(a) no CNPJ nº ${dados.cliente_cnpj}${ieTexto}, com sede no CEP: ${dados.cep_empresa_cliente || dados.cep_moradia_cliente}, Endereço: ${dados.rua_empresa_cliente || dados.rua_moradia_cliente}, nº ${dados.numero_empresa_cliente || dados.numero_moradia_cliente}${dados.complemento_empresa_cliente ? `, ${dados.complemento_empresa_cliente}` : ""}, Bairro: ${dados.bairro_empresa_cliente || dados.bairro_moradia_cliente}, Cidade: ${dados.cidade_empresa_cliente || dados.cidade_moradia_cliente}, UF: ${dados.estado_empresa_cliente || dados.estado_moradia_cliente}, neste ato representado(a) pelo(a) Sr(a). ${responsavelNome}, CPF: ${responsavelCpf}.`;
      };

      let instalador: any = {};
      let tecnico: any = {};
      if (!!dadosCard?.responsaveis?.["Instalador"]) {
        await listarUsuarioPeloId(dadosCard?.responsaveis?.["Instalador"]).then(
          (usuarioInstalador) => {
            instalador = usuarioInstalador;
          }
        );
      }
      if (!!dadosCard?.responsaveis?.["Técnico"]) {
        await listarUsuarioPeloId(dadosCard?.responsaveis?.["Técnico"]).then(
          (usuarioTecnico) => {
            tecnico = usuarioTecnico;
          }
        );
      }

      // Aplicar lógica do "incluso" aos componentes
      const tabelaProdutosParametro =
        parametrosLocal?.tabela_produtos_parametro ??
        parametros?.tabela_produtos_parametro;

      const hasPermissionToSeeValues =
        usuario?.visualiza_custo_kit_usuario == "1";
      let componentesFormatados = componentes;
      if (componentes && componentes.length > 0) {
        componentesFormatados = componentes
          .map((componente: any) => {
            // 8 = inversor, 9 = módulo, 16 = bateria
            const isModuloOuInversor =
              componente.tipo_item == "9" ||
              componente.tipo_item == "8" ||
              componente.tipo_item == "16" ||
              componente.category == "Baterias" ||
              componente.category == "Inversores" ||
              componente.category == "Modulos";

            const qtdReal = componente.qtd || componente.qtd_item;

            // Regra: se 'qtd_real' usar quantidade real para todos;
            // se 'incluso', mostrar INCLUSO exceto para Módulos e Inversores.
            const qtd_item =
              tabelaProdutosParametro === "incluso" && !isModuloOuInversor
                ? "INCLUSO"
                : qtdReal;

            return {
              ...componente,
              name: componente.descricao || componente.name,
              unid_item: "UN",
              vlr_unit_item: hasPermissionToSeeValues
                ? formatarValor(componente.precoUnitario_item)
                : "Restrito",
              vlr_total_item: hasPermissionToSeeValues
                ? formatarValor(
                    componente.precoUnitario_item * componente.qtd_item
                  )
                : "Restrito",
              category: componente.categoria || componente.category,
              qtd_item: qtd_item || componente.qtd,
              _isModuloOuInversor: isModuloOuInversor, // Flag para sorting
            };
          })
          .sort((a: any, b: any) => {
            // Módulos, Inversores e Baterias primeiro
            if (a._isModuloOuInversor && !b._isModuloOuInversor) return -1;
            if (!a._isModuloOuInversor && b._isModuloOuInversor) return 1;
            return 0;
          })
          .map((componente: any) => {
            // Remover flag após sorting
            const { _isModuloOuInversor, ...resto } = componente;
            return resto;
          });
      }
      const { catalogoItens, itensCompCatalog } =
        await carregarDadosExpansaoItensCompostos();
      const componentesExpandidos = formatarComponentesTabelaKitExpandido(
        componentes,
        catalogoItens,
        itensCompCatalog,
        {
          tabelaProdutosParametro,
          hasPermissionToSeeValues,
        }
      );
      const inversores_proposta = componentes.filter(
        (componente: any) => componente?.tipo_item == "8"
      );

      const obterGarantiaComponente = (
        matchFn: (componente: any) => boolean
      ) => {
        const componente = componentes?.find((item: any) => matchFn(item));
        const valorGarantia = componente?.garantia_item ?? componente?.garantia;

        if (
          valorGarantia === undefined ||
          valorGarantia === null ||
          valorGarantia === ""
        ) {
          return undefined;
        }

        const garantiaNumero = Number(String(valorGarantia).replace(",", "."));
        if (garantiaNumero === 0) {
          return undefined;
        }
        return Number.isNaN(garantiaNumero) ? undefined : garantiaNumero;
      };

      const garantiaModulo = obterGarantiaComponente(
        (item) => String(item?.tipo_item) === "9"
      );
      const garantiaInversor = obterGarantiaComponente(
        (item) => String(item?.tipo_item) === "8"
      );
      const garantiaEstrutura = obterGarantiaComponente((item) => {
        const categoria = String(
          item?.categoria || item?.category || ""
        ).toLowerCase();
        return (
          categoria.includes("estrutura") || String(item?.tipo_item) === "7"
        );
      });
      const garantiaBateria = obterGarantiaComponente((item) => {
        const categoria = String(
          item?.categoria || item?.category || ""
        ).toLowerCase();
        return (
          categoria.includes("bateria") || String(item?.tipo_item) === "16"
        );
      });

      const [qtd_min_modulos, qtd_max_modulos] = inversores_proposta.reduce(
        (acc: [number, number], inversor: any) => {
          const potenciaInversorW = parseFloat(inversor.potencia_item) * 1000; // Converte kW para W
          const underload = +inversor.underload_item / 100; // 70% -> 0.7
          const overload = +inversor.overload_item / 100; // 150% -> 1.5
          const potenciaModulo = +proposta?.potencia_modulo_proposta;
          const qtdItem = parseInt(inversor.qtd_item) || 1;

          let minModulos =
            (potenciaInversorW * qtdItem * underload) / potenciaModulo;
          minModulos = Math.floor(minModulos);

          let maxModulos =
            (potenciaInversorW * qtdItem * overload) / potenciaModulo;

          if (inversor.tipoInversor_item == "micro_inversor") {
            maxModulos = Math.floor(
              (potenciaInversorW * overload) / potenciaModulo
            );

            maxModulos =
              maxModulos > +inversor.qtdModulos_max_item
                ? +inversor.qtdModulos_max_item
                : maxModulos;

            maxModulos = maxModulos * qtdItem;
          }

          maxModulos = Math.floor(maxModulos);

          return [acc[0] + minModulos, acc[1] + maxModulos];
        },
        [0, 0]
      );

      const qtd_expansivel_modulos = String(
        qtd_max_modulos - +proposta?.modulosDigitado_proposta
      );

      const [anoGeracao, mesGeracao, diaGeracao] = String(
        dataGeracaoContrato || ""
      )
        .split(" ")[0]
        .split("-")
        .map((v: string) => Number(v));

      const dataGeracaoBase =
        anoGeracao && mesGeracao && diaGeracao
          ? new Date(anoGeracao, mesGeracao - 1, diaGeracao)
          : new Date();

      const diaNumeroGeracao = String(dataGeracaoBase.getDate()).padStart(
        2,
        "0"
      );
      const mesExtensoGeracao = capitalizeMonth(
        dataGeracaoBase.toLocaleDateString("pt-BR", { month: "long" })
      );
      const anoNumeroGeracao = String(dataGeracaoBase.getFullYear());

      const dadosParaRelacionar = {
        // ...dadosCliente,
        ...proposta,
        ...dadosCard,
        ...clienteOuFinanciador,
        ...camposPersonalizadosFormat,
        ...tagsProfissao,
        data_geracao_contrato: dataGeracaoContrato,
        data_contrato: capitalizeMonth(
          getDateTimeBrasil(
            {
              day: "2-digit",
              month: "long",
              year: "numeric",
            },
            dataContratoSistema || undefined
          )
        ),
        telhado_proposta: telhadoNome,
        tipo_edificacao_coleta: tipoEdificacaoNome,
        orientacoes_proposta:
          orientacoesLocal?.orientacoes_proposta ||
          orientacoes.orientacoes_proposta ||
          "N/A",
        valorTotal_proposta: formatarValor(proposta.valorTotal_proposta),
        valor_extenso_proposta: extenso(+proposta.valorTotal_proposta, {
          mode: "currency",
        }),
        preco_kit: formatarValor(proposta.preco_kit),
        preco_extenso_kit: extenso(+proposta.preco_kit, { mode: "currency" }),
        valor_sem_kit: formatarValor(
          +proposta.valorTotal_proposta - +proposta.preco_kit
        ),
        valor_extenso_sem_kit: extenso(
          +proposta.valorTotal_proposta - +proposta.preco_kit,
          { mode: "currency" }
        ),
        informacoes_pagamento:
          proposta.informacoes_pagamento_proposta || "Sem condições definidas",
        // componentes_tabela_kit_val: componentesFormatados,
        instalador_nome_empresa_terceirizada:
          instalador?.nome_empresa_terceirizada || "Sem designação",
        instalador_cnpj_empresa_terceirizada:
          instalador?.cnpj_empresa_terceirizada || "Sem designação",
        instalador_rua_empresa_terceirizada:
          instalador?.rua_empresa_terceirizada || "Sem designação",
        instalador_numero_empresa_terceirizada:
          instalador?.numero_empresa_terceirizada || "Sem designação",
        instalador_bairro_empresa_terceirizada:
          instalador?.bairro_empresa_terceirizada || "Sem designação",
        instalador_cidade_empresa_terceirizada:
          instalador?.cidade_empresa_terceirizada || "Sem designação",
        instalador_estado_empresa_terceirizada:
          instalador?.estado_empresa_terceirizada || "Sem designação",
        instalador_cep_empresa_terceirizada:
          instalador?.cep_empresa_terceirizada || "Sem designação",
        valor_total_pagamento: formatarValor(proposta.valorTotal_proposta),
        valorKwp_proposta: formatarValor(
          +proposta.valorTotal_proposta / potencia_kit
        ),
        cep_moradia_cliente: clienteOuFinanciador.cep_cliente,
        rua_moradia_cliente: clienteOuFinanciador.rua_cliente,
        numero_moradia_cliente: clienteOuFinanciador.nro_cliente,
        complemento_moradia_cliente: clienteOuFinanciador.comp_cliente,
        bairro_moradia_cliente: clienteOuFinanciador.bairro_cliente,
        cidade_moradia_cliente: clienteOuFinanciador.cidade_cliente,
        estado_moradia_cliente: clienteOuFinanciador.estado_cliente,
        razao_social_cliente: clienteOuFinanciador.nomeEmpresa_cliente,
        qtd_expansivel_modulos: qtd_expansivel_modulos,
        max_modulos: qtd_max_modulos,
        numero_negocio: dadosCard.id_coleta_cliente,
        garantia_modulos: calcularAnosEMeses(
          garantiaModulo ??
            +(
              parametrosLocal?.garantia_modulos_parametro ??
              parametros?.garantia_modulos_parametro
            )
        ),
        garantia_inversores: calcularAnosEMeses(
          garantiaInversor ??
            +(
              parametrosLocal?.garantia_inversores_parametro ??
              parametros?.garantia_inversores_parametro
            )
        ),
        garantia_servicos: calcularAnosEMeses(
          +(
            parametrosLocal?.garantia_servicos_parametro ??
            parametros?.garantia_servicos_parametro
          )
        ),
        garantia_estruturas: calcularAnosEMeses(
          garantiaEstrutura ??
            +(
              parametrosLocal?.garantia_estruturas_parametro ??
              parametros?.garantia_estruturas_parametro
            )
        ),
        garantia_baterias: calcularAnosEMeses(
          garantiaBateria ??
            +(
              parametrosLocal?.garantia_baterias_parametro ??
              parametros?.garantia_baterias_parametro
            )
        ),
        dias_prazo_entrega:
          parametrosLocal.tabelaPrazos.find(
            (prazo: any) =>
              +prazo.potencia_inicial_prazo <= potencia_kit &&
              +prazo.potencia_final_prazo >= potencia_kit
          )?.dias_prazo || "0",
        observacoes: proposta.obs_proposta || "N/A",
        observacao_pagamento: proposta.observacao_pagamento_proposta || "N/A",
        nome_resp_tecnico: tecnico?.nome_usuario || "Sem designação",
        endereco_loja: `${lojaAtual.endereco_loja}, ${lojaAtual.numero_loja}, ${lojaAtual.complemento_loja}, Bairro ${lojaAtual.bairro_loja}`,
        cep_loja: `${lojaAtual.cep_loja}`,
        cidade_loja: `${lojaAtual.cidade_loja}`,
        estado_loja: `${lojaAtual.estado_loja}`,
        proprietario_loja: `${lojaAtual.proprietario_loja}`,
        razao_social_loja: `${lojaAtual.razaosocial_loja}`,
        bairro_loja: `${lojaAtual.bairro_loja}`,
        numero_loja: `${lojaAtual.numero_loja}`,
        nome_loja: `${lojaAtual.razaosocial_loja}`,
        rua_loja: `${lojaAtual.endereco_loja}`,
        telefone_loja: `${lojaAtual.telefone_loja}`,
        complemento_loja: `${lojaAtual.complemento_loja}`,
        nomeRepresentanteLegal_loja: `${lojaAtual.nomeRepresentanteLegal_loja}`,
        cpfRepresentanteLegal_loja: `${lojaAtual.cpfRepresentanteLegal_loja}`,
        tipoPessoa_cliente: `${clienteOuFinanciador?.tipoPessoa_cliente == "F" ? "CPF" : "CNPJ"}`,
        email_loja: `${lojaAtual.email_loja}`,
        mensagem_contratante: formatarMensagem({
          tipoPessoa_cliente: clienteOuFinanciador.tipoPessoa_cliente,
          tipo_cliente:
            clienteOuFinanciador.tipoPessoa_cliente === "F"
              ? "física"
              : "jurídica",
          nacionalidade_cliente:
            clienteOuFinanciador.nacionalidade_cliente || "brasileiro(a)",
          profissao_cliente: clienteOuFinanciador.profissao_cliente,
          cliente_rg: clienteOuFinanciador.rg_cliente,
          cliente_rg_expedidor:
            clienteOuFinanciador.rg_expedidor_cliente ||
            clienteOuFinanciador.orgaoExpedidor_cliente,
          cliente_ie: clienteOuFinanciador.ie_cliente,
          nome_cliente: clienteOuFinanciador.nome_cliente,
          cliente_cpf: clienteOuFinanciador.cpfcnpj_cliente,
          rua_moradia_cliente: clienteOuFinanciador.rua_cliente,
          bairro_moradia_cliente: clienteOuFinanciador.bairro_cliente,
          numero_moradia_cliente: clienteOuFinanciador.nro_cliente,
          cidade_moradia_cliente: clienteOuFinanciador.cidade_cliente,
          complemento_moradia_cliente: clienteOuFinanciador.comp_cliente,
          estado_moradia_cliente: clienteOuFinanciador.estado_cliente,
          cep_moradia_cliente: clienteOuFinanciador.cep_cliente,
          razao_social_cliente: clienteOuFinanciador.nomeEmpresa_cliente,
          cliente_cnpj: clienteOuFinanciador.cpfcnpj_cliente,
          rua_empresa_cliente: clienteOuFinanciador.logradouroEmpresa_cliente,
          numero_empresa_cliente:
            clienteOuFinanciador.numeroEmpresa_cliente ?? "",
          complemento_empresa_cliente:
            clienteOuFinanciador.complementoEmpresa_cliente ?? "",
          bairro_empresa_cliente: clienteOuFinanciador.bairroEmpresa_cliente,
          cep_empresa_cliente: clienteOuFinanciador.cepEmpresa_cliente,
          cidade_empresa_cliente: clienteOuFinanciador.cidadeEmpresa_cliente,
          estado_empresa_cliente: clienteOuFinanciador.ufEmpresa_cliente,
          nome_responsavel_empresa_cliente:
            clienteOuFinanciador.nomeResponsavelFisico_cliente,
          cpf_responsavel_empresa_cliente:
            clienteOuFinanciador.cpfResponsavel_cliente,
        }),
        localizacao_instalacao: localizacao,
        potencia_kit: proposta.potenciaSistema_proposta,
        componentes_tabela_kit_val: componentesFormatados,
        componentes_tabela_kit_expandido_val: componentesExpandidos,
        revisaoContrato: coletaContratos.length + 1,
        numero_contrato: contratoIdTemporario,
        tabela_ucs: ucTable,
        numero_uc_geradora: dadosCard.uc_coleta_numero,
        media_consumoTotal: formatarNumero(+proposta.consumoTotal_proposta),
        consumoTotal_anual: formatarNumero(
          (+proposta.consumoTotal_proposta * 12).toFixed(2)
        ),
        estimativa_geracao: formatarNumero(
          +(+proposta.estimativa_proposta).toFixed(2)
        ),
        geracao_anual: (+proposta.estimativa_proposta * 12).toFixed(2),
        media_consumo_uc_geradora: formatarNumero(
          +proposta.consumoTotal_proposta
        ),
        agencia_loja: lojaAtual?.nrAgencia_conta_loja,
        conta_loja: lojaAtual?.conta_loja,
        pix_loja: lojaAtual?.pix_loja,
        banco_loja: lojaAtual?.nome_inst_bancaria,
        banco_proposta: proposta.banco_proposta,
        conta_proposta: proposta.conta_proposta,
        agencia_proposta: proposta.agencia_proposta,
        nome_distribuidor: proposta.nome_distribuidor,
        periodoEficiencia: parametrosLocal?.anos_eficiencia_modulo_parametro,
        eficiencia_modulos_25anos:
          parametrosLocal?.eficiencia_25anos_modulo_parametro,
        complementos_bancarios_loja: lojaAtual?.complementos_bancarios_loja,
        cnpj_loja: lojaAtual?.cnpj_loja,
        // Mantem tags existentes, agora baseadas na data de geração do contrato.
        mes_extenso: mesExtensoGeracao,
        ano_numero: anoNumeroGeracao,
        dia_numero: diaNumeroGeracao,
        // Tags explicitas para uso direto em templates de contrato.
        mes_extenso_geracao_contrato: mesExtensoGeracao,
        ano_numero_geracao_contrato: anoNumeroGeracao,
        dia_numero_geracao_contrato: diaNumeroGeracao,
      };

      // Função para sanitizar strings que podem causar problemas no relacionamento
      const sanitizeString = (value: any): any => {
        if (typeof value === "string") {
          // Remove ou escapa aspas duplas problemáticas
          return value
            .replace(/"/g, "'") // Substitui aspas duplas por aspas simples
            .replace(/\r\n/g, " ") // Remove quebras de linha
            .replace(/\n/g, " ") // Remove quebras de linha
            .replace(/\r/g, " ") // Remove carriage return
            .replace(/\t/g, " ") // Remove tabs
            .replace(/\s+/g, " ") // Remove espaços múltiplos
            .trim(); // Remove espaços nas extremidades
        }
        return value;
      };

      Object.keys(dadosParaRelacionar).map((chave) => {
        if (chave.includes("img_") && !dadosParaRelacionar[chave]) {
          delete dadosParaRelacionar[chave];
        } else if (dadosParaRelacionar[chave]) {
          // Sanitiza o valor para evitar problemas com aspas e caracteres especiais
          dadosParaRelacionar[chave] = sanitizeString(
            dadosParaRelacionar[chave]
          );
        }
      });
      setLoaderStep(1);
      const nomesRelacionamentos = new Set(
        relacionamentosContrato.map((r) => r.name)
      );
      // Deleta do objeto tudo que não está na lista de relacionamentos
      Object.keys(dadosParaRelacionar).forEach((key) => {
        if (!nomesRelacionamentos.has(key)) {
          delete dadosParaRelacionar[key];
        }
      });

      // Função auxiliar para verificar se é uma data inválida
      const isDataInvalida = (valor: any): boolean => {
        if (typeof valor !== "string") return false;
        return (
          valor === "00/00/0000" ||
          valor === "0000-00-00" ||
          valor === "00-00-0000" ||
          valor.includes("00/00/0000") ||
          valor.includes("0000-00-00")
        );
      };

      // Validação: Se a tag existe em nomesRelacionamentos mas não tem valor, atribui "Não informado"
      // Exceção: Complementos de endereço ficam vazios para não ficar estranho no endereço
      // Datas inválidas (00/00/0000) também recebem "Não informado"
      nomesRelacionamentos.forEach((tag) => {
        const valor = dadosParaRelacionar[tag];
        if (
          !tag.includes("img_") &&
          (valor === undefined ||
            valor === null ||
            valor === "" ||
            (typeof valor === "string" && valor.trim() === "") ||
            isDataInvalida(valor))
        ) {
          // Campos de complemento de endereço recebem string vazia
          if (tag.includes("complemento")) {
            dadosParaRelacionar[tag] = "";
          } else {
            dadosParaRelacionar[tag] = "Não informado";
          }
        }
      });

      const images = Object.keys(dadosParaRelacionar).reduce(
        (acc: any[], key) => {
          if (
            typeof dadosParaRelacionar[key] == "string" &&
            dadosParaRelacionar[key].includes("data:image/")
          ) {
            acc = [...acc, key];
          }
          return acc;
        },
        []
      );

      if (images.length > 0) {
        setLoaderStep(2);
        const imagensPayload = images.map((key) => ({
          key,
          base64: dadosParaRelacionar[key],
        }));
        const links = await salvarAwsContratoLink({
          imagens: imagensPayload,
          contratoId: contratoIdTemporario,
          sigla: session["sigla"],
        });

        links.forEach(({ key, link }: { key: string; link: string }) => {
          dadosParaRelacionar[key] = link;
        });
      }
      setLoaderStep(3);

      // if (!accessToken) {
      //   toast.error("Sem token válido para gerar o PDF.");
      //   return;
      // }
      generatePdf(
        dadosParaRelacionar,
        documentId,
        lojaAtual?.id_loja as any,
        session.sigla
      )
        .then((resPdfContrato) => {
          setLoaderStep(4);

          const base64 = resPdfContrato.data.base64;
          const pdfUrl = `data:application/pdf;base64,${base64}`;
          setPdf(pdfUrl);
          const byteCharacters = atob(base64);
          const byteArrays = [];

          for (let offset = 0; offset < byteCharacters.length; offset += 512) {
            const slice = byteCharacters.slice(offset, offset + 512);
            const byteNumbers = new Array(slice.length);

            for (let i = 0; i < slice.length; i++) {
              byteNumbers[i] = slice.charCodeAt(i);
            }

            byteArrays.push(new Uint8Array(byteNumbers));
          }

          const pdfBlob = new Blob(byteArrays, { type: "application/pdf" });

          const blobToDataURL = async (blob: Blob) => {
            return new Promise((resolve, reject) => {
              const reader = new FileReader();
              reader.onload = () => resolve(reader.result);
              reader.onerror = reject;
              reader.readAsDataURL(blob);
            });
          };
          blobToDataURL(pdfBlob)
            .then(async (pdfUrl) => {
              // reListarDadosKanban();
              // setPdf(pdfUrl);
              setPdfBlob(pdfBlob);
            })
            .finally(() => {
              deleteDoc(
                resPdfContrato.data.documentId,
                lojaAtual?.id_loja as any,
                session.sigla
              );
            });
        })
        .catch((err) => {
          console.error(err);
          setHasError(true);
          const errorMessage = err?.response?.data?.erro
            ? `Erro ao gerar o PDF: ${err.response.data.erro}`
            : "Não foi possível gerar o PDF. Verifique os dados e tente novamente.";
          toast.error(errorMessage);
        })
        .finally(() => {
          setIsLoaded(true);
        });
    } catch (e) {
      console.error(e);
      toast.error("Erro ao gerar o template");
    } finally {
      console.timeEnd("GerarContrato-total");
    }
    // return template;
  };

  useEffect(() => {
    return () => {
      if (!regerarContrato && !contratoSalvo) {
        deletarContrato({ id_contrato: contratoIdTemporario });
      }
    };
  }, []);

  const onSaveFormContrato = () => {
    setIsSavingContrato(true);
    setIsLoading(true);
    const { session } = valuesSession();

    if (regerarContrato && contratoExistente?.id_contrato) {
      if (!pdfBlob) {
        setIsSavingContrato(false);
        setIsLoading(false);
        return toast.error("PDF do contrato ainda não foi gerado");
      }

      const formulario = new FormData();
      formulario.append("pdfBlob", pdfBlob);
      formulario.append("id_contrato", String(contratoExistente.id_contrato));
      formulario.append("caminho_contrato", contratoExistente.caminho_contrato);
      formulario.append("id_usuario", String(session.id_usuario));
      formulario.append(
        "id_coleta",
        String(
          contratoExistente.coleta_contrato ||
            proposta?.coleta_proposta ||
            dadosCard?.id_coleta_cliente ||
            ""
        )
      );

      return salvarPdfContrato(formulario)
        .then(() => {
          contratoSalvo = true;
          toast.success("PDF do contrato regerado com as novas datas");
          reloadContratos();
        })
        .catch((err: any) => {
          toast.error(err?.message || "Erro ao regerar o PDF do contrato");
        })
        .finally(() => {
          setIsSavingContrato(false);
          setIsLoading(false);
        });
    }

    const dataAtual = new Date()?.toLocaleString("sv-SE", {
      timeZone: "America/Sao_Paulo",
      hour12: false,
    });
    // Gera o ID do contrato apenas ao salvar
    listarUltimoIdContrato().then((id) => {
      const novoContratoId = Number(id) + 1;
      setContratoId(novoContratoId);
      contratoIdTemporario = novoContratoId;

      const formulario = new FormData();
      if (pdfBlob) {
        formulario.append("pdfBlob", pdfBlob);
        const dados: any = {
          id_contrato: novoContratoId,
          coleta_contrato: proposta.coleta_proposta,
          revisao_contrato: coletaContratos.length + 1,
          cliente_contrato: dadosCliente.id_cliente,
          financiador_contrato: dadosCliente.id_financiador,
          proposta_contrato: proposta.id_proposta,
          caminho_contrato: `clientes/${dadosCliente.pasta_cliente}/Contratos/Contrato_${proposta.id_proposta}_Versao_${
            coletaContratos.length + 1
          }_Coleta_${proposta.coleta_proposta}.pdf`,
          data_contrato: dataAtual,
          data_geracao_contrato: dataGeracaoContrato,
          user_contrato: session.id_usuario,
          dataEmail_contrato: "",
          horaEmail_contrato: "",
          userEmail_contrato: "",
          status_contrato: "0",
          id_card: dadosCard.id,
          // Persistido no backend em arquivo .origem.json (não é coluna da tabela).
          origem_dados_default: origemDadosDefaultContrato
            ? JSON.stringify(origemDadosDefaultContrato)
            : "",
          // ...camposPersonalizadosSearch,
        };
        for (const key in dados) {
          formulario.append(key, dados[key]);
        }
        salvarContrato(formulario)
          .then(async () => {
            await addConclusaoPendencia({
              id_coleta: dadosCard.id_coleta_cliente,
              id_etapa: dadosCard.id_lista,
              id_pendencia: "5",
            });

            contratoSalvo = true;

            reloadContratos();
          })
          .finally(() => {
            setIsSavingContrato(false);
            setIsLoading(false);
          });
      }
    });
  };

  return proposta ? (
    <div>
      {isLoaded ? (
        <div className="flex flex-col ">
          {origemDadosDefaultContrato ? (
            <div
              className={`flex flex-row gap-3 items-start rounded-lg border-l-4 p-3 mb-4 ${
                (origemDadosDefaultContrato as IOrigemDadosDefaultContrato)
                  .tipo === "CONTRATO_EXISTENTE"
                  ? "border-warning bg-warning bg-opacity-10"
                  : "border-primary bg-primary bg-opacity-10"
              }`}
            >
              <Info size={20} className="shrink-0 mt-0.5" />
              <div className="flex flex-col gap-1">
                <span className="font-bold text-sm">
                  Como este contrato foi gerado
                </span>
                <span className="text-xs">
                  {
                    (origemDadosDefaultContrato as IOrigemDadosDefaultContrato)
                      .descricao
                  }
                </span>
              </div>
            </div>
          ) : null}
          {hasError ? (
            <div className="flex flex-col items-center justify-center text-center p-8">
              <span className="text-red-500 text-xl font-semibold mb-4">
                Erro ao gerar o contrato
              </span>
              <span className="text-gray-600 mb-6">
                Não foi possível gerar o PDF. Verifique os dados do contrato e
                tente novamente.
              </span>
              {/* <button
                type="button"
                onClick={() => {
                  setHasError(false);
                  setIsLoaded(false);
                  gerarContrato(ensureAccessToken, parametros, orientacoes);
                }}
                className="px-6 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
              >
                Tentar Novamente
              </button> */}
            </div>
          ) : (
            <>
              <button
                type="button"
                onClick={() => onSaveFormContrato()}
                className={`flex flex-row hover:bg-opacity-80 mb-9 md:w-fit md:px-9 py-3 flex-nowrap max-sm:mx-4 max-sm:justify-center max-sm:px-13 max-sm:h-10 max-sm:text-xs items-center bg-success rounded px-2  text-white ${
                  isSavingContrato && "opacity-50"
                }`}
                disabled={isSavingContrato}
              >
                {!isSavingContrato && (
                  <div className="pr-2">
                    <FaFileUpload />
                  </div>
                )}
                {isSavingContrato ? (
                  <Image width={32} height={32} src={LoaderGif} alt="Logo" />
                ) : regerarContrato ? (
                  "Salvar PDF Regenerado"
                ) : (
                  "Salvar Contrato"
                )}
              </button>
              {pdf && (
                <PDFViewer
                  // height={460}
                  // width={700}
                  pdfUrl={pdf}
                />
              )}
            </>
          )}
        </div>
      ) : (
        <div className="w-full h-[500px] flex flex-col justify-center items-center">
          <div className="flex w-[273px] h-[230px]">
            <Image
              style={{ transform: "scale(13.5) translate(-22px, 3px)" }}
              src="/images/loaders/loaderProposta.svg"
              alt="Carregando..."
              width={980}
              height={280}
            />
          </div>
          <span className="text-black text-3xl mb-9">Gerando Contrato</span>
          <LoaderBar steps={steps} currentStep={loaderStep} />
        </div>
      )}
    </div>
  ) : (
    <div className="flex flex-col items-center justify-center text-lg">
      Não é possível gerar contrato pois a proposta ainda não foi aprovada
    </div>
  );
};

export default GeracaoContrato;
