import LoaderSun from "@/components/common/Loader/LoaderSun";
import InputSelectComponent from "@/components/Forms/InputSelect";
import { handleSweetAlert } from "@/components/Modal/SweetAlertConfirm";
import ReactTable from "@/components/ReactTable/ReactTable";
import { cadastrarContaBancariaLoja } from "@/requests/CRUD/ContasBancariasLojas/cadastrarInstBancaria";
import { deletarContaBancariaLoja } from "@/requests/CRUD/ContasBancariasLojas/deletarContaBancariaLoja";
import { editarContaBancariaLoja } from "@/requests/CRUD/ContasBancariasLojas/editarContaBancariaLoja";
import { listarContasBancariasLojas } from "@/requests/CRUD/ContasBancariasLojas/listarContasBancariasLojas";
import { listarInstBancarias } from "@/requests/CRUD/InstBancarias/listarInstBancarias";
import { editarLoja } from "@/requests/CRUD/Lojas/editarLoja";
import { listarLojas } from "@/requests/CRUD/Lojas/listarLojas";
import { useAuth } from "@/src/contexts/authContext";
import { Tooltip } from "@mui/material";
import { Square, SquareCheckBig } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { BiTrash } from "react-icons/bi";
import { MdWarning } from "react-icons/md";
import FormContaBancariaLoja from "./FormContaBancariaLoja";

export const tiposChavePix = [
  { label: "CPF", value: "cpf" },
  { label: "CNPJ", value: "cnpj" },
  { label: "E-mail", value: "email" },
  { label: "Telefone", value: "telefone" },
  { label: "Chave Aleatória", value: "chave aleatória" },
];

export const tiposPessoas = [
  { value: "F", label: "Física" },
  { value: "J", label: "Jurídica" },
];

export default function ContasBancariasLoja({ formLoja, loja }: any) {
  const [lojas, setLojas] = useState<any[]>([]);
  const [instBancarias, setInstBancarias] = useState<any[]>([]);
  const [cod_conta_padrao_loja, setCod_conta_padrao_loja] = useState<any>(
    formLoja?.control?._formValues?.cod_conta_padrao_loja ||
      loja?.cod_conta_padrao_loja
  );
  const [isLoaded, setIsLoaded] = useState(false);
  const [tableKey, setTableKey] = useState<number>(1);
  const { valuesSession } = useAuth();
  const { session } = valuesSession();

  // const formFiltro = GetForm();

  const [filtro, setFiltro] = useState<any>({});
  const [lojaFiltroId, setLojaFiltroId] = useState<string>(
    String(loja?.id_loja ?? "*")
  );

  const isBancoLiberadoParaLoja = (banco: any) => {
    if (String(banco?.status_inst_bancaria) == "0") {
      return false;
    }

    const codLojas = String(banco?.codLojas_inst_bancaria ?? "").trim();
    if (codLojas == "*") {
      return true;
    }

    const lojaId = String(loja?.id_loja ?? "").trim();
    if (!lojaId) {
      return false;
    }

    return codLojas
      .split(/[;,]/)
      .map((v: string) => v.trim())
      .filter(Boolean)
      .includes(lojaId);
  };

  const isContaDaLoja = (conta: any, lojaIdFiltro?: string | number) => {
    const lojaId = String(lojaIdFiltro ?? loja?.id_loja ?? "").trim();
    if (!lojaId) {
      return false;
    }

    const lojasConta = String(conta?.loja_conta_loja ?? "").trim();
    if (!lojasConta) {
      return false;
    }

    if (lojasConta == "*") {
      return true;
    }

    return lojasConta
      .split(/[;,]/)
      .map((v: string) => v.trim())
      .filter(Boolean)
      .includes(lojaId);
  };

  const parseLojasConta = (lojaContaValue: any): string[] => {
    const raw = String(lojaContaValue ?? "").trim();
    if (!raw) {
      return [];
    }

    if (raw == "*") {
      return ["*"];
    }

    return raw
      .split(/[;,]/)
      .map((v: string) => v.trim())
      .filter(Boolean);
  };

  const editarContaComValidacao = async (data: any) => {
    const isContaPadraoDaLoja =
      String(cod_conta_padrao_loja) == String(data?.id_conta_loja);

    if (isContaPadraoDaLoja) {
      const lojaAtualId = String(loja?.id_loja ?? "").trim();
      const lojasConta = parseLojasConta(data?.loja_conta_loja);
      const lojaAindaVinculada =
        lojasConta.includes("*") || lojasConta.includes(lojaAtualId);

      if (!lojaAindaVinculada) {
        handleSweetAlert({
          icon: "warning",
          title: "Conta padrão da loja",
          html: "Não é permitido remover esta loja de uma conta que está marcada como padrão.",
          showDenyButton: false,
          confirmButtonText: "Ok",
        });
        return Promise.resolve();
      }
    }

    return editarContaBancariaLoja(data);
  };

  const listarContasDaLoja = async (...args: any[]) => {
    const response = await listarContasBancariasLojas(...args);
    const filtroLoja = String(lojaFiltroId ?? "*").trim();
    const deveFiltrarPorLoja = filtroLoja != "*";

    const filtrarConta = (conta: any) =>
      !deveFiltrarPorLoja || isContaDaLoja(conta, filtroLoja);

    if (Array.isArray(response)) {
      return response.filter((conta: any) => filtrarConta(conta));
    }

    if (Array.isArray(response?.body)) {
      return {
        ...response,
        body: response.body.filter((conta: any) => filtrarConta(conta)),
      };
    }

    return response;
  };

  useEffect(() => {
    if (loja?.id_loja) {
      setLojaFiltroId(String(loja.id_loja));
    }
  }, [loja?.id_loja]);

  function filtrarPorMultiSelecao(
    row: any,
    columnId: string,
    filterValue: any[]
  ) {
    if (!row.original[columnId]) {
      return true;
    }

    if (
      filterValue?.length == 0 ||
      filterValue.some(
        (optionSelected) =>
          optionSelected.value == "*" ||
          optionSelected.label == row.original[columnId]
      )
    ) {
      return true;
    }

    return false;
  }

  function filtrarPorTexto(row: any, columnId: string, filterValue: string) {
    if (!row.original[columnId]) {
      return true;
    }

    if (
      filterValue == "" ||
      filterValue == "*" ||
      filterValue == "Todos" ||
      filterValue == row.original[columnId]
    ) {
      return true;
    }

    return false;
  }

  const columns = [
    // {
    //   header: "Código",
    //   accessorKey: "id_conta_loja",
    // },
    {
      header: "Tipo da Conta",
      accessorKey: "tipo_conta_loja",
      filterFn: filtrarPorTexto,
    },
    {
      header: "CPF/CNPJ",
      accessorKey: "cpf_cnjp_conta_loja",
    },
    {
      header: "Nome Quem Está na Conta",
      accessorKey: "nome_responsavel_conta_loja",
    },
    {
      header: "Instituição Financeira",
      accessorKey: "cod_inst_bancaria_conta_loja",
      filterFn: filtrarPorTexto,
    },
    {
      header: "Agência",
      accessorKey: "nrAgencia_conta_loja",
    },
    {
      header: "Número Conta",
      accessorKey: "numero_conta_loja",
    },
    {
      header: "Tipo Chave Pix",
      accessorKey: "tipoChavePix_conta_loja",
      filterFn: filtrarPorTexto,
    },
    {
      header: "Chave Pix",
      accessorKey: "chavePix_conta_loja",
    },
    {
      header: "Nome Recebedor do Pix",
      accessorKey: "nome_recebedor_pix_conta_loja",
    },
    {
      header: "Lojas Vinculadas",
      accessorKey: "loja_conta_loja",
      filterFn: filtrarPorTexto,
    },
  ];

  useEffect(() => {
    Promise.all([
      listarLojas(session.id_usuario).then(setLojas),
      listarInstBancarias().then(setInstBancarias),
    ]).finally(() => setIsLoaded(true));
  }, []);

  async function formatarLista(arr: any[]) {
    return arr.map((e) => {
      e["isContaPadrao"] = cod_conta_padrao_loja == e?.id_conta_loja;
      const banco = instBancarias?.find(
        (banco) => banco.id_inst_bancaria == e["cod_inst_bancaria_conta_loja"]
      );
      e["cod_inst_bancaria_conta_loja"] =
        `${banco?.codCompensacao_inst_bancaria ? `${banco?.codCompensacao_inst_bancaria} - ` : ""}${banco?.nome_inst_bancaria}`;
      e["tipoChavePix_conta_loja"] = tiposChavePix?.find(
        (tipo) => tipo.value == e?.tipoChavePix_conta_loja
      )?.label;

      e["tipo_conta_loja"] = tiposPessoas?.find(
        (tipo) => tipo?.value == e?.tipo_conta_loja
      )?.label;

      const lojasContaRaw = String(e?.loja_conta_loja ?? "").trim();
      if (lojasContaRaw == "*") {
        e["loja_conta_loja"] = "Todas";
      } else if (lojasContaRaw) {
        const ids = lojasContaRaw
          .split(/[;,]/)
          .map((v: string) => v.trim())
          .filter(Boolean);

        const nomesLojas = ids
          .map((idLoja: string) => {
            const lojaEncontrada = lojas?.find(
              (lojaItem: any) => String(lojaItem?.id_loja) == idLoja
            );
            return lojaEncontrada?.nome_loja || idLoja;
          })
          .join(", ");

        e["loja_conta_loja"] = nomesLojas || "-";
      } else {
        e["loja_conta_loja"] = "-";
      }

      return e;
    });
  }

  const CustomForm = useCallback(
    (props: any) => (
      <FormContaBancariaLoja
        {...props}
        loja={loja}
        lojas={lojas}
        instBancarias={instBancarias}
        tiposChavePix={tiposChavePix}
        tiposPessoas={tiposPessoas}
      />
    ),
    [lojas, instBancarias]
  );

  const lojaSelecionadaNoFiltro = lojas.find(
    (lojaItem: any) => String(lojaItem.id_loja) == String(lojaFiltroId)
  );

  return (
    <>
      <h2 className="text-xl max-sm:text-sm font-bold mb-4">
        Cadastro de Conta da Loja
      </h2>
      <div className="flex flex-col gap-2">
        {isLoaded ? (
          <div>
            <div className="flex flex-row flex-wrap gap-3 mb-4">
              <InputSelectComponent
                name="filtro_loja_conta_loja"
                label="Loja"
                options={[
                  { label: "Todas", value: "*" },
                  ...lojas.map((lojaItem: any) => ({
                    label: lojaItem.nome_loja,
                    value: String(lojaItem.id_loja),
                  })),
                ]}
                defaultValue={
                  lojaSelecionadaNoFiltro
                    ? {
                        label: lojaSelecionadaNoFiltro?.nome_loja,
                        value: String(lojaFiltroId),
                      }
                    : undefined
                }
                width="min-w-[220px] flex-1"
                onChange={(e: any) => {
                  setLojaFiltroId(String(e?.value ?? "*"));
                  setTableKey((prev) => prev + 1);
                }}
              />
              <InputSelectComponent
                name="tipo_conta_loja"
                label="Tipo da Conta"
                options={[
                  { label: "Todos", value: "*" },
                  ...tiposPessoas?.map((data) => ({
                    ...data,
                    value: data.label,
                  })),
                ]}
                width="min-w-[190px] flex-1"
                onChange={(e: any) => {
                  setFiltro((prev: any) => ({
                    ...prev,
                    tipo_conta_loja: e?.value,
                  }));
                  setTableKey((prev) => prev + 1);
                }}
              />
              <InputSelectComponent
                name="cod_inst_bancaria_conta_loja"
                label="Instituição Financeira"
                options={[
                  { label: "Todos", value: "*" },
                  ...instBancarias
                    ?.filter((banco: any) => isBancoLiberadoParaLoja(banco))
                    ?.sort(
                      (a: any, b: any) =>
                        a?.codCompensacao_inst_bancaria -
                        b?.codCompensacao_inst_bancaria
                    )
                    .map((banco: any) => ({
                      // value: banco.id_inst_bancaria,
                      label: `${banco.codCompensacao_inst_bancaria ? `${banco.codCompensacao_inst_bancaria} - ` : ""}${banco.nome_inst_bancaria}`,
                      value: `${banco.codCompensacao_inst_bancaria ? `${banco.codCompensacao_inst_bancaria} - ` : ""}${banco.nome_inst_bancaria}`,
                    })),
                ]}
                width="min-w-[190px] flex-1"
                onChange={(e: any) => {
                  setFiltro((prev: any) => ({
                    ...prev,
                    cod_inst_bancaria_conta_loja: e?.value,
                  }));
                  setTableKey((prev) => prev + 1);
                }}
              />
              <InputSelectComponent
                name="tipoChavePix_conta_loja"
                label="Tipo Chave Pix"
                options={[
                  { label: "Todos", value: "*" },
                  ...tiposChavePix?.map((data) => ({
                    ...data,
                    value: data.label,
                  })),
                ]}
                width="min-w-[190px] flex-1"
                onChange={(e: any) => {
                  setFiltro((prev: any) => ({
                    ...prev,
                    tipoChavePix_conta_loja: e?.value,
                  }));
                  setTableKey((prev) => prev + 1);
                }}
              />
            </div>
            <ReactTable
              columns={columns}
              createFunction={cadastrarContaBancariaLoja}
              listFunction={listarContasDaLoja}
              formatFunction={formatarLista}
              idCol="id_conta_loja"
              // isActiveCol="status_inst_bancaria"
              canEdit
              // canDesactive
              editFunction={editarContaComValidacao}
              Form={CustomForm}
              pageName="Conta da Loja"
              filters={filtro}
              manualFilters
              // columnFilters={filtro}
              key={tableKey}
              actionButtons={(
                rowData: any,
                updateTable: any,
                setIsLoading: any,
                {
                  idCol,
                  isActive,
                  isActiveCol,
                  pageName,
                  editFunction,
                  listData,
                  rowOriginal,
                }
              ) => [
                (() => {
                  const contaPertenceLoja = isContaDaLoja(
                    rowOriginal || rowData
                  );
                  const isContaPadrao =
                    cod_conta_padrao_loja == rowData?.id_conta_loja;

                  return {
                    className: `navButton ${isContaPadrao ? "buttonSuccess" : "buttonDanger"} transition-all duration-300`,
                    onClick: (e: any) => {
                      if (!contaPertenceLoja) {
                        handleSweetAlert({
                          icon: "warning",
                          title: "Conta não pertence à loja",
                          html: "Esta conta não está vinculada à loja atual e não pode ser definida como padrão.",
                          showDenyButton: false,
                          confirmButtonText: "Ok",
                        });
                        return;
                      }

                      if (isContaPadrao) {
                        return;
                      }

                      handleSweetAlert(
                        {
                          icon: "warning",
                          title: `Setar Conta Padrão`,
                          html: `Tem certeza que deseja setar esta conta como a padrão dessa loja?`,
                        },
                        async () => {
                          return editarLoja({
                            id_loja: loja?.id_loja,
                            cod_conta_padrao_loja: rowData[idCol],
                          }).then(() => {
                            setCod_conta_padrao_loja(rowData[idCol]);
                            formLoja.setValue(
                              "cod_conta_padrao_loja",
                              rowData[idCol]
                            );
                            updateTable();
                          });
                        }
                      );
                    },
                    content: !contaPertenceLoja ? (
                      <Tooltip title="Conta não pertence a esta loja">
                        <MdWarning size={21} />
                      </Tooltip>
                    ) : isContaPadrao ? (
                      <Tooltip title="É a conta padrão">
                        <SquareCheckBig size={21} />
                      </Tooltip>
                    ) : (
                      <Tooltip title="Setar conta como padrão">
                        <Square size={21} />
                      </Tooltip>
                    ),
                  };
                })(),
                {
                  className:
                    "navButton buttonDanger transition-all duration-300",
                  title: "Excluir conta",
                  onClick: () => {
                    const isContaPadrao =
                      cod_conta_padrao_loja == rowData?.id_conta_loja;

                    if (isContaPadrao) {
                      handleSweetAlert({
                        icon: "warning",
                        title: "Conta padrão da loja",
                        html: "Não é permitido excluir a conta padrão da loja atual.",
                        showDenyButton: false,
                        confirmButtonText: "Ok",
                      });
                      return;
                    }

                    handleSweetAlert(
                      {
                        icon: "question",
                        title: "Excluir conta",
                        html: "Tem certeza que deseja excluir esta conta da instituição financeira?",
                      },
                      async () => {
                        await deletarContaBancariaLoja({
                          id_conta_loja: rowData[idCol],
                          id_usuario: session.id_usuario,
                        });
                        return updateTable();
                      }
                    );
                  },
                  content: (
                    <Tooltip title="Excluir conta">
                      <BiTrash size={20} />
                    </Tooltip>
                  ),
                },
              ]}
            />
          </div>
        ) : (
          <div className="flex justify-center w-full">
            <LoaderSun />
          </div>
        )}
      </div>
    </>
  );
}
