import LoaderSun from "@/components/common/Loader/LoaderSun";
import FileRenderer from "@/components/FileRenderer";
import Button from "@/components/Forms/Button";
import Input from "@/components/Forms/Input";
import ReactTable from "@/components/ReactTable/ReactTable";
import { baixarAwsBase64 } from "@/requests/common/Aws/baixarAws";
import { salvarValidacaoCustosOS } from "@/requests/CRM/PosvOrdensServico/salvarValidacaoCustosOS";
import { addConclusaoPendencia } from "@/requests/CRUD/ConclusaoPendencia/conclusaoPendencia";
import { obterLoja } from "@/requests/CRUD/Lojas/obterLoja";
import { listarMotivosReagendamento } from "@/requests/CRUD/MotivosReagendamento/listarMotivosReagendamento";
import { listarResponsabilidadesFinanceiras } from "@/requests/CRUD/ResponsabilidadesFinanceiras/listarResponsabilidadesFinanceiras";
import { listarUsuarios } from "@/requests/CRUD/Usuario/listarUsuarios";
import {
  formatarValor,
  FormatFields,
  getDateBrasil,
  GetForm,
  GetGallery,
  handleDownload,
} from "@/utils";
import { useEffect, useState } from "react";
import { FaPaperclip } from "react-icons/fa";
import { MdClose } from "react-icons/md";

const VisualizacaoValidacaoOS = ({
  ordemServico,
  // defaultValues,
  dadosCard,
  dadosCliente,
  usuario,
  setActiveStepAtual,
  setOpenModalCustosOrdemServico,
  setOpenModalBaixarOrdemServico,
  setOpenModalValidacaoOrdemServico,
  setActiveTab,
  // usuarios,
  // proposta,

  // contrato,
  atualizarOrdensServico,
  isDisabled,
  ...rest
}: {
  [x: string]: any;
}) => {
  const columns = [
    // {
    //   header: "ID",
    //   accessorKey: "id_anexo_crm",
    // },
    {
      header: "Responsabilidade Financeira",
      accessorKey: "cod_respfin_pvos",
    },
    {
      header: "Terceiro Responsável",
      accessorKey: "terceiro_pvos",
    },
    {
      header: "Conclusão do Serviço",
      accessorKey: "dataConclusao_execucao_servico",
    },
    {
      header: "Valor Total",
      accessorKey: "valor_execucao_servico",
    },
    {
      header: "Valor do Serviço",
      accessorKey: "valorServico_execucao_servico",
    },
    {
      header: "Valor do km",
      accessorKey: "valorKm_execucao_servico",
    },
    {
      header: "Quilometragem",
      accessorKey: "qtdKm_execucao_servico",
    },
    {
      header: "Valor Hora",
      accessorKey: "valorHora_execucao_servico",
    },
    {
      header: "Qtd Horas",
      accessorKey: "qtdHoras_execucao_servico",
    },
    {
      header: "Observação dos custos",
      accessorKey: "obs_execucao_servico",
    },
  ];

  const defaultValues = isDisabled
    ? {
        ...ordemServico,
        // dataConclusao_execucao_servico:
        //   ordemServico?.dataConclusaoBaixaValidacao_execucao_servico,
        obs_execucao_servico: ordemServico?.obsBaixaValidacao_execucao_servico,

        valor_execucao_servico: ordemServico?.valorValidacao_execucao_servico,
        valorServico_execucao_servico:
          ordemServico?.valorServicoValidacao_execucao_servico,
        qtdKm_execucao_servico: ordemServico?.qtdKmValidacao_execucao_servico,
        qtdHoras_execucao_servico:
          ordemServico?.qtdHorasValidacao_execucao_servico,
        valorTotalKm_execucao_servico:
          ordemServico?.valorTotalKmValidacao_execucao_servico,
        valorTotalHora_execucao_servico:
          ordemServico?.valorTotalHoraValidacao_execucao_servico,
        obsCustos_execucao_servico:
          ordemServico?.obsCustosValidacao_execucao_servico,
        motivoAtraso_execucao_servico:
          ordemServico?.motivoAtrasoValidacao_execucao_servico,
        descricaoAtraso_execucao_servico:
          ordemServico?.descricaoAtrasoValidacao_execucao_servico,
        cod_respfin_pvos: ordemServico?.cod_respfin_validacao_execucao_servico,
        terceiro_pvos:
          ordemServico?.cod_terceiro_respfin_validacao_execucao_servico,
        valorKm_execucao_servico:
          ordemServico?.valorKmValidacao_execucao_servico,
        valorHora_execucao_servico:
          ordemServico?.valorHoraValidacao_execucao_servico,
      }
    : ordemServico;

  const [motivosReagendamento, setMotivosReagendamento] = useState<any[]>([]);
  const [anexos, setAnexos] = useState<File[]>(false || []);
  const [imageUrls, setImageUrls] = useState<string[]>([]);
  const [isLoadingAnexos, setIsLoadingAnexos] = useState(false);
  const [inputKey, setInputKey] = useState(1);
  const [responsabilidaesFinanceiras, setResponsabilidaesFinanceiras] =
    useState<any[]>([]);

  const [isLoading, setIsLoading] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const [loja, setLoja] = useState<any>();
  const [usuarios, setUsuarios] = useState<any[]>([]);
  const [justificarAlteracoes, setJustificarAlteracoes] = useState(false);
  const [changeCustos, setChangeCustos] = useState(false);

  const { handleSubmit, ...form } = GetForm();
  const { ...formBaixaOS } = GetForm();
  const { ...formCustosServicoOS } = GetForm();
  const { openGallery, setGallery } = GetGallery();

  useEffect(() => {
    const valuesFormBaixaOS = formBaixaOS?.control?._formValues;
    const valuesFormCustosServicoOS = formCustosServicoOS?.control?._formValues;

    const is_terceiro_respfin =
      form?.watch()?.cod_respfin_validacao_execucao_servico
        ?.is_terceiro_respfin == 1;
    if (!is_terceiro_respfin) {
      form.control.unregister(
        ["cod_terceiro_respfin_validacao_execucao_servico"] as never[],
        {
          keepDirty: false,
          keepValue: false,
          keepError: false,
        },
      );
      // form.reload();
      form.setYupSchema((prev: any) => {
        const fields: any = prev.fields;
        delete fields["cod_terceiro_respfin_validacao_execucao_servico"];
        prev.fields = fields;
        return prev;
      });
    }
  }, [
    form?.watch()?.cod_respfin_validacao_execucao_servico?.is_terceiro_respfin,
  ]);

  useEffect(() => {
    if (changeCustos) {
    } else {
      if (
        Object?.keys(form?.control?._formValues)?.includes(
          "justificativaAlteracoesValidacao_execucao_servico",
        )
      ) {
        form.control.unregister(
          ["justificativaAlteracoesValidacao_execucao_servico"] as never[],
          {
            keepDirty: false,
            keepValue: false,
            keepError: false,
          },
        );
        // form.reload();
        form.setYupSchema((prev: any) => {
          const fields: any = prev.fields;
          delete fields["justificativaAlteracoesValidacao_execucao_servico"];
          prev.fields = fields;
          return prev;
        });
      }
      form.reload();
      formCustosServicoOS.reset();
    }
  }, [changeCustos]);

  const adicionarAnexo = (event: any) => {
    const inputElement = event.target as HTMLInputElement;
    if (inputElement.files && inputElement.files.length > 0) {
      let arquivo = inputElement.files[0];
      setAnexos((prev) => {
        // if (prev.some((anexo) => anexo.name == arquivo.name)) {
        let nomeArquivo = arquivo.name?.replaceAll("/", "_");
        let extensao = nomeArquivo.substring(nomeArquivo.lastIndexOf("."));
        let nomeBase = nomeArquivo.substring(0, nomeArquivo.lastIndexOf("."));

        let contador = 0;
        let novoNome = nomeArquivo;
        while (prev.some((anexo) => anexo.name === novoNome)) {
          novoNome = `${nomeBase} (${++contador})${extensao}`;
        }
        arquivo = new File([arquivo], novoNome, {
          type: arquivo.type,
          lastModified: arquivo.lastModified,
        });
        // }

        return [...prev, arquivo];
      });

      setInputKey(inputKey + 1);
    }
  };

  useEffect(() => {
    setInputKey(inputKey + 1);
    const loadImages = async () => {
      const newImageUrls = await Promise.all(
        anexos.map(async (anexo) => {
          const reader = new FileReader();
          return new Promise((resolve) => {
            reader.onload = () => resolve(reader.result as string);
            reader.readAsDataURL(anexo);
          }).catch(() => {});
        }),
      );
      setImageUrls(newImageUrls as string[]);
      setGallery(
        newImageUrls.map((newImageUrl, index) => ({
          src: newImageUrl as string,
          name: anexos[index].name?.split("/").pop()!,
        })),
      );
    };

    loadImages();
  }, [anexos]);

  useEffect(() => {
    Promise.all([
      listarMotivosReagendamento().then(setMotivosReagendamento),
      obterLoja({ id_loja: dadosCard?.id_loja_coleta }).then(setLoja),
      listarUsuarios().then(setUsuarios),
      listarResponsabilidadesFinanceiras().then(setResponsabilidaesFinanceiras),
      (async () => {
        if (defaultValues && defaultValues["anexos_data"]) {
          const anexos_data = defaultValues["anexos_data"];

          setIsLoadingAnexos(true);
          return Promise.all(
            anexos_data
              ?.filter((anexo: any) => anexo?.tipoAnexo_os_pvos == "3")
              .map((data: any) =>
                baixarAwsBase64(data["caminho_arq_pvos"]).then((res) => {
                  const resultObject =
                    typeof res === "string" ? JSON.parse(res) : res;
                  const base64Content = resultObject.base64;

                  const byteCharacters = atob(base64Content);
                  const byteNumbers = new Array(byteCharacters.length);
                  for (let i = 0; i < byteCharacters.length; i++) {
                    byteNumbers[i] = byteCharacters.charCodeAt(i);
                  }
                  const byteArray = new Uint8Array(byteNumbers);
                  const blob = new Blob([byteArray], {
                    type: "application/octet-stream",
                  });

                  const fileName = data["caminho_arq_pvos"].split("/").pop();
                  const file = new File([blob], fileName, { type: blob.type });
                  (file as any).id = data?.id_arq_pvos;
                  return file;
                }),
              ),
          )
            .then((res) => {
              setAnexos(res);
            })
            .finally(() => setIsLoadingAnexos(false));
        }
      })(),
    ]).finally(() => {
      setIsLoaded(true);
    });
  }, []);

  async function onSubmitFormValidacaoOS(e: any) {
    setIsLoading(true);
    return Promise.all(
      [
        formBaixaOS?.handleSubmit,
        formCustosServicoOS?.handleSubmit,
        handleSubmit,
      ].map(
        (handleSubmitItem) =>
          new Promise((resolve, reject) => {
            handleSubmitItem((d: any) => {
              return resolve(d);
            })(e).finally(() => reject(false));
          }),
      ),
    )
      .then(async (res) => {
        const [validacaoBaixa, validacaoCustosServico, dataValidacao] =
          res as any[];

        const newData = {
          ...dataValidacao,

          valorValidacao_execucao_servico:
            validacaoCustosServico?.valor_execucao_servico,
          valorServicoValidacao_execucao_servico:
            validacaoCustosServico?.valorServico_execucao_servico,
          qtdKmValidacao_execucao_servico:
            validacaoCustosServico?.qtdKm_execucao_servico,
          qtdHorasValidacao_execucao_servico:
            validacaoCustosServico?.qtdHoras_execucao_servico,
          // valorKmValidacao_execucao_servico: loja?.valor_km_loja,
          // valorHoraValidacao_execucao_servico: loja?.valor_hora_adicional_loja,
          valorTotalKmValidacao_execucao_servico:
            validacaoCustosServico?.valorTotalKm_execucao_servico,
          valorTotalHoraValidacao_execucao_servico:
            validacaoCustosServico?.valorTotalHora_execucao_servico,
          obsCustosValidacao_execucao_servico:
            validacaoCustosServico?.obsCustos_execucao_servico,
          motivoAtrasoValidacao_execucao_servico:
            validacaoCustosServico?.motivoAtraso_execucao_servico,
          descricaoAtrasoValidacao_execucao_servico:
            validacaoCustosServico?.descricaoAtraso_execucao_servico,

          dataConclusaoBaixaValidacao_execucao_servico:
            validacaoBaixa?.dataConclusao_execucao_servico,
          obsBaixaValidacao_execucao_servico:
            validacaoBaixa?.obs_execucao_servico,

          // Verificar as defaultValues
          anexosCustosServico: validacaoCustosServico?.anexos,
          caminhos_anexosCustosServico: validacaoCustosServico?.anexos?.map(
            (anexo: File) => ({
              cod_os_pvos: ordemServico?.id_pvos,
              caminho_arq_pvos: `clientes/${dadosCliente?.pasta_cliente}/${dadosCard?.id_coleta_cliente}/OrdensServico/anexosCustosInstalador/${anexo.name}`,
              nome_arq_pvos: anexo.name,
              tipoAnexo_os_pvos: "2",
              id_arq_pvos: (anexo as any)?.id || null,
            }),
          ),

          anexosBaixa: validacaoBaixa?.anexos,
          caminhos_anexosBaixa: validacaoBaixa?.anexos?.map((anexo: File) => ({
            cod_os_pvos: ordemServico?.id_pvos,
            caminho_arq_pvos: `clientes/${dadosCliente?.pasta_cliente}/${dadosCard?.id_coleta_cliente}/OrdensServico/anexosBaixaInstalador/${anexo.name}`,
            nome_arq_pvos: anexo.name,
            tipoAnexo_os_pvos: "1",
            id_arq_pvos: (anexo as any)?.id || null,
          })),

          anexos,
          caminhos_anexos: anexos?.map((anexo: File) => ({
            cod_os_pvos: ordemServico?.id_pvos,
            caminho_arq_pvos: `clientes/${dadosCliente?.pasta_cliente}/${dadosCard?.id_coleta_cliente}/OrdensServico/anexosValidacaoOS/${anexo.name}`,
            nome_arq_pvos: anexo.name,
            tipoAnexo_os_pvos: "3",
            id_arq_pvos: (anexo as any)?.id || null,
          })),

          id_card: dadosCard?.id,
          id_execucao_servico: ordemServico?.id_execucao_servico,
          userValidacao_execucao_servico: usuario?.id_usuario,
          coleta_execucao_servico: ordemServico?.coleta_execucao_servico,
          os_execucao_servico: ordemServico?.os_execucao_servico,
          statusValidacao_execucao_servico: "1",
        };

        return onSubmitValidacaoOS(newData);
        // setIsLoading(false);
        // return res;
      })
      .catch((err) => {
        setIsLoading(false);
      });
  }

  async function onSubmitValidacaoOS(data: any) {
    // setIsLoading(false);
    return salvarValidacaoCustosOS(data)
      .then(async () => {
        return Promise.all([
          atualizarOrdensServico(),
          addConclusaoPendencia({
            id_coleta: dadosCard.id_coleta_cliente,
            id_etapa: dadosCard.id_lista,
            id_pendencia: "24",
          }),
          (async () => {
            const responsabilidadeFinanceira =
              responsabilidaesFinanceiras?.find(
                (responsabilidade) =>
                  responsabilidade?.id_respfin ==
                  data?.cod_respfin_validacao_execucao_servico,
              );
            if (responsabilidadeFinanceira?.faturar_respfin == "0") {
              return addConclusaoPendencia({
                id_coleta: dadosCard.id_coleta_cliente,
                id_etapa: dadosCard.id_lista,
                id_pendencia: "26",
              }).then(async () => {
                if (
                  defaultValues?.is_externo_usuario &&
                  defaultValues?.is_externo_usuario != "0"
                ) {
                  return addConclusaoPendencia({
                    id_coleta: dadosCard.id_coleta_cliente,
                    id_etapa: dadosCard.id_lista,
                    id_pendencia: "27",
                  });
                }
                return;
              });
            } else {
              return;
            }
          })(),
        ]).then(() => {
          setActiveStepAtual((prev: any) => prev + 1);
        });
      })
      .then(() => {
        setOpenModalValidacaoOrdemServico(false);
      })
      .finally(() => {
        setIsLoading(false);
      });
  }

  const fakeListOld = async (): Promise<any[]> => {
    const promise: Promise<any[]> = new Promise((resolve, reject) =>
      resolve([ordemServico]),
    );
    return promise;
  };

  const fakeListNew = async (): Promise<any[]> => {
    const promise: Promise<any[]> = new Promise((resolve, reject) =>
      resolve([defaultValues]),
    );
    return promise;
  };

  async function formatFunction(arr: any[]) {
    const { formatarNumero } = FormatFields;
    return arr.map((e) => {
      e.cod_respfin_pvos = responsabilidaesFinanceiras?.find(
        (resp) => resp?.id_respfin == e.cod_respfin_pvos,
      )?.nome_respfin;
      e.terceiro_pvos = ["", "0", null, undefined]?.includes(e.terceiro_pvos)
        ? ""
        : usuarios?.find((usuario) => usuario?.id_usuario == e.terceiro_pvos)
            ?.nome_usuario;
      e.dataConclusao_execucao_servico = e.dataConclusao_execucao_servico
        ? getDateBrasil(undefined, e.dataConclusao_execucao_servico)
        : "";

      e.valor_execucao_servico = formatarValor(e.valor_execucao_servico);
      e.valorServico_execucao_servico = formatarValor(
        e.valorServico_execucao_servico,
      );
      e.valorKm_execucao_servico = formatarValor(e.valorKm_execucao_servico);
      e.qtdKm_execucao_servico =
        formatarNumero(e.qtdKm_execucao_servico) + " km";
      e.valorHora_execucao_servico = formatarValor(
        e.valorHora_execucao_servico,
      );
      e.qtdHoras_execucao_servico =
        formatarNumero(e.qtdHoras_execucao_servico) + " h";
      return e;
    });
  }

  return isLoaded ? (
    <div className="flex flex-row flex-wrap gap-4" key={form.key}>
      <div className="w-full flex flex-col items-center justify-center gap-5">
        <div className="w-full flex flex-col items-center justify-center">
          <div className="text-title-lg">Dados do Custo</div>
          <ReactTable
            columns={columns}
            listFunction={fakeListOld}
            formatFunction={formatFunction}
            hidePagination
            cannotFilter
          />
        </div>
        <div className="w-full flex flex-col items-center justify-center">
          <div className="text-title-lg">Log de Alterações</div>
          <ReactTable
            columns={columns}
            listFunction={fakeListNew}
            formatFunction={formatFunction}
            hidePagination
            cannotFilter
          />
        </div>
      </div>

      <Input
        name="obsValidacao_execucao_servico"
        label="Observações da Validação"
        formulario={form}
        defaultValue={
          defaultValues && defaultValues?.obsValidacao_execucao_servico
        }
        disabled={isDisabled}
        width={"flex-1"}
      />

      {/* {justificarAlteracoes && ( */}
      {(changeCustos || isDisabled) && (
        <Input
          name="justificativaAlteracoesValidacao_execucao_servico"
          label="Justificativa das alterações"
          formulario={form}
          defaultValue={
            defaultValues &&
            defaultValues?.justificativaAlteracoesValidacao_execucao_servico
          }
          type="textarea"
          disabled={isDisabled}
          // width={"flex-1"}
          required
          error="Justifique as alterações"
        />
      )}

      <div className="w-full">
        <div>Anexos da Validação</div>
        <div className="pt-1">
          <div className="flex flex-col gap-1 max-h-[200px] overflow-auto">
            {isLoadingAnexos ? (
              <div className="flex justify-center items-center">
                <LoaderSun height={100} />
              </div>
            ) : (
              imageUrls.map((imageUrl, index) => {
                const anexo: File = anexos[index];
                return (
                  <div
                    key={index}
                    className="flex flex-row justify-between px-2 cursor-pointer hover:bg-[rgb(0,0,0)]/[.1] border border-transparent hover:border-black/[0.4] rounded"
                    onClick={() => handleDownload(anexo)}
                  >
                    <div className="w-[400px] overflow-hidden text-ellipsis p-1 flex flex-row items-center gap-1">
                      <figure
                        className="flex flex-col items-center overflow-hidden w-[20%] hover:w-[50%] transition-all"
                        onClick={(e) => {
                          e.stopPropagation();
                          openGallery(index);
                        }}
                      >
                        <FileRenderer
                          src={imageUrl}
                          name={anexo?.name?.split("/").pop()!}
                          className={
                            "h-full w-30 flex flex-col items-center justify-center bg-animate-pulse bg-white rounded overflow-hidden"
                          }
                          width={200}
                        />
                      </figure>
                      {anexo?.name}
                    </div>
                    <button
                      type="button"
                      onClick={(e) => {
                        e.stopPropagation();
                        setAnexos((prev) => {
                          const newAnexos = [...prev];
                          newAnexos.splice(index, 1);
                          return newAnexos;
                        });
                      }}
                    >
                      <MdClose />
                    </button>
                  </div>
                );
              })
            )}
          </div>
          {!isDisabled && (
            <label
              htmlFor="add_anexo_validacao"
              // htmlFor={indexItem}
              className="justify-center dark:text-white whitespace-nowrap rounded-md font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 text-primary-foreground flex bg-success hover:brightness-90 hover:bg-success text-sm h-fit items-center w-fit m-1 mb-4 p-1 px-2 cursor-pointer"
            >
              <FaPaperclip /> Adicionar Anexo
            </label>
          )}
          <input
            id="add_anexo_validacao"
            // id={indexItem}
            type="file"
            // accept="image/png, image/gif, image/jpeg"
            className="hidden"
            key={inputKey}
            onInput={(e) => adicionarAnexo(e)}
          />
        </div>
      </div>
      {!isDisabled && (
        <div>
          <Button
            type="button"
            onClick={onSubmitFormValidacaoOS}
            loading={isLoading}
          >
            Salvar
          </Button>
        </div>
      )}
    </div>
  ) : (
    <div className="flex justify-center w-full">
      <LoaderSun />
    </div>
  );
};

export default VisualizacaoValidacaoOS;
