import { eq, and } from "drizzle-orm";
import { db } from "./db.js";
import { bibliotecaAnotacoes, bibliotecaLivros } from "../../shared/schema.js";
function escaparHtml(texto) {
    return texto
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
}
function montarHtmlShare(params) {
    const { titulo, descricao, capa, destino } = params;
    return `<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<title>${escaparHtml(titulo)}</title>
<meta property="og:title" content="${escaparHtml(titulo)}">
<meta property="og:description" content="${escaparHtml(descricao)}">
<meta property="og:image" content="${escaparHtml(capa)}">
<meta http-equiv="refresh" content="0; url=${escaparHtml(destino)}">
<script>location.replace(${JSON.stringify(destino)});</script>
</head>
<body>Redirecionando…</body>
</html>`;
}
/**
 * Funções puras de geração de HTML — reutilizadas em dois lugares:
 *  1. As rotas /share/* explícitas abaixo (link com ?ref= de afiliado)
 *  2. O middleware de detecção de robô em static.ts, pro caso da pessoa
 *     compartilhar o link direto (/livro/:id ou /serie/:nome) sem passar
 *     pela rota /share/* — resolve o card sem capa nesse caso também,
 *     sem precisar de nenhuma mudança no frontend.
 *
 * Retornam null quando o conteúdo não existe/não está publicado — quem
 * chama decide o que fazer nesse caso (404 explícito na rota /share/*,
 * deixar cair pro SPA normal no middleware de robô).
 */
export async function gerarHtmlLivro(id, ref) {
    const [livro] = await db.select().from(bibliotecaLivros).where(eq(bibliotecaLivros.id, id));
    if (!livro || livro.status !== "publicado")
        return null;
    const destino = `/livro/${livro.id}${ref ? `?ref=${encodeURIComponent(ref)}` : ""}`;
    const capa = livro.capaUrl || "/media/images/capas/capa-placeholder.svg";
    const descricao = (livro.resumo || `Um livro de ${livro.autor}, na Biblioteca OnFide.`).slice(0, 200);
    return montarHtmlShare({ titulo: livro.titulo, descricao, capa, destino });
}
export async function gerarHtmlSerie(nome, ref) {
    // "Série" não é uma entidade própria — é o campo `serie` (texto) em
    // biblioteca_livros. A "capa da série" é a capa do primeiro volume
    // publicado (ordenado por volumeNumero) — mesmo critério visual que
    // a EstanteLivros usa como card de abertura da série.
    const livrosDaSerie = await db
        .select()
        .from(bibliotecaLivros)
        .where(and(eq(bibliotecaLivros.status, "publicado"), eq(bibliotecaLivros.serie, nome)))
        .orderBy(bibliotecaLivros.volumeNumero);
    if (livrosDaSerie.length === 0)
        return null;
    const primeiroVolume = livrosDaSerie[0];
    const destino = `/serie/${encodeURIComponent(nome)}${ref ? `?ref=${encodeURIComponent(ref)}` : ""}`;
    const capa = primeiroVolume.capaUrl || "/media/images/capas/capa-placeholder.svg";
    const descricao = `${livrosDaSerie.length} título${livrosDaSerie.length > 1 ? "s" : ""} na série ${nome}, na Biblioteca OnFide.`;
    return montarHtmlShare({ titulo: nome, descricao, capa, destino });
}
export async function gerarHtmlTrecho(id, ref) {
    const [anotacao] = await db
        .select()
        .from(bibliotecaAnotacoes)
        .where(and(eq(bibliotecaAnotacoes.id, id), eq(bibliotecaAnotacoes.tipo, "compartilhamento"), eq(bibliotecaAnotacoes.publico, true)));
    if (!anotacao)
        return null;
    const [livro] = await db.select().from(bibliotecaLivros).where(eq(bibliotecaLivros.id, anotacao.livroId));
    if (!livro)
        return null;
    const parametroRef = ref ? `&ref=${encodeURIComponent(ref)}` : "";
    const destino = `/leitor/${livro.id}?cfi=${encodeURIComponent(anotacao.cfiInicio)}${parametroRef}`;
    const capa = livro.capaUrl || "/media/images/capas/capa-placeholder.svg";
    const trecho = (anotacao.trechoTexto || "").slice(0, 200);
    return montarHtmlShare({ titulo: livro.titulo, descricao: trecho, capa, destino });
}
export function registrarRotaCompartilhamento(app) {
    app.get("/share/livro/:id", async (req, res) => {
        const id = Number(req.params.id);
        const ref = typeof req.query.ref === "string" ? req.query.ref : undefined;
        const html = await gerarHtmlLivro(id, ref);
        if (!html) {
            res.status(404).send("Livro não encontrado.");
            return;
        }
        res.send(html);
    });
    app.get("/share/serie/:nome", async (req, res) => {
        const ref = typeof req.query.ref === "string" ? req.query.ref : undefined;
        const html = await gerarHtmlSerie(req.params.nome, ref);
        if (!html) {
            res.status(404).send("Série não encontrada.");
            return;
        }
        res.send(html);
    });
    app.get("/share/trecho/:id", async (req, res) => {
        const id = Number(req.params.id);
        const ref = typeof req.query.ref === "string" ? req.query.ref : undefined;
        const html = await gerarHtmlTrecho(id, ref);
        if (!html) {
            res.status(404).send("Trecho não encontrado.");
            return;
        }
        res.send(html);
    });
}
