import Button from "@/components/Forms/Button";
import {
  listaAutomacao,
  listarAcoesNotificacoes,
  listarNotificacoesAutomatizadas,
} from "@/requests/CRUD/Notificacoes/listarNotificacoes";

import { handleSweetAlert } from "@/components/Modal/SweetAlertConfirm";
import {
  CAMPO_MODELO_POR_CANAL,
  paraListaDeCanais,
  valorDeSelect,
} from "@/constants/modeloNotificacao";
import { Desc_TipoNotificacaoCanal } from "@/enums/enums";
import { listarUsuario } from "@/requests/CRM/agenda";
import { cadastrarNotificacaoAutomatizada } from "@/requests/CRUD/Notificacoes/cadastrarNotificacao";
import { editarNotificacaoAutomatizada } from "@/requests/CRUD/Notificacoes/editarNotificacao";
import { listarModeloEmail } from "@/requests/CRUD/ModelosEmail/listarModeloEmail";
import { deletarAutomatizacao } from "@/requests/CRUD/Notificacoes/removerNotificacao";
import { useEffect, useState } from "react";
import { MdAdd, MdClose } from "react-icons/md";
import CardNotificacaoAutomatizada from "./CardNotificacaoAutomatizada";
import FormNotificacao from "./FormNotificacao";

const COLUNAS_GRID = [
  "Ações",
  "ID",
  "Ação Notificada",
  "Canais",
  "Responsáveis Notificados",
  "Contato do Projeto",
  "Outros Usuários",
  "Modelos de Notificação",
  "Status",
];

const NotificacaoComponent = () => {
  const [isLoading, setIsLoading] = useState(false);
  const [notificacoesAutomatizadas, setNotificacoesAutomatizadas] = useState<
    any[]
  >([]);
  const [formAberto, setFormAberto] = useState(false);

  const [usuarios, setdadosUsuarios] = useState<any[]>([]);
  const [automatizacao, setAutomatizacao] = useState<any[]>([]);
  const [acoes, setAcoes] = useState<any[]>([]);
  const [modelosNotificacao, setModelosNotificacao] = useState<any[]>([]);

  useEffect(() => {
    listarAcoesNotificacoes().then((res) => setAcoes(res));
    listarUsuario().then((res: any) => setdadosUsuarios(res));
    listarModeloEmail().then(setModelosNotificacao);
    atualizarListaAutomatizacoes();
  }, []);

  const atualizarListaAutomatizacoes = () => {
    listarNotificacoesAutomatizadas().then((res: any) =>
      setNotificacoesAutomatizadas(res ?? [])
    );
    listaAutomacao().then((res) => setAutomatizacao(res));
  };

  // Os selects entregam a option inteira (ou a lista de options, quando isMulti);
  // o back-end grava o value — ou o CSV de values, no caso dos múltiplos.
  const normalizarPayload = (data: any) =>
    Object.keys(data).reduce(
      (acc: any, campo: string) => ({
        ...acc,
        [campo]: valorDeSelect(data[campo]),
      }),
      {}
    );

  const avisar = (title: string, html: string) => {
    handleSweetAlert({
      icon: "warning",
      title,
      html,
      showDenyButton: false,
      confirmButtonText: "Ok",
    });
    return false;
  };

  /**
   * Item 03: a notificação só é salva com pelo menos um canal e com o Modelo
   * de Notificação de cada canal escolhido. Os campos de modelo são montados
   * conforme o canal, por isso a checagem fica aqui e não no schema do yup.
   */
  const notificacaoValida = (payload: any) => {
    const canais = paraListaDeCanais(payload.tipo_notificacao_canal);

    if (canais.length === 0) {
      return avisar(
        "Informe o Canal de Notificação",
        "Selecione ao menos um canal para esta notificação."
      );
    }

    const canaisSemModelo = canais.filter(
      (canal) => !payload[CAMPO_MODELO_POR_CANAL[canal]]
    );

    if (canaisSemModelo.length > 0) {
      return avisar(
        "Informe o Modelo de Notificação",
        `Selecione o modelo para: ${canaisSemModelo
          .map((canal) => (Desc_TipoNotificacaoCanal as any)[canal])
          .join(", ")}.`
      );
    }

    return true;
  };

  const onSubmitFunction = async (data: any) => {
    const payload = normalizarPayload(data);
    if (!notificacaoValida(payload)) return undefined;

    setIsLoading(true);

    return cadastrarNotificacaoAutomatizada(payload)
      .then((resultado) => {
        setFormAberto(false);
        return resultado ?? true;
      })
      .finally(() => {
        atualizarListaAutomatizacoes();
        setIsLoading(false);
      });
  };

  // Salva a edição feita no grid. Devolve `undefined` quando a validação barra o
  // envio, para que o card não feche o modal achando que salvou.
  const editarAutomacao = async (data: any) => {
    const payload = normalizarPayload(data);
    if (!notificacaoValida(payload)) return undefined;

    setIsLoading(true);
    return editarNotificacaoAutomatizada(payload)
      .then((resultado) => resultado ?? true)
      .finally(() => {
        atualizarListaAutomatizacoes();
        setIsLoading(false);
      });
  };

  // Habilitar/Desabilitar envia apenas o status: não passa pela validação de
  // canais/modelos, que só se aplica ao formulário completo.
  const alternarStatusAutomacao = async (payload: any) => {
    setIsLoading(true);
    return editarNotificacaoAutomatizada(payload).finally(() => {
      atualizarListaAutomatizacoes();
      setIsLoading(false);
    });
  };

  const removerAutomatizacao = async (id_automatizacao: any) => {
    setIsLoading(true);
    return deletarAutomatizacao({ id_automatizacao }).finally(() => {
      atualizarListaAutomatizacoes();
      setIsLoading(false);
    });
  };

  // As ações marcadas com configuravel_central_acao_notificacao = 0 são
  // configuradas dentro da ETAPA (item 06) e por isso não entram aqui.
  const acoesDisponiveis = acoes.filter(
    (acao: any) =>
      acao.configuravel_central_acao_notificacao?.toString() !== "0" &&
      !notificacoesAutomatizadas.some(
        (notificacao: any) =>
          notificacao.acao_automatizacao_notificacao == acao.id_acao_notificacao
      )
  );

  return (
    <div className="flex flex-col gap-4">
      <div className="flex flex-row items-center justify-between gap-2">
        <p className="text-sm text-black-2/60 dark:text-white/60">
          Defina quem é notificado, por quais canais e com qual Modelo de
          Notificação em cada ação do sistema.
        </p>
        <Button
          type="button"
          className="w-fit whitespace-nowrap text-sm"
          disabled={!formAberto && acoesDisponiveis.length === 0}
          onClick={() => setFormAberto((aberto) => !aberto)}
        >
          <span className="flex flex-row items-center gap-1">
            {formAberto ? <MdClose size={16} /> : <MdAdd size={16} />}
            {formAberto ? "Cancelar" : "Nova Notificação"}
          </span>
        </Button>
      </div>

      {formAberto && (
        <div className="rounded-md border border-stroke p-4 dark:border-strokedark">
          <FormNotificacao
            onSubmitFunction={onSubmitFunction}
            automatizacao={automatizacao}
            acoes={acoes}
            usuarios={usuarios}
            notificacoesAutomatizadas={notificacoesAutomatizadas}
          >
            <div className="flex w-full flex-row justify-center p-4">
              <Button className="w-29 text-sm" loading={isLoading}>
                Salvar
              </Button>
            </div>
          </FormNotificacao>
        </div>
      )}

      <div className="min-h-[200px] overflow-x-auto rounded-md bg-body bg-opacity-10">
        {notificacoesAutomatizadas.length > 0 ? (
          <table className="w-full min-w-[1000px] text-sm">
            <thead>
              <tr className="bg-body bg-opacity-20 dark:bg-graydark">
                {COLUNAS_GRID.map((coluna) => (
                  <th key={coluna} className="p-2 text-left font-semibold">
                    {coluna}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {notificacoesAutomatizadas?.map((notificacaoAuto, index) => {
                const acaoAtual = automatizacao.find(
                  (notificacaoAtual: any) =>
                    notificacaoAuto.id_automatizacao_notificacao ===
                    notificacaoAtual.id_automatizacao_notificacao
                );

                return (
                  <CardNotificacaoAutomatizada
                    key={notificacaoAuto.id_automatizacao_notificacao ?? index}
                    acaoAtual={acaoAtual}
                    notificacaoAuto={notificacaoAuto}
                    removerAutomatizacao={removerAutomatizacao}
                    editarAutomacao={editarAutomacao}
                    alternarStatusAutomacao={alternarStatusAutomacao}
                    usuarios={usuarios}
                    modelosNotificacao={modelosNotificacao}
                    isLoading={isLoading}
                    indexCard={index}
                  />
                );
              })}
            </tbody>
          </table>
        ) : (
          <div className="flex h-full w-full flex-col items-center justify-center self-center p-8">
            Não há notificações Configuradas
          </div>
        )}
      </div>
    </div>
  );
};

export default NotificacaoComponent;
