import Button from "@/components/Forms/Button";
import Input from "@/components/Forms/Input";
import {
  Table,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { useEffect, useMemo, useState } from "react";
import {
  CAMPO_PENDENCIA_TIPO,
  encodePendenciaTipo,
  montarAbasLinhaPendencias,
  parsePendenciaTipo,
  tiposPorPermissao,
} from "@/utils/permissoesLinhaPendencias";

// Menu "d. Linha Pendências": uma aba por tipo de negócio cadastrado e, dentro
// da aba, as permissões das pendências liberadas para aquele tipo. A numeração
// ("d1", "d2" ...) reinicia em cada aba - vem de montarAbasLinhaPendencias.
//
// O que é gravado:
// - coluna booleana da permissão em `perfis`: ligada se algum tipo de negócio
//   estiver marcado (a checagem em runtime ainda é global);
// - CAMPO_PENDENCIA_TIPO: o detalhe "permissao:idTipo" de cada marcação.
const TabelaLinhaPendencias = ({
  defaultValues,
  disabledFields,
  children,
  form,
  storageKey,
  tiposNegocios,
  pendencias,
  pendenciasPorTiposNegocios,
  linhaPendencias,
  permissoesCadastradas,
}: any) => {
  const [isLoaded, setIsLoaded] = useState(false);
  // Booleano global por permissão (coluna em `perfis`).
  const [checkedValues, setCheckedValues] = useState<Record<string, boolean>>(
    {},
  );
  // Tipos de negócio marcados por permissão (independentes entre si).
  const [checkedTipos, setCheckedTipos] = useState<Record<string, string[]>>(
    {},
  );
  const [abaAtiva, setAbaAtiva] = useState<string | null>(null);

  const storageKeyTipos = `${storageKey}_tipos`;

  const abas = useMemo(
    () =>
      montarAbasLinhaPendencias({
        tiposNegocios,
        pendencias,
        pendenciasPorTiposNegocios,
        linhaPendencias,
        permissoesCadastradas,
      }),
    [
      tiposNegocios,
      pendencias,
      pendenciasPorTiposNegocios,
      linhaPendencias,
      permissoesCadastradas,
    ],
  );
  const tiposDaPermissao = useMemo(() => tiposPorPermissao(abas), [abas]);

  const abaSelecionada =
    abas.find((aba) => aba.idTipo === abaAtiva) ?? abas[0] ?? null;

  useEffect(() => {
    const todasPermissoes = Array.from(
      new Set(
        abas.flatMap((aba) => aba.permissoes.map((permissao) => permissao.value)),
      ),
    );

    // Valores globais: defaultValues do perfil como base e o localStorage
    // (escrito pelas outras abas) por cima - a visão "Gerenciar Todas
    // Permissões" grava só as permissões que o usuário mexeu, então o merge
    // evita perder o valor original das demais.
    const base = todasPermissoes.reduce(
      (acc, value) => {
        acc[value] = defaultValues && defaultValues[value] === "1";
        return acc;
      },
      {} as Record<string, boolean>,
    );
    const storedValues = localStorage.getItem(storageKey);
    const globais = {
      ...base,
      ...(storedValues ? JSON.parse(storedValues) : {}),
    } as Record<string, boolean>;
    setCheckedValues(globais);

    // Detalhe por tipo - localStorage ou o campo codificado do perfil.
    const storedTipos = localStorage.getItem(storageKeyTipos);
    const detalhe = storedTipos
      ? (JSON.parse(storedTipos) as Record<string, string[]>)
      : parsePendenciaTipo(defaultValues?.[CAMPO_PENDENCIA_TIPO]);

    // Reconcilia com o global: se a permissão está ligada mas não há detalhe
    // por tipo (ex.: perfil antigo ou vindo de predefinição), assume todos os
    // tipos em que ela aparece. Se está desligada, nenhum tipo.
    const inicialTipos: Record<string, string[]> = {};
    Object.entries(tiposDaPermissao).forEach(([value, todosIds]) => {
      if (!globais[value]) {
        inicialTipos[value] = [];
        return;
      }
      const marcados = detalhe[value];
      inicialTipos[value] = marcados
        ? marcados.filter((idTipo) => todosIds.includes(idTipo))
        : todosIds;
    });
    setCheckedTipos(inicialTipos);
    setIsLoaded(true);
  }, [defaultValues, abas]);

  useEffect(() => {
    if (!isLoaded) return;
    localStorage.setItem(storageKey, JSON.stringify(checkedValues));
  }, [checkedValues, isLoaded]);

  useEffect(() => {
    if (!isLoaded) return;
    localStorage.setItem(storageKeyTipos, JSON.stringify(checkedTipos));
    form.setValue(CAMPO_PENDENCIA_TIPO, encodePendenciaTipo(checkedTipos));
  }, [checkedTipos, isLoaded]);

  // Aba "Sem Tipo de Negócio": a permissão não tem detalhe por tipo, então vale
  // o booleano global direto.
  const setPermissaoGlobal = (value: string, marcado: boolean) => {
    form.setValue(value, marcado ? "1" : "0");
    setCheckedValues((prev) => ({ ...prev, [value]: marcado }));
  };

  // Aplica a lista de tipos marcados de uma permissão e mantém o booleano
  // global (coluna permValue) em sincronia = "ligado" se houver algum tipo.
  const aplicarTipos = (value: string, novosTipos: string[]) => {
    setCheckedTipos((prev) => ({ ...prev, [value]: novosTipos }));
    const ligado = novosTipos.length > 0;
    form.setValue(value, ligado ? "1" : "0");
    setCheckedValues((prev) => ({ ...prev, [value]: ligado }));
  };

  const toggleTipo = (value: string, idTipo: string, marcado: boolean) => {
    const atual = checkedTipos[value] || [];
    aplicarTipos(
      value,
      marcado
        ? Array.from(new Set([...atual, idTipo]))
        : atual.filter((tipo) => tipo !== idTipo),
    );
  };

  // Marcar / Desmarcar Todos atua somente na aba visível, para não mexer nos
  // outros tipos de negócio sem o usuário ver.
  const marcarAba = (marcado: boolean) => {
    if (!abaSelecionada) return;
    const values = abaSelecionada.permissoes.map((permissao) => permissao.value);

    if (!abaSelecionada.idTipo) {
      values.forEach((value) => form.setValue(value, marcado ? "1" : "0"));
      setCheckedValues((prev) => ({
        ...prev,
        ...Object.fromEntries(values.map((value) => [value, marcado])),
      }));
      return;
    }

    const idTipo = abaSelecionada.idTipo;
    const nextTipos = { ...checkedTipos };
    const nextValues = { ...checkedValues };
    values.forEach((value) => {
      const atual = nextTipos[value] || [];
      nextTipos[value] = marcado
        ? Array.from(new Set([...atual, idTipo]))
        : atual.filter((tipo) => tipo !== idTipo);
      nextValues[value] = nextTipos[value].length > 0;
      form.setValue(value, nextValues[value] ? "1" : "0");
    });
    setCheckedTipos(nextTipos);
    setCheckedValues(nextValues);
  };

  const estaMarcada = (value: string) =>
    abaSelecionada?.idTipo
      ? (checkedTipos[value] || []).includes(abaSelecionada.idTipo)
      : checkedValues[value] || false;

  if (!abaSelecionada) {
    return (
      <div className="py-8 text-center text-sm text-gray-500">
        Nenhuma pendência com permissão vinculada a tipo de negócio.
      </div>
    );
  }

  return (
    <div>
      {/* Uma aba por tipo de negócio; a numeração reinicia em cada uma. */}
      <div className="mb-4 flex flex-wrap gap-2 border-b border-gray-200 dark:border-strokedark">
        {abas.map((aba) => {
          const ativa = aba.idTipo === abaSelecionada.idTipo;
          return (
            <button
              key={aba.idTipo || "sem-tipo"}
              type="button"
              onClick={() => setAbaAtiva(aba.idTipo)}
              className={`-mb-px rounded-t-md border border-b-0 px-3 py-2 text-sm transition-colors ${
                ativa
                  ? "border-gray-200 bg-white font-semibold text-primary dark:border-strokedark dark:bg-boxdark dark:text-white"
                  : "border-transparent text-gray-500 hover:text-primary dark:text-gray-400"
              }`}
            >
              {aba.nome}
            </button>
          );
        })}
      </div>

      <Table className="min-w-full bg-white dark:bg-[#1d2a39] border border-gray-300 shadow-sm">
        <TableHeader>
          <TableRow>
            <TableHead className="font-bold py-2 px-4 border-b text-center">
              Nome
            </TableHead>
            <TableHead className="font-bold py-2 px-4 border-b text-end">
              Acesso
            </TableHead>
          </TableRow>
        </TableHeader>
        <tbody>
          <TableRow>
            <TableCell className="py-2 text-center">
              <div className="flex justify-center gap-2">
                <Button
                  type="button"
                  className="bg-meta-1 flex-1 py-1 px-2 text-sm"
                  onClick={() => marcarAba(false)}
                >
                  Desmarcar Todos
                </Button>
                <Button
                  type="button"
                  className="flex-1 py-1 px-2 text-sm"
                  onClick={() => marcarAba(true)}
                >
                  Marcar Todos
                </Button>
              </div>
            </TableCell>
          </TableRow>

          <TableRow>
            <TableCell colSpan={2} className="bg-black-2/5 font-bold">
              {abaSelecionada.nome}
            </TableCell>
          </TableRow>

          {abaSelecionada.permissoes.map((permissao) => (
            <TableRow key={permissao.value}>
              <TableCell className="py-2 text-left">{permissao.label}</TableCell>
              <TableCell fullWidth={true} className="py-2 text-center">
                <Input
                  type="checkbox"
                  name={permissao.value}
                  checked={estaMarcada(permissao.value)}
                  onChange={(e) =>
                    abaSelecionada.idTipo
                      ? toggleTipo(
                          permissao.value,
                          abaSelecionada.idTipo,
                          e.target.checked,
                        )
                      : setPermissaoGlobal(permissao.value, e.target.checked)
                  }
                  disabled={disabledFields?.some(
                    (field: any) => field === permissao.value,
                  )}
                />
              </TableCell>
            </TableRow>
          ))}
        </tbody>
      </Table>

      {children}
    </div>
  );
};

export default TabelaLinhaPendencias;
