"use client";

import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { Toaster } from "sonner";
import { ArrowLeft, Check, Globe, Link2, Loader2, Printer, RefreshCw, Trash2 } from "lucide-react";
import { getSupabaseClient } from "@/lib/supabase";
import { chaveDoDia, doTexto, somaDias, type EventoAgenda } from "../tipos";
import { CorpoRelatorio, DIMENSOES, type ChaveDim } from "@/components/relatorio/corpo";
import { nomeDoRelatorio, useTituloDaPagina } from "@/components/relatorio/titulo-da-pagina";
import { aviso } from "../aviso";

/**
 * Relatório da agenda, versão interna.
 *
 * O recorte mora na URL, entao qualquer ajuste de periodo continua sendo um
 * link que se manda a outra pessoa da empresa. Para quem esta de fora existe o
 * link publico, que e outra coisa: leva um token proprio e nao aceita o
 * periodo por querystring — senao quem recebesse trocaria as datas e leria
 * qualquer mes.
 *
 * O PDF sai pela impressao do navegador. Gerar no servidor exigiria uma
 * dependencia pesada para produzir o que o navegador ja faz, e com a vantagem
 * de a pessoa escolher paginas e margem.
 */

const PRESETS = [
  { chave: "7", rotulo: "7 dias" },
  { chave: "30", rotulo: "30 dias" },
  { chave: "mes", rotulo: "Este mês" },
  { chave: "90", rotulo: "90 dias" },
] as const;

type LinkPublico = {
  id: string;
  token: string;
  periodo_inicio: string;
  periodo_fim: string;
  incluir_detalhes: boolean;
  expires_at: string;
  acessos: number;
};

export default function RelatorioPage() {
  return (
    <Suspense fallback={<Carregando />}>
      <Relatorio />
    </Suspense>
  );
}

function Carregando() {
  return (
    <div className="flex min-h-[60vh] items-center justify-center">
      <Loader2 className="h-5 w-5 animate-spin text-[var(--ag-text-5)]" />
    </div>
  );
}

function Relatorio() {
  const router = useRouter();
  const params = useSearchParams();
  const hoje = useMemo(() => new Date(), []);

  const [de, setDe] = useState(params.get("de") || chaveDoDia(somaDias(hoje, -29)));
  const [ate, setAte] = useState(params.get("ate") || chaveDoDia(hoje));
  const [linha, setLinha] = useState<ChaveDim>(
    ((params.get("linha") as ChaveDim) in DIMENSOES ? (params.get("linha") as ChaveDim) : "categoria")
  );
  const [coluna, setColuna] = useState<ChaveDim>(
    ((params.get("coluna") as ChaveDim) in DIMENSOES ? (params.get("coluna") as ChaveDim) : "diaSemana")
  );

  const [eventos, setEventos] = useState<EventoAgenda[]>([]);
  const [carregando, setCarregando] = useState(true);
  const [erro, setErro] = useState<string | null>(null);
  const [copiado, setCopiado] = useState(false);

  const [painelPublico, setPainelPublico] = useState(false);
  const [links, setLinks] = useState<LinkPublico[]>([]);
  const [gerando, setGerando] = useState(false);
  const [comDetalhes, setComDetalhes] = useState(false);
  const [validade, setValidade] = useState(30);

  useEffect(() => {
    const q = new URLSearchParams({ de, ate, linha, coluna });
    router.replace(`/dashboard/agenda/relatorio?${q}`, { scroll: false });
  }, [de, ate, linha, coluna, router]);

  /* O titulo vira o nome sugerido do PDF, entao acompanha o periodo. */
  useTituloDaPagina(nomeDoRelatorio(de, ate));

  const ultima = useRef("");
  const buscar = useCallback(
    async (forcar = false) => {
      const chave = `${de}|${ate}`;
      if (!forcar && ultima.current === chave) return;
      if (de > ate) {
        setErro("A data inicial é depois da final.");
        return;
      }
      ultima.current = chave;
      setCarregando(true);
      setErro(null);
      try {
        const supabase = getSupabaseClient();
        const { data, error } = await supabase.rpc("get_agenda_range", { p_inicio: de, p_fim: ate });
        if (error) throw new Error(error.message);
        setEventos((data as EventoAgenda[]) ?? []);
      } catch (e) {
        const msg = e instanceof Error ? e.message : "Não foi possível carregar.";
        setErro(/intervalo/i.test(msg) ? "Escolha um período de até 400 dias." : msg);
        setEventos([]);
      } finally {
        setCarregando(false);
      }
    },
    [de, ate]
  );

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

  const carregarLinks = useCallback(async () => {
    const supabase = getSupabaseClient();
    const { data } = await supabase
      .from("agenda_report_shares")
      .select("id, token, periodo_inicio, periodo_fim, incluir_detalhes, expires_at, acessos")
      .is("revoked_at", null)
      .gt("expires_at", new Date().toISOString())
      .order("created_at", { ascending: false })
      .limit(10);
    setLinks((data as LinkPublico[]) ?? []);
  }, []);

  useEffect(() => {
    if (painelPublico) carregarLinks();
  }, [painelPublico, carregarLinks]);

  const gerarLink = async () => {
    setGerando(true);
    try {
      const supabase = getSupabaseClient();
      const { data, error } = await supabase.rpc("criar_link_relatorio_agenda", {
        p_inicio: de,
        p_fim: ate,
        p_linha: linha,
        p_coluna: coluna,
        p_dias_validade: validade,
        p_incluir_detalhes: comDetalhes,
      });
      if (error) throw new Error(error.message);
      const token = (data as { token: string }[])?.[0]?.token;
      if (!token) throw new Error("Não foi possível gerar o link.");
      const url = `${window.location.origin}/relatorio/${token}`;
      await navigator.clipboard.writeText(url).catch(() => {});
      aviso.sucesso("Link público criado e copiado.");
      carregarLinks();
    } catch (e) {
      aviso.erro(e instanceof Error ? e.message : "Não foi possível gerar o link.");
    } finally {
      setGerando(false);
    }
  };

  const revogar = async (id: string) => {
    try {
      const supabase = getSupabaseClient();
      const { error } = await supabase.rpc("revogar_link_relatorio_agenda", { p_id: id });
      if (error) throw new Error(error.message);
      aviso.sucesso("Link revogado. Quem tiver a URL não abre mais.");
      carregarLinks();
    } catch (e) {
      aviso.erro(e instanceof Error ? e.message : "Não foi possível revogar.");
    }
  };

  const aplicarPreset = (chave: string) => {
    if (chave === "mes") {
      setDe(chaveDoDia(new Date(hoje.getFullYear(), hoje.getMonth(), 1)));
      setAte(chaveDoDia(new Date(hoje.getFullYear(), hoje.getMonth() + 1, 0)));
      return;
    }
    setDe(chaveDoDia(somaDias(hoje, -(Number(chave) - 1))));
    setAte(chaveDoDia(hoje));
  };

  const copiarLinkInterno = async () => {
    try {
      await navigator.clipboard.writeText(window.location.href);
      setCopiado(true);
      aviso.sucesso("Link copiado. Abre para quem tem acesso à empresa.");
      window.setTimeout(() => setCopiado(false), 2200);
    } catch {
      aviso.erro("Não foi possível copiar o link.");
    }
  };

  const periodoLegivel = `${doTexto(de).toLocaleDateString("pt-BR")} a ${doTexto(ate).toLocaleDateString("pt-BR")}`;

  return (
    <div className="relatorio-agenda min-h-screen bg-[var(--ks-color-bg-body)] pb-20 print:bg-[var(--ag-surface)] print:pb-0">
      <div className="w-full space-y-4 py-6 print:py-0">
        <div className="flex flex-wrap items-start justify-between gap-3 print:block">
          <div>
            <Link
              href="/dashboard/agenda"
              className="mb-1.5 inline-flex items-center gap-1.5 text-[12px] font-medium text-[#6C3CF0] hover:underline print:hidden"
            >
              <ArrowLeft className="h-3.5 w-3.5" />
              Voltar para a agenda
            </Link>
            <h1 className="text-[24px] font-bold leading-tight text-[var(--ag-text)]">Relatório da agenda</h1>
            <p className="mt-0.5 text-[13px] text-[var(--ag-text-3)]">
              {periodoLegivel} · {eventos.length} {eventos.length === 1 ? "registro" : "registros"}
            </p>
          </div>

          <div className="flex flex-wrap items-center gap-2 print:hidden">
            <button
              type="button"
              onClick={copiarLinkInterno}
              className="flex h-9 items-center gap-2 rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] px-[14px] text-[12px] font-semibold text-[var(--ag-text-2)] transition-colors hover:border-[var(--ag-border-strong)] hover:bg-[var(--ag-surface-2)]"
            >
              {copiado ? <Check className="h-4 w-4 text-emerald-600" /> : <Link2 className="h-4 w-4" />}
              {copiado ? "Copiado" : "Copiar link"}
            </button>
            <button
              type="button"
              onClick={() => setPainelPublico((v) => !v)}
              aria-expanded={painelPublico}
              className={`flex h-9 items-center gap-2 rounded-[9px] border px-[14px] text-[12px] font-semibold transition-colors ${
                painelPublico
                  ? "border-[rgba(108,60,240,0.35)] bg-[rgba(108,60,240,0.06)] text-[#6C3CF0]"
                  : "border-[var(--ag-border-strong)] bg-[var(--ag-surface)] text-[var(--ag-text-2)] hover:border-[var(--ag-border-strong)] hover:bg-[var(--ag-surface-2)]"
              }`}
            >
              <Globe className="h-4 w-4" />
              Link público
            </button>
            <button
              type="button"
              onClick={() => buscar(true)}
              aria-label="Atualizar"
              className="flex h-9 w-9 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)]"
            >
              <RefreshCw className="h-4 w-4" />
            </button>
            <button
              type="button"
              onClick={() => window.print()}
              className="flex h-9 items-center gap-2 rounded-[9px] bg-[#6C3CF0] px-[14px] text-[12px] font-semibold text-white transition-colors hover:bg-[#5C31D8]"
            >
              <Printer className="h-4 w-4" />
              Baixar PDF
            </button>
          </div>
        </div>

        {/* ---------- Compartilhar para fora ---------- */}
        {painelPublico && (
          <div className="space-y-3 rounded-[14px] border border-[rgba(108,60,240,0.25)] bg-[rgba(108,60,240,0.03)] p-4 print:hidden">
            <div>
              <p className="text-[13px] font-semibold text-[var(--ag-text)]">Link público deste período</p>
              <p className="mt-0.5 text-[11.5px] text-[var(--ag-text-3)]">
                Abre sem login, para quem não tem acesso ao sistema. O período fica travado em{" "}
                <strong className="font-semibold text-[var(--ag-text-2)]">{periodoLegivel}</strong> — quem receber não
                consegue ver outras datas.
              </p>
            </div>

            <div className="flex flex-wrap items-end gap-4">
              <label className="flex flex-col gap-1">
                <span className="text-[10.5px] font-semibold uppercase tracking-[0.04em] text-[var(--ag-text-4)]">
                  Validade
                </span>
                <select
                  value={validade}
                  onChange={(e) => setValidade(Number(e.target.value))}
                  className="h-9 rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] px-2.5 text-[12.5px] text-[var(--ag-text)]"
                >
                  <option value={7}>7 dias</option>
                  <option value={30}>30 dias</option>
                  <option value={90}>90 dias</option>
                  <option value={180}>180 dias</option>
                </select>
              </label>

              <label className="flex cursor-pointer items-center gap-2 pb-2">
                <input
                  type="checkbox"
                  checked={comDetalhes}
                  onChange={(e) => setComDetalhes(e.target.checked)}
                  className="h-4 w-4 rounded border-[var(--ag-border-strong)] accent-[#6C3CF0]"
                />
                <span className="text-[12px] text-[var(--ag-text-2)]">
                  Incluir nomes de clientes e a lista detalhada
                </span>
              </label>

              <button
                type="button"
                onClick={gerarLink}
                disabled={gerando}
                className="flex h-9 items-center gap-2 rounded-[9px] bg-[#6C3CF0] px-[14px] text-[12px] font-semibold text-white transition-colors hover:bg-[#5C31D8] disabled:opacity-60"
              >
                {gerando ? <Loader2 className="h-4 w-4 animate-spin" /> : <Globe className="h-4 w-4" />}
                Gerar e copiar
              </button>
            </div>

            {!comDetalhes && (
              <p className="text-[11px] text-[var(--ag-text-4)]">
                Sem essa opção, os gráficos vão completos mas nenhum nome de cliente sai do servidor.
              </p>
            )}

            {links.length > 0 && (
              <div className="border-t border-[rgba(108,60,240,0.15)] pt-3">
                <p className="mb-2 text-[10.5px] font-semibold uppercase tracking-[0.04em] text-[var(--ag-text-4)]">
                  Links ativos
                </p>
                <ul className="space-y-1.5">
                  {links.map((l) => (
                    <li
                      key={l.id}
                      className="flex flex-wrap items-center gap-2 rounded-[9px] border border-[var(--ag-border)] bg-[var(--ag-surface)] px-3 py-2"
                    >
                      <span className="min-w-0 flex-1 truncate text-[11.5px] font-medium text-[var(--ag-text-2)]">
                        {doTexto(l.periodo_inicio).toLocaleDateString("pt-BR")} a{" "}
                        {doTexto(l.periodo_fim).toLocaleDateString("pt-BR")}
                        {l.incluir_detalhes && (
                          <span className="ml-2 rounded-full bg-amber-50 px-2 py-[1px] text-[10px] font-medium text-amber-700">
                            com nomes
                          </span>
                        )}
                      </span>
                      <span className="shrink-0 text-[11px] text-[var(--ag-text-5)]">
                        expira {new Date(l.expires_at).toLocaleDateString("pt-BR")} · {l.acessos}{" "}
                        {l.acessos === 1 ? "acesso" : "acessos"}
                      </span>
                      <button
                        type="button"
                        onClick={() => {
                          navigator.clipboard.writeText(`${window.location.origin}/relatorio/${l.token}`);
                          aviso.sucesso("Link copiado.");
                        }}
                        className="flex h-7 items-center gap-1.5 rounded-[7px] border border-[var(--ag-border-strong)] px-2 text-[11px] font-medium text-[var(--ag-text-2)] hover:bg-[var(--ag-surface-2)]"
                      >
                        <Link2 className="h-3.5 w-3.5" />
                        Copiar
                      </button>
                      <button
                        type="button"
                        onClick={() => revogar(l.id)}
                        aria-label="Revogar link"
                        className="flex h-7 w-7 items-center justify-center rounded-[7px] border border-[var(--ag-border-strong)] text-rose-600 hover:bg-rose-50"
                      >
                        <Trash2 className="h-3.5 w-3.5" />
                      </button>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        )}

        {/* ---------- Recorte ---------- */}
        <div className="flex flex-wrap items-end gap-x-5 gap-y-3 rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)] p-4 print:hidden">
          <label className="flex flex-col gap-1">
            <span className="text-[10.5px] font-semibold uppercase tracking-[0.04em] text-[var(--ag-text-4)]">De</span>
            <input
              type="date"
              value={de}
              onChange={(e) => setDe(e.target.value)}
              className="h-9 rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] px-2.5 text-[12.5px] text-[var(--ag-text)]"
            />
          </label>
          <label className="flex flex-col gap-1">
            <span className="text-[10.5px] font-semibold uppercase tracking-[0.04em] text-[var(--ag-text-4)]">Até</span>
            <input
              type="date"
              value={ate}
              onChange={(e) => setAte(e.target.value)}
              className="h-9 rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] px-2.5 text-[12.5px] text-[var(--ag-text)]"
            />
          </label>
          <div className="flex gap-1.5">
            {PRESETS.map((p) => (
              <button
                key={p.chave}
                type="button"
                onClick={() => aplicarPreset(p.chave)}
                className="h-9 rounded-[9px] border border-[var(--ag-border-strong)] bg-[var(--ag-surface)] px-3 text-[12px] font-medium text-[var(--ag-text-2)] transition-colors hover:border-[var(--ag-border-strong)] hover:bg-[var(--ag-surface-2)]"
              >
                {p.rotulo}
              </button>
            ))}
          </div>
          {carregando && <Loader2 className="mb-2 h-4 w-4 animate-spin text-[var(--ag-text-5)]" />}
        </div>

        {erro && (
          <p className="rounded-[12px] bg-rose-50 px-4 py-3 text-[12.5px] font-semibold text-rose-700">{erro}</p>
        )}

        {!erro && eventos.length === 0 && !carregando && (
          <div className="rounded-[14px] border border-[var(--ag-border)] bg-[var(--ag-surface)] px-4 py-12 text-center">
            <p className="text-[13px] text-[var(--ag-text-3)]">Nenhum registro neste período.</p>
          </div>
        )}

        {eventos.length > 0 && (
          <>
            <CorpoRelatorio
              eventos={eventos}
              de={de}
              ate={ate}
              linha={linha}
              coluna={coluna}
              aoTrocarLinha={setLinha}
              aoTrocarColuna={setColuna}
            />
            <p className="pt-1 text-center text-[10.5px] text-[var(--ag-text-5)]">
              Gerado em {new Date().toLocaleString("pt-BR")} · Ktalogu
            </p>
          </>
        )}
      </div>

      <Toaster richColors position="top-center" />
    </div>
  );
}
