"use client";

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { getSupabaseClient } from "@/lib/supabase";
import { AlertTriangle, ArrowRight, BellOff, RotateCcw, X } from "lucide-react";
import { aviso } from "./aviso";

export type Alerta = {
  tipo: string;
  gravidade: "critico" | "atencao";
  titulo: string;
  detalhe: string | null;
  origem_id: string | null;
  quando: string | null;
  rota: string;
};

/**
 * Alertas que cruzam modulos.
 *
 * Ficam atras de um icone com contador, e nao abertos na tela. Uma parede de
 * avisos vermelhos toda vez que a agenda abre ensina a pessoa a passar os
 * olhos por cima — e ai o aviso que importava se perde junto.
 *
 * O contador some quando nao ha nada: botao aceso sem motivo vira ruido.
 *
 * Nao ha "marcar como lido": cada aviso e uma leitura do estado real, entao
 * ele sai da lista quando o pedido e entregue ou a conta e paga — na tela de
 * origem, que e onde a mudanca vale. Por isso cada item leva para la, dizendo
 * o que resolver. Para o caso de "ja sei disso, some por uns dias" existe o
 * silenciar, que nao mente sobre o dado: e prazo, nao baixa.
 */
export default function Alertas() {
  const [itens, setItens] = useState<Alerta[]>([]);
  const [aberto, setAberto] = useState(false);
  const [ocupado, setOcupado] = useState<string | null>(null);
  const [temSilenciado, setTemSilenciado] = useState(false);

  const buscar = useCallback(async () => {
    const supabase = getSupabaseClient();

    try {
      const { data } = await supabase.rpc("get_agenda_alertas");
      setItens((data as Alerta[]) ?? []);
    } catch {
      setItens([]);
    }

    /* Bloco proprio: a contagem de silenciados so decide se aparece o botao
       de trazer de volta. Junto do outro, uma falha aqui derrubava a lista de
       avisos inteira — o `catch` zerava tudo. */
    try {
      const { count } = await supabase
        .from("agenda_alert_dismissals")
        .select("id", { count: "exact", head: true })
        .gt("dispensado_ate", new Date().toISOString());
      setTemSilenciado((count ?? 0) > 0);
    } catch {
      setTemSilenciado(false);
    }
  }, []);

  const chaveDe = (a: Alerta) => `${a.tipo}|${a.origem_id ?? ""}|${a.quando ?? ""}`;

  const silenciar = async (a: Alerta) => {
    const chave = chaveDe(a);
    setOcupado(chave);
    /* Some da lista antes da resposta: esperar o servidor para o item sumir
       faz o botao parecer quebrado. Se falhar, a busca devolve o item. */
    setItens((atual) => atual.filter((x) => chaveDe(x) !== chave));
    try {
      const supabase = getSupabaseClient();
      const { error } = await supabase.rpc("dispensar_alerta_agenda", {
        p_tipo: a.tipo,
        p_origem_id: a.origem_id,
        p_quando: a.quando,
        p_dias: 7,
      });
      if (error) throw new Error(error.message);
      setTemSilenciado(true);
      aviso.sucesso("Silenciado por 7 dias", {
        descricao: "Volta para a lista se continuar pendente.",
      });
    } catch {
      aviso.erro("Não foi possível silenciar.");
      buscar();
    } finally {
      setOcupado(null);
    }
  };

  const restaurar = async () => {
    try {
      const supabase = getSupabaseClient();
      const { error } = await supabase.rpc("restaurar_alertas_agenda");
      if (error) throw new Error(error.message);
      aviso.sucesso("Avisos restaurados", { descricao: "Tudo que estava silenciado voltou." });
      buscar();
    } catch {
      aviso.erro("Não foi possível restaurar.");
    }
  };

  useEffect(() => {
    buscar();
  }, [buscar]);

  useEffect(() => {
    if (!aberto) return;
    const aoTeclar = (e: KeyboardEvent) => e.key === "Escape" && setAberto(false);
    window.addEventListener("keydown", aoTeclar);
    const antes = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", aoTeclar);
      document.body.style.overflow = antes;
    };
  }, [aberto]);

  /* Some por completo so quando nao ha aviso nem nada silenciado: com algo
     escondido, o botao precisa continuar la para dar o caminho de volta. */
  if (itens.length === 0 && !temSilenciado) return null;

  const criticos = itens.filter((a) => a.gravidade === "critico").length;

  return (
    <>
      <button
        type="button"
        onClick={() => setAberto(true)}
        aria-label={`${itens.length} pontos de atenção`}
        className="relative flex h-11 w-11 shrink-0 items-center justify-center rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] text-[var(--ag-text-2)] transition-colors hover:border-[var(--ag-border-strong)] hover:bg-[var(--ag-surface-2)] sm:h-9 sm:w-9"
      >
        <AlertTriangle
          className={`h-[16px] w-[16px] ${
            itens.length === 0 ? "text-[var(--ag-text-5)]" : criticos ? "text-rose-500" : "text-amber-500"
          }`}
        />
        {itens.length > 0 && (
          <span
            className={`absolute -right-1 -top-1 flex h-5 min-w-[20px] items-center justify-center rounded-full px-1 text-[10px] font-semibold text-white ${
              criticos ? "bg-rose-500" : "bg-amber-500"
            }`}
          >
            {itens.length}
          </span>
        )}
      </button>

      {aberto && (
        <div className="fixed inset-0 z-[60] flex items-end justify-center sm:items-center">
          <button
            type="button"
            aria-label="Fechar"
            onClick={() => setAberto(false)}
            className="absolute inset-0 bg-slate-900/40 backdrop-blur-[3px]"
          />
          <div
            role="dialog"
            aria-modal="true"
            aria-label="Pontos de atenção"
            className="relative flex max-h-[85vh] w-full flex-col rounded-t-[28px] bg-[var(--ks-color-bg-body)] shadow-2xl sm:max-w-lg sm:rounded-[28px]"
          >
            <div className="mx-auto mt-3 h-1 w-10 shrink-0 rounded-full bg-[var(--ks-color-border-strong)] sm:hidden" />

            <div className="flex items-start justify-between gap-3 px-5 pb-3 pt-4">
              <div>
                <h2 className="text-lg font-black text-[var(--ks-color-text-primary)]">
                  Pontos de atenção
                </h2>
                <p className="text-xs text-[var(--ks-color-text-muted)]">
                  {itens.length === 0
                    ? "Nada pendente agora"
                    : criticos > 0
                      ? `${criticos} ${criticos === 1 ? "precisa" : "precisam"} de ação hoje`
                      : "Nada urgente por enquanto"}
                </p>
              </div>
              <button
                type="button"
                onClick={() => setAberto(false)}
                aria-label="Fechar"
                className="flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl text-[var(--ks-color-text-muted)] hover:bg-[var(--ks-color-bg-soft)]"
              >
                <X className="h-4 w-4" />
              </button>
            </div>

            {/* Explica de onde a lista vem: sem isso, "9 pontos de atenção"
                parece uma caixa de notificações que se marca como lida — e a
                pessoa procura um botão de limpar que não deveria existir. */}
            <p className="mx-4 mb-2 rounded-xl bg-[var(--ks-color-bg-soft)] px-3 py-2 text-[11px] leading-relaxed text-[var(--ks-color-text-muted)]">
              Cada aviso é lido da origem. Sai da lista sozinho quando o pedido for entregue ou a conta
              paga — <strong className="font-semibold">Resolver</strong> leva até lá. Use{" "}
              <strong className="font-semibold">Silenciar</strong> só para adiar por 7 dias.
            </p>

            <div className="min-h-0 flex-1 space-y-2 overflow-y-auto px-4 pb-5">
              {itens.length === 0 && (
                <p className="py-8 text-center text-[12.5px] text-[var(--ks-color-text-muted)]">
                  Nada pendente. Os avisos que você silenciou continuam guardados.
                </p>
              )}

              {itens.map((a, i) => {
                const chave = `${a.tipo}-${a.origem_id ?? i}-${a.quando ?? ""}`;
                const critico = a.gravidade === "critico";
                return (
                  <div
                    key={chave}
                    className={`rounded-2xl p-3 ${
                      critico ? "bg-rose-50 dark:bg-rose-500/10" : "bg-amber-50 dark:bg-amber-500/10"
                    }`}
                  >
                    <div className="flex items-start gap-3">
                      <span
                        className={`mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-xl ${
                          critico ? "bg-rose-500" : "bg-amber-500"
                        }`}
                      >
                        <AlertTriangle className="h-4 w-4 text-white" />
                      </span>
                      <div className="min-w-0 flex-1">
                        <p
                          className={`text-[13px] font-bold ${
                            critico
                              ? "text-rose-900 dark:text-rose-200"
                              : "text-amber-900 dark:text-amber-200"
                          }`}
                        >
                          {a.titulo}
                        </p>
                        {a.detalhe && (
                          <p
                            className={`text-[11px] ${
                              critico
                                ? "text-rose-700/80 dark:text-rose-300/80"
                                : "text-amber-700/80 dark:text-amber-300/80"
                            }`}
                          >
                            {a.detalhe}
                          </p>
                        )}
                      </div>
                    </div>

                    <div className="mt-2.5 flex items-center gap-2 pl-11">
                      <Link
                        href={a.rota}
                        onClick={() => setAberto(false)}
                        className={`flex h-8 items-center gap-1.5 rounded-lg px-3 text-[11.5px] font-semibold text-white transition-opacity hover:opacity-90 ${
                          critico ? "bg-rose-600" : "bg-amber-600"
                        }`}
                      >
                        Resolver
                        <ArrowRight className="h-3.5 w-3.5" />
                      </Link>
                      <button
                        type="button"
                        onClick={() => silenciar(a)}
                        disabled={ocupado === `${a.tipo}|${a.origem_id ?? ""}|${a.quando ?? ""}`}
                        className="flex h-8 items-center gap-1.5 rounded-lg bg-white/70 px-3 text-[11.5px] font-medium text-[var(--ks-color-text-primary)] transition-colors hover:bg-white disabled:opacity-50 dark:bg-white/10 dark:hover:bg-white/20"
                      >
                        <BellOff className="h-3.5 w-3.5" />
                        Silenciar 7 dias
                      </button>
                    </div>
                  </div>
                );
              })}
            </div>

            {temSilenciado && (
              <div className="shrink-0 border-t border-[var(--ks-color-border-subtle)] px-4 py-3">
                <button
                  type="button"
                  onClick={restaurar}
                  className="flex h-9 items-center gap-2 rounded-lg px-3 text-[12px] font-semibold text-[var(--ks-color-primary)] transition-colors hover:bg-[var(--ks-color-bg-soft)]"
                >
                  <RotateCcw className="h-3.5 w-3.5" />
                  Trazer de volta os silenciados
                </button>
              </div>
            )}
          </div>
        </div>
      )}
    </>
  );
}
