import Breadcrumb from "@/components/Breadcrumbs/Breadcrumb";
import Button from "@/components/Forms/Button";
import Container from "@/components/Forms/Container";
import { baixarTemplateImportacaoClientes } from "@/requests/CRUD/Cliente/baixarTemplateImportacaoClientes";
import { importarClientes } from "@/requests/CRUD/Cliente/importarClientes";
import { useAuth } from "@/src/contexts/authContext";
import { useScreenContext } from "@/src/contexts/ScreenContext";
import { validarCNPJ, validarCPF } from "@/utils";
import { useEffect, useState } from "react";
import { FaCloudDownloadAlt } from "react-icons/fa";
import { MdCloudUpload } from "react-icons/md";
import { toast } from "react-toastify";
import { read, utils } from "xlsx";

export default function ImportacaoClientes() {
  const [arquivo, setArquivo] = useState<File | null>(null);
  const [docErrors, setDocErrors] = useState<any>();
  const [inputKey, setInputKey] = useState(0);
  const [docArrayOfValues, setDocArrayOfValues] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [errorArquivo, setErrorArquivo] = useState<string | null>(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [templateExemplo, setTemplateExemplo] = useState<any>();

  const { isMobile } = useScreenContext();
  const { usuario } = useAuth();

  useEffect(() => {
    baixarTemplateImportacaoClientes()
      .then(setTemplateExemplo)
      .finally(() => setIsLoaded(true));
  }, []);

  useEffect(() => {
    if (docArrayOfValues.length > 0) {
      validarDocArrayOfValues();
    }
  }, [docArrayOfValues]);

  function onChangeArquivo(e: any) {
    setInputKey(inputKey + 1);
    if (e.target && e.target.files) {
      // setArquivo(e.target.files[0]);
      const selectedFile = e.target.files[0];
      setArquivo(selectedFile);

      const reader = new FileReader();
      reader.onload = (e) => {
        try {
          const data = e.target?.result;
          if (data) {
            const workbook = read(data, {
              type: "binary",
              // dateNF: "dd/mm/yyyy",
              dateNF: "yyyy-mm-dd",
            });
            const sheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[sheetName];
            const arrayOfValues: any[] = utils.sheet_to_json(worksheet, {
              // blankrows: true,
              raw: false,
              header: 0,
            });
            //
            const maxIndex = Math.max(
              ...arrayOfValues.map((d) => d.__rowNum__),
            );
            const newArr = Array(maxIndex + 1); // cria array esparso

            for (const obj of arrayOfValues) {
              newArr[obj.__rowNum__] = obj; // atribui no índice certo
            }
            //
            setDocArrayOfValues(newArr);
          }
          setErrorArquivo(null);
        } catch (error) {
          console.error("Erro ao ler o arquivo:", error);
          setErrorArquivo("O arquivo não é um spreadsheet válido");

          setDocArrayOfValues([]);
          setDocErrors(undefined);
        }
      };
      reader.readAsArrayBuffer(selectedFile);

      e.target.files = null;
    }
  }

  async function validarDocArrayOfValues() {
    setIsLoading(true);
    const docErrors: any = {};

    if (docArrayOfValues?.[1]) {
      docArrayOfValues?.map((cliente, i) => {
        if (cliente?.["Nº PROJETO"] > 9999) {
          docErrors[String(i)] = [
            ...(docErrors[String(i)] || []),
            `Nº Projeto não pode ser maior ou igual que 10.000`,
          ];
        }

        [
          "Nº PROJETO",
          "VENDEDOR",
          ...(cliente?.["CLIENTE NOVO?"] == "1"
            ? ["NOME CLIENTE", "CPF / CNPJ", "TELEFONE"]
            : []),
          "CIDADE INSTALAÇÃO",
          "ENDEREÇO INSTALAÇÃO",
          "Nº",
          "BAIRRO",
          "CEP",
          ...(!!cliente?.["NOME FINANCIADOR"]
            ? ["CPF/CNPJ FINANCIADOR", "TELEFONE FINANCIADOR"]
            : []),
          "N° MODULOS",
          "MARCA DO MÓDULO",
          "MODELO DO MÓDULO",
          "POTÊNCIA DO MÓDULO",
          "POTÊNCIA DO MÓDULO",
          "POTÊNCIA DO SISTEMA",
          "MODELO INVERSOR 1",
          "QTD INVERSOR 1",
          ...(!!cliente?.["MODELO INVERSOR 2"] ? ["QTD INVERSOR 2"] : []),
          "TIPO DE TELHADO",
          "CONCLUSÃO INSTALAÇÃO",
          "LOJA",
        ].map((obrigatoryCol) => {
          if (cliente?.[obrigatoryCol] == undefined) {
            docErrors[String(i)] = [
              ...(docErrors[String(i)] || []),
              `${obrigatoryCol} é obrigatório e está vazio`,
            ];
          }
          if (obrigatoryCol.toLowerCase().includes("cpf")) {
            if (
              !cliente?.[obrigatoryCol] ||
              (!validarCPF(cliente?.[obrigatoryCol]) &&
                !validarCNPJ(cliente?.[obrigatoryCol]))
            ) {
              docErrors[String(i)] = [
                ...(docErrors[String(i)] || []),
                `${obrigatoryCol} Não é um CPF/CNPJ válido`,
              ];
            }
          }
        });

        [
          "Nº PROJETO",
          "NÚMERO UC GERADORA",
          "CPF / CNPJ",
          "CPF/CNPJ FINANCIADOR",
          "ID CLIENTE",
        ].map((uniqueCol) => {
          docArrayOfValues.map((val, indexVal) => {
            if (
              val &&
              cliente?.[uniqueCol] &&
              cliente?.[uniqueCol] == val?.[uniqueCol] &&
              i != indexVal
            ) {
              docErrors[String(i)] = [
                ...(docErrors[String(i)] || []),
                `${uniqueCol} se repete na linha ${indexVal + 1}`,
              ];
            }
          });
        });
      });

      if (Object.keys(docErrors).length > 0) {
        setDocErrors(docErrors);
      } else {
        setDocErrors(undefined);
      }

      await importarClientes({
        // id_usuario: usuario?.id_usuario,
        clientes: docArrayOfValues,
      }).then((res) => {
        if (res != "Ok") {
          for (const key in res) {
            docErrors[String(key)] = [
              ...(docErrors[String(key)] || []),
              ...res[key],
            ];
          }
        }
      });
    } else {
      setDocErrors({ "0": ["Documento não apresenta a estrutura do modelo"] });
    }
    if (Object.keys(docErrors).length > 0) {
      setDocErrors(docErrors);
    } else {
      setDocErrors(undefined);
    }
    setIsLoading(false);
    // if (docArrayOfValues?.[1]) {
    //   const docErrors: any = {};
    //   const columnNames = docArrayOfValues[1];
    //   const colNames = [
    //     "FABRICANTE",
    //     "ITEM",
    //     "Item SAP",
    //     "MPPTS (Somente Inversores)",
    //     "Overload (Somente p/ inversores)",
    //     "Potência do Inversor kW (Somente Inversores)",
    //     "Preço de venda",
    //     "QTD Módulos (Somente p/ estruturas)",
    //     "Qtd Máx Módulos (Somente para Microinversor)",
    //     "Rede (Somente p/ inversores)",
    //     "Strings (Somente inversores)",
    //     "Tipo",
    //     "Tipo de Instalação (Somente p/ estruturas)",
    //     "Tipo de Inversor  (Somente p/ inversores)",
    //     "Tipo de Telhado(Somente p/ estruturas)",
    //     "Underload (Somente p/ inversores)",
    //     "Watts",
    //     "Wp (Somente p/ modulos)",
    //   ];
    //   const newArrayOfValues = docArrayOfValues
    //     .filter((_, index) => index > 1)
    //     .map((array, i) => {
    //       const obj: any = {};
    //       columnNames.forEach((columnName: string, index: number) => {
    //         obj[columnName] = array[index];
    //       });

    //       i = i + 3;

    //       docErrors[String(i)] = [];

    //       ["FABRICANTE", "ITEM", "Item SAP", "Preço de venda"].map(
    //         (obrigatoryCol) => {
    //           if (obj[obrigatoryCol] == undefined) {
    //             docErrors[String(i)] = [
    //               ...docErrors[String(i)],
    //               `${obrigatoryCol} é obrigatório e está vazio`,
    //             ];
    //           }
    //         }
    //       );

    //       if (
    //         [
    //           "aterramentos",
    //           "cabos",
    //           "conectores",
    //           "disjuntores",
    //           "dps",
    //           "estacao",
    //           "estruturas",
    //           "inversores",
    //           "modulos",
    //           "monitoramento",
    //           "outros_componentes",
    //           "perfis_aluminio",
    //           "stringbox",
    //           "suportes",
    //           "terminais",
    //         ].every((validTiposItens) => obj["Tipo"] != validTiposItens)
    //       ) {
    //         docErrors[String(i)] = [
    //           ...docErrors[String(i)],
    //           `O Tipo está com um valor inválido ou vazio`,
    //         ];
    //       }

    //       if (obj["Tipo"] == "modulos") {
    //         if (!Number.isInteger(obj["Wp (Somente p/ modulos)"])) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `Wp é obrigatório para módulos e não é um número inteiro válido`,
    //           ];
    //         }
    //       }

    //       if (obj["Tipo"] == "inversores") {
    //         if (
    //           obj["Tipo de Inversor  (Somente p/ inversores)"] !=
    //             "inversor_parede" &&
    //           obj["Tipo de Inversor  (Somente p/ inversores)"] !=
    //             "micro_inversor"
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O tipo de Inversor não é inversor_parede ou micro_inversor`,
    //           ];
    //         }

    //         if (
    //           obj["Tipo de Inversor  (Somente p/ inversores)"] ==
    //             "micro_inversor" &&
    //           !Number.isInteger(
    //             obj["Qtd Máx Módulos (Somente para Microinversor)"]
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `A quantidade máxima de módulos é necessária para microinversores e não é um número inteiro válido`,
    //           ];
    //         }

    //         if (
    //           obj["Tipo de Inversor  (Somente p/ inversores)"] ==
    //             "inversor_parede" &&
    //           !Number.isInteger(obj["Strings (Somente inversores)"])
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `A quantidade de strings é necessária para inversores e não é um número inteiro válido`,
    //           ];
    //         }

    //         if (
    //           obj["Potência do Inversor kW (Somente Inversores)"] ==
    //             undefined ||
    //           !(
    //             +obj["Potência do Inversor kW (Somente Inversores)"] ==
    //               +obj["Potência do Inversor kW (Somente Inversores)"] &&
    //             +obj["Potência do Inversor kW (Somente Inversores)"] > 0
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `A potência do inversor não é um número válido`,
    //           ];
    //         }

    //         if (obj["Watts"] == undefined) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `Watts é obrigatório para inversores e está vazio`,
    //           ];
    //         }

    //         if (
    //           (obj["Underload (Somente p/ inversores)"]
    //             ? obj["Underload (Somente p/ inversores)"]
    //             : 0) >= 100
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O Underload do inversor deve ser menor que 100`,
    //           ];
    //         }

    //         if (
    //           (obj["Overload (Somente p/ inversores)"]
    //             ? obj["Overload (Somente p/ inversores)"]
    //             : 0) <= 100
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O Overload do inversor deve ser maior que 100`,
    //           ];
    //         }

    //         if (
    //           obj["Rede (Somente p/ inversores)"] != "Monofásico" &&
    //           obj["Rede (Somente p/ inversores)"] != "Trifásico"
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `A Rede do Inversor não é Monofásico ou Trifásico`,
    //           ];
    //         }
    //       }

    //       if (obj["Tipo"] == "estruturas") {
    //         if (
    //           ["telhado", "solo", "garagem"].every(
    //             (validValue) =>
    //               obj["Tipo de Instalação (Somente p/ estruturas)"] !=
    //               validValue
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O tipo de Instalação da estrutura não é válido como: telhado, solo ou garagem`,
    //           ];
    //         }

    //         if (
    //           obj["Tipo de Instalação (Somente p/ estruturas)"] == "telhado" &&
    //           ["ceramico", "fcca", "metalico", "laje"].every(
    //             (validValue) =>
    //               obj["Tipo de Telhado(Somente p/ estruturas)"] != validValue
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O tipo de telhado (na instalação de tehlado) da estrutura não é válido como: ceramico, fcca, laje ou metalico`,
    //           ];
    //         } else if (
    //           obj["Tipo de Instalação (Somente p/ estruturas)"] == "solo" &&
    //           ["solo", undefined].every(
    //             (validValue) =>
    //               obj["Tipo de Telhado(Somente p/ estruturas)"] != validValue
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O tipo de telhado (na instalação de solo) da estrutura não é válido como: solo`,
    //           ];
    //         } else if (
    //           obj["Tipo de Instalação (Somente p/ estruturas)"] == "garagem" &&
    //           ["garagem", undefined].every(
    //             (validValue) =>
    //               obj["Tipo de Telhado(Somente p/ estruturas)"] != validValue
    //           )
    //         ) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `O tipo de telhado (na instalação de garagem) da estrutura não é válido como: garagem`,
    //           ];
    //         }

    //         if (!Number.isInteger(obj["QTD Módulos (Somente p/ estruturas)"])) {
    //           docErrors[String(i)] = [
    //             ...docErrors[String(i)],
    //             `A QTD Módulos da estrutura não é um número inteiro válido`,
    //           ];
    //         }
    //       }

    //       if (docErrors[String(i)].length == 0) {
    //         delete docErrors[String(i)];
    //       }

    //       return obj;
    //     });

    //   if (Object.keys(docErrors).length > 0) {
    //     setDocErrors(docErrors);
    //   } else {
    //     setDocErrors(undefined);
    //   }
    // } else {
    //   setDocErrors({ "1": ["Documento não apresenta a estrutura do modelo"] });
    // }
  }

  function saveArquivo() {
    setIsLoading(true);

    const savePromise = new Promise((resolve, reject) => {
      importarClientes({
        id_usuario: usuario?.id_usuario,
        clientes: docArrayOfValues,
      })
        .then((res) => {
          if (res == "Ok") {
            resolve("Ok");
          }
          reject("Erro");
        })
        .catch(() => {
          reject("Erro");
        })
        .finally(() => {
          setIsLoading(false);
        });
    });

    toast.promise(savePromise, {
      pending: {
        render(data: any) {
          return "Aguarde";
        },
      },
      success: {
        render(data: any) {
          return "Salvo com sucesso";
        },
      },
      error: {
        render(data: any) {
          return data.data;
        },
      },
    });
  }

  return (
    <>
      <Breadcrumb pageName="Importação de Clientes" />
      <Container>
        <div>Importação de Clientes Externos</div>
        <div
          className={`flex flex-${isMobile ? "col" : "row"} gap-2 p-3 bg-white`}
        >
          <div
            className={`flex flex-col gap-3 ${
              !isMobile && docErrors ? "w-1/2" : "w-full"
            } items-center`}
          >
            <a
              href={templateExemplo}
              target="_blank"
              className="bg-success text-white w-fit py-2 px-3 rounded hover:opacity-90 active:opacity-100 cursor-pointer flex flex-row items-center gap-2"
            >
              Baixar Template de Exemplo <FaCloudDownloadAlt />
            </a>
            {/* <Button
              type="button"
              className=" text-white w-fit py-2 px-3 rounded hover:opacity-90 active:opacity-100 cursor-pointer flex flex-row items-center gap-2"
              onClick={() => {
                // baixarTemplateImportacaoClientes().then(async (fileUrl) => {
                //   const link = document.createElement("a");
                //   link.href = fileUrl;
                //   link.download = ""; // pode deixar em branco para manter o nome original
                //   document.body.appendChild(link);
                //   link.click();
                //   document.body.removeChild(link);
                // });
              }}
            >
              Baixar Template de Exemplo <FaCloudDownloadAlt />
            </Button> */}
            <label
              htmlFor="arquivo"
              className="bg-primary text-white w-fit py-2 px-3 rounded hover:opacity-90 active:opacity-100 cursor-pointer flex flex-row items-center gap-2"
            >
              Selecionar Arquivo <MdCloudUpload />
            </label>
            <input
              key={inputKey}
              id="arquivo"
              type="file"
              accept=".xlsx,.xls,.ods,.csv,.tsv"
              onInput={onChangeArquivo}
              className="hidden"
            />
            {arquivo && (
              <div>
                <div>{arquivo.name}</div>
              </div>
            )}
            {errorArquivo && <div className="text-error">{errorArquivo}</div>}
            {arquivo && !errorArquivo && !docErrors && (
              <Button type="button" onClick={saveArquivo} loading={isLoading}>
                Salvar
              </Button>
            )}
          </div>

          {docErrors && (
            <div
              className={`flex flex-col ${!isMobile && "w-1/2"} items-center`}
            >
              <div className="text-error font-semibold">Erros</div>
              <div className="max-h-[50vh] overflow-auto shadow-2 rounded-lg p-5">
                <table>
                  <tbody>
                    {Object.keys(docErrors).map((docErrorPosition, index) => (
                      <tr key={index}>
                        <td className="p-2 border-y whitespace-nowrap font-medium">
                          Linha {Number(docErrorPosition) + 1}:
                        </td>
                        <td className="py-1 border-y">
                          <div className="flex flex-col gap-1">
                            {docErrors[docErrorPosition]?.map(
                              (docError: string, i: number) => (
                                <div key={i} className="">
                                  {docError}
                                </div>
                              ),
                            )}
                          </div>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>
          )}
        </div>
      </Container>
    </>
  );
}
