import { createClient } from "@supabase/supabase-js";

/**
 * O que a página pública do centro de aprendizado precisa saber.
 *
 * Leitura com a chave anônima de propósito: a política do banco só deixa ver
 * seção ativa e artigo publicado, então rascunho não vaza nem por engano de
 * código. Escrita (resposta, leitura, busca) vai pela chave de serviço, dentro
 * de rota, para o mundo não poder escrever direto na tabela.
 */

export type Secao = {
  id: string;
  slug: string;
  title: string;
  description: string | null;
  icon: string;
  color: string;
  position: number;
};

export type Artigo = {
  id: string;
  section_id: string;
  slug: string;
  title: string;
  subtitle: string | null;
  body_html: string;
  level: string;
  keywords: string[];
  published_at: string | null;
  updated_at: string | null;
};

export const ROTULO_DO_NIVEL: Record<string, string> = {
  comecando: "Começando",
  usando: "Usando",
  avancado: "Avançado",
};

export function leitor() {
  return createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL as string,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY as string,
    { auth: { persistSession: false, autoRefreshToken: false } }
  );
}

/** A mesma biblioteca de desenhos do Owner. Nenhum ícone vem de fora. */
export const DESENHOS: Record<string, string> = {
  livro:
    "M4 5.6h6.2A2.4 2.4 0 0 1 12.6 8v11a1.8 1.8 0 0 0-1.8-1.8H4V5.6ZM20 5.6h-6.2A2.4 2.4 0 0 0 11.4 8v11a1.8 1.8 0 0 1 1.8-1.8H20V5.6Z",
  orcamento: "M4 6h16M4 12h10M4 18h13",
  cliente: "M12 11.6a3.8 3.8 0 1 0 0-7.6 3.8 3.8 0 0 0 0 7.6ZM4.6 20a7.4 7.4 0 0 1 14.8 0",
  produto: "M4.6 8.2 12 4.4l7.4 3.8v7.6L12 19.6l-7.4-3.8V8.2ZM4.6 8.2 12 12l7.4-3.8M12 12v7.6M8.3 6.3l7.4 3.8",
  pedido: "M3.4 4.6h17.2v14.8H3.4zM3.4 9.4h17.2M8 14h5",
  pdv: "M4 20V9.6l8-5.2 8 5.2V20M9 13h6v7H9z",
  preco: "M3.6 17.4 9 12l3.4 3.4L20.4 7M15.6 7h4.8v4.8",
  producao: "M3.6 5h6.4v6.4H3.6zM14 5h6.4v6.4H14zM3.6 14.6h6.4V19H3.6zM14 14.6h6.4V19H14z",
  estoque: "M4 8.4 12 4l8 4.4v7.2L12 20l-8-4.4V8.4ZM4 8.4 12 13l8-4.6M12 13v7",
  fornecedor: "M5.4 6h13.2l-1.3 12.2a2 2 0 0 1-2 1.8H8.7a2 2 0 0 1-2-1.8L5.4 6ZM9 6a3 3 0 0 1 6 0",
  loja: "M4 10.4 5.6 5.4h12.8L20 10.4M4 10.4h16V18a1.6 1.6 0 0 1-1.6 1.6H5.6A1.6 1.6 0 0 1 4 18v-7.6ZM9.6 14h4.8",
  financeiro: "M12 3.6v16.8M8 7.4h6.4a2.6 2.6 0 0 1 0 5.2H9.6a2.6 2.6 0 0 0 0 5.2H16",
  relatorio: "M4 18.4 8.6 7.2l4 6.4 3-4.2 4.4 9",
  agenda: "M3.6 6.4h16.8V20H3.6zM3.6 10.6h16.8M8 3.6v4M16 3.6v4",
  chat: "M4 5.6h16v10.2H10.6L6 19.4v-3.6H4V5.6Z",
  config:
    "M12 15.2a3.2 3.2 0 1 0 0-6.4 3.2 3.2 0 0 0 0 6.4ZM19.6 12a7.7 7.7 0 0 0-.1-1.2l2-1.5-1.9-3.3-2.4 1a7.6 7.6 0 0 0-2-1.2l-.4-2.6h-3.8l-.4 2.6a7.6 7.6 0 0 0-2 1.2l-2.4-1L2.5 9.3l2 1.5A7.7 7.7 0 0 0 4.4 12c0 .4 0 .8.1 1.2l-2 1.5 1.9 3.3 2.4-1c.6.5 1.3.9 2 1.2l.4 2.6h3.8l.4-2.6c.7-.3 1.4-.7 2-1.2l2.4 1 1.9-3.3-2-1.5c.1-.4.1-.8.1-1.2Z",
};

/**
 * Monta o player a partir do identificador guardado no HTML.
 *
 * O editor grava só o ID, nunca um `<iframe>`. Quem decide o endereço do
 * player é a página: assim, trocar de provedor ou apertar a privacidade
 * (`youtube-nocookie`) é uma linha aqui, e não uma migração de todo o texto já
 * escrito.
 */
export function montarVideos(html: string) {
  return html.replace(
    /<figure class="help-video"([^>]*)>([\s\S]*?)<\/figure>/gi,
    (inteiro, atributos: string, dentro: string) => {
      const achado = /data-youtube="([A-Za-z0-9_-]{6,20})"/.exec(atributos);
      if (!achado) return inteiro;
      const quadro = `<div class="help-video-quadro"><iframe src="https://www.youtube-nocookie.com/embed/${achado[1]}" title="Vídeo" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen loading="lazy"></iframe></div>`;
      return `<figure class="help-video">${quadro}${dentro}</figure>`;
    }
  );
}

/** Âncora estável para o sumário: o mesmo texto sempre gera o mesmo id. */
export function ancora(texto: string, indice: number) {
  const limpo = texto
    .toLowerCase()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .slice(0, 60);
  return limpo ? `${limpo}-${indice}` : `parte-${indice}`;
}

/**
 * Lê os títulos do artigo e carimba a âncora em cada um.
 *
 * Devolve o HTML já com `id` nos títulos e a lista para o "nesta página". As
 * duas coisas saem da mesma varredura de propósito: numeradas em separado,
 * elas sairiam do compasso no primeiro título repetido.
 */
export function prepararTexto(html: string) {
  /* Os blocos de passo saem de cena antes da varredura e voltam depois.
     O título de um passo é um h3, mas ele é o nome do passo, não uma parte do
     artigo: no "nesta página" ele viraria ruído e empurraria as seções de
     verdade para baixo. O marcador é um comentário HTML porque a faxina
     descarta comentários, então ele nunca aparece num texto de verdade. */
  const guardados: string[] = [];
  const semPassos = html.replace(/<div class="help-passos">[\s\S]*?<\/div><\/div><\/div>/gi, (bloco) => {
    guardados.push(bloco);
    return `<!--passo:${guardados.length - 1}-->`;
  });

  const titulos: Array<{ id: string; texto: string; nivel: number }> = [];
  let indice = 0;
  const marcado = semPassos.replace(
    /<(h2|h3)([^>]*)>([\s\S]*?)<\/\1>/gi,
    (inteiro, tag: string, atributos: string, dentro: string) => {
      const texto = dentro.replace(/<[^>]*>/g, "").replace(/&nbsp;/g, " ").trim();
      if (!texto) return inteiro;
      indice += 1;
      const id = ancora(texto, indice);
      titulos.push({ id, texto, nivel: tag.toLowerCase() === "h2" ? 2 : 3 });
      return `<${tag}${atributos} id="${id}">${dentro}</${tag}>`;
    }
  );

  const inteiro = marcado.replace(/<!--passo:(\d+)-->/g, (_todo, n: string) => guardados[Number(n)] ?? "");
  return { html: montarVideos(inteiro), titulos };
}

export function minutosDeLeitura(html: string) {
  const palavras = html.replace(/<[^>]*>/g, " ").split(/\s+/).filter(Boolean).length;
  return Math.max(1, Math.round(palavras / 200));
}

export function dataPorExtenso(valor: string | null) {
  if (!valor) return "";
  const data = new Date(valor);
  if (Number.isNaN(data.getTime())) return "";
  return data.toLocaleDateString("pt-BR", { day: "numeric", month: "long", year: "numeric" });
}
