"use client";

import { FormEvent, useCallback, useEffect, useMemo, useState } from "react";
import { userMessage } from "../lib/messages";

const apiBase = process.env.NEXT_PUBLIC_API_BASE_URL || "/api/v1";
type Row = Record<string, unknown>;
type EditorialData = { articulos: Row[]; categorias: Row[]; autores: Row[]; medios: Row[]; metricas: Row };

function message(detail: unknown, fallback: string) {
  if (typeof detail === "string") return detail;
  if (Array.isArray(detail)) return detail.map((item) => (item as { msg?: string }).msg || "Valor inválido").join(" · ");
  return fallback;
}

function contentToText(content: unknown) {
  if (!Array.isArray(content)) return "";
  return content.map((block) => {
    const item = block as { tipo?: string; texto?: string };
    const prefix = item.tipo === "SUBTITULO" ? "## " : item.tipo === "LISTA" ? "- " : item.tipo === "CITA" ? "> " : item.tipo === "ALERTA" ? "! " : "";
    return `${prefix}${item.texto || ""}`;
  }).join("\n\n");
}

function textToContent(value: string) {
  return value.split(/\n\s*\n/).map((part) => part.trim()).filter(Boolean).map((part) => {
    if (part.startsWith("## ")) return { tipo: "SUBTITULO", texto: part.slice(3).trim() };
    if (part.startsWith("- ")) return { tipo: "LISTA", texto: part.slice(2).trim() };
    if (part.startsWith("> ")) return { tipo: "CITA", texto: part.slice(2).trim() };
    if (part.startsWith("! ")) return { tipo: "ALERTA", texto: part.slice(2).trim() };
    return { tipo: "PARRAFO", texto: part };
  });
}

export default function EditorialManagement({ csrf, notify }: { csrf: () => Promise<string>; notify: (value: string) => void }) {
  const [data, setData] = useState<EditorialData | null>(null);
  const [tab, setTab] = useState<"articulos" | "taxonomia" | "medios">("articulos");
  const [selected, setSelected] = useState<Row | null>(null);
  const [kind, setKind] = useState("NOTICIA");
  const [busy, setBusy] = useState(false);

  const load = useCallback(async () => {
    const response = await fetch(`${apiBase}/panel/admin/editorial`, { credentials: "include", cache: "no-store" });
    const body = await response.json();
    if (!response.ok) throw new Error(message(body.detail, "No fue posible cargar el contenido editorial."));
    setData(body as EditorialData);
  }, []);

  useEffect(() => { void load().catch((reason) => notify(userMessage(reason, "No fue posible cargar el contenido editorial."))); }, [load, notify]);
  useEffect(() => { setKind(String(selected?.tipo || "NOTICIA")); }, [selected]);

  const categories = useMemo(() => (data?.categorias || []).filter((row) => row.tipo === kind && row.activa), [data, kind]);

  async function saveArticle(event: FormEvent<HTMLFormElement>) {
    event.preventDefault(); setBusy(true);
    const formElement = event.currentTarget;
    try {
      const form = new FormData(formElement);
      const content = textToContent(String(form.get("contenido") || ""));
      if (!content.length) throw new Error("Agrega al menos un párrafo al contenido.");
      const payload = {
        tipo: form.get("tipo"), categoria_id: Number(form.get("categoria_id")),
        autor_id: form.get("autor_id") ? Number(form.get("autor_id")) : null,
        imagen_portada_id: form.get("imagen_portada_id") ? Number(form.get("imagen_portada_id")) : null,
        slug: form.get("slug") || null, titulo: form.get("titulo"), bajada: form.get("bajada"), contenido: content,
        destacado: form.get("destacado") === "on", meta_titulo: form.get("meta_titulo"),
        meta_descripcion: form.get("meta_descripcion"), relacionados: [],
      };
      const token = await csrf();
      const target = selected ? `${apiBase}/panel/admin/editorial/articles/${selected.id}` : `${apiBase}/panel/admin/editorial/articles`;
      const response = await fetch(target, { method: selected ? "PUT" : "POST", credentials: "include",
        headers: { "Content-Type": "application/json", "X-CSRF-Token": token }, body: JSON.stringify(payload) });
      const body = await response.json();
      if (!response.ok) throw new Error(message(body.detail, "No fue posible guardar el contenido."));
      formElement.reset(); await load(); setSelected(null); notify("Contenido editorial guardado correctamente.");
    } catch (reason) { notify(userMessage(reason, "No fue posible guardar el contenido.")); }
    finally { setBusy(false); }
  }

  async function transition(article: Row, accion: string) {
    setBusy(true);
    try {
      const token = await csrf();
      const response = await fetch(`${apiBase}/panel/admin/editorial/articles/${article.id}/transition`, {
        method: "POST", credentials: "include", headers: { "Content-Type": "application/json", "X-CSRF-Token": token },
        body: JSON.stringify({ accion, comentario: null }),
      });
      const body = await response.json();
      if (!response.ok) throw new Error(message(body.detail, "No fue posible cambiar el estado."));
      await load(); notify(`Estado actualizado a ${String(body.estado).replaceAll("_", " ").toLowerCase()}.`);
    } catch (reason) { notify(userMessage(reason, "No fue posible cambiar el estado.")); }
    finally { setBusy(false); }
  }

  async function createTaxonomy(event: FormEvent<HTMLFormElement>, target: "categories" | "authors") {
    event.preventDefault(); setBusy(true);
    const formElement = event.currentTarget;
    try {
      const form = new FormData(formElement);
      const payload = target === "categories"
        ? { tipo: form.get("tipo"), nombre: form.get("nombre"), slug: form.get("slug") || null,
            descripcion: form.get("descripcion") || null, orden: Number(form.get("orden") || 0), activa: true }
        : { nombre: form.get("nombre"), slug: form.get("slug") || null, cargo: form.get("cargo") || null,
            biografia: form.get("biografia") || null, avatar_url: form.get("avatar_url") || null, activo: true };
      const token = await csrf();
      const response = await fetch(`${apiBase}/panel/admin/editorial/${target}`, { method: "POST", credentials: "include",
        headers: { "Content-Type": "application/json", "X-CSRF-Token": token }, body: JSON.stringify(payload) });
      const body = await response.json();
      if (!response.ok) throw new Error(message(body.detail, "No fue posible guardar."));
      formElement.reset(); await load(); notify(target === "categories" ? "Categoría creada correctamente." : "Autor creado correctamente.");
    } catch (reason) { notify(userMessage(reason, "No fue posible guardar.")); }
    finally { setBusy(false); }
  }

  async function upload(event: FormEvent<HTMLFormElement>) {
    event.preventDefault(); setBusy(true);
    const formElement = event.currentTarget;
    try {
      const form = new FormData(formElement); const token = await csrf();
      const response = await fetch(`${apiBase}/panel/admin/editorial/media`, { method: "POST", credentials: "include",
        headers: { "X-CSRF-Token": token }, body: form });
      const body = await response.json();
      if (!response.ok) throw new Error(message(body.detail, "No fue posible subir la imagen."));
      formElement.reset(); await load(); notify("Imagen incorporada a la biblioteca.");
    } catch (reason) { notify(userMessage(reason, "No fue posible subir la imagen.")); }
    finally { setBusy(false); }
  }

  if (!data) return <div className="panel-empty">Cargando noticias y ayuda…</div>;
  return <div className="editorial-admin">
    <section className="panel-card cms-intro-card"><div><span className="section-kicker">H10 · CONTENIDO</span><h2>Noticias y centro de ayuda</h2><p>Redacta, revisa y publica contenido con URLs estables y metadatos para buscadores.</p></div><div className="editorial-public-links"><a className="button button-secondary" href="https://documenta.cl/noticias" target="_blank" rel="noreferrer">Ver noticias ↗</a><a className="button button-secondary" href="https://documenta.cl/ayuda" target="_blank" rel="noreferrer">Ver ayuda ↗</a></div></section>
    <div className="metrics-grid cms-metrics">{Object.entries(data.metricas || {}).map(([key, value]) => <article className="metric-card" key={key}><small>{key.replaceAll("_", " ")}</small><strong>{Number(value || 0).toLocaleString("es-CL")}</strong></article>)}</div>
    <div className="editorial-tabs"><button className={tab === "articulos" ? "is-active" : ""} onClick={() => setTab("articulos")}>Artículos</button><button className={tab === "taxonomia" ? "is-active" : ""} onClick={() => setTab("taxonomia")}>Categorías y autores</button><button className={tab === "medios" ? "is-active" : ""} onClick={() => setTab("medios")}>Medios</button></div>

    {tab === "articulos" && <div className="editorial-grid">
      <section className="panel-card editorial-list"><header><div><small>FLUJO EDITORIAL</small><h2>Contenido</h2></div><button className="button button-secondary" type="button" onClick={() => setSelected(null)}>Nuevo</button></header>
        <div>{data.articulos.length ? data.articulos.map((article) => <article className={selected?.id === article.id ? "is-selected" : ""} key={String(article.id)}>
          <button type="button" onClick={() => setSelected(article)}><small>{String(article.tipo)} · {String(article.estado).replaceAll("_", " ")}</small><strong>{String(article.titulo)}</strong><span>/{article.tipo === "NOTICIA" ? "noticias" : "ayuda"}/{String(article.slug)}</span></button>
          <div className="editorial-actions">{article.estado === "BORRADOR" && <button disabled={busy} onClick={() => transition(article, "ENVIAR_REVISION")}>Enviar a revisión</button>}{article.estado === "EN_REVISION" && <><button disabled={busy} onClick={() => transition(article, "PUBLICAR")}>Publicar</button><button disabled={busy} onClick={() => transition(article, "DEVOLVER")}>Devolver</button></>}{article.estado === "PUBLICADO" && <button disabled={busy} onClick={() => transition(article, "RETIRAR")}>Retirar</button>}{article.estado === "RETIRADO" && <button disabled={busy} onClick={() => transition(article, "REPUBLICAR")}>Republicar</button>}</div>
        </article>) : <p className="panel-empty">Aún no hay artículos.</p>}</div>
      </section>
      <form className="panel-card profile-form editorial-form" key={String(selected?.id || "new")} onSubmit={saveArticle}>
        <header><div><small>{selected ? "EDITAR" : "NUEVO"}</small><h2>{selected ? String(selected.titulo) : "Crear contenido"}</h2></div>{selected && <button type="button" className="editorial-close" onClick={() => setSelected(null)} aria-label="Cerrar">×</button>}</header>
        <div className="editorial-form-row"><label>Tipo<select name="tipo" value={kind} onChange={(event) => setKind(event.target.value)}><option value="NOTICIA">Noticia</option><option value="AYUDA">Ayuda / FAQ</option></select></label><label>Categoría<select name="categoria_id" defaultValue={String(selected?.categoria_id || "")} required><option value="">Selecciona</option>{categories.map((row) => <option key={String(row.id)} value={String(row.id)}>{String(row.nombre)}</option>)}</select></label></div>
        <label>Título<input name="titulo" defaultValue={String(selected?.titulo || "")} maxLength={220} required /></label>
        <label>URL estable<input name="slug" defaultValue={String(selected?.slug || "")} placeholder="se genera desde el título" readOnly={Boolean(selected?.publicado_en)} /><small>Después de publicar por primera vez, la URL queda protegida.</small></label>
        <label>Bajada<textarea name="bajada" defaultValue={String(selected?.bajada || "")} rows={3} maxLength={700} required /></label>
        <label>Contenido<textarea className="editorial-content-input" name="contenido" defaultValue={contentToText(selected?.contenido)} rows={16} required /><small>Separa párrafos con una línea vacía. Usa ## subtítulo, - lista, &gt; cita o ! alerta.</small></label>
        <div className="editorial-form-row"><label>Autor<select name="autor_id" defaultValue={String(selected?.autor_id || "")}><option value="">Sin autor</option>{data.autores.filter((row) => row.activo).map((row) => <option key={String(row.id)} value={String(row.id)}>{String(row.nombre)}</option>)}</select></label><label>Imagen de portada<select name="imagen_portada_id" defaultValue={String(selected?.imagen_portada_id || "")}><option value="">Sin imagen</option>{data.medios.filter((row) => row.activo).map((row) => <option key={String(row.id)} value={String(row.id)}>{String(row.nombre_original)}</option>)}</select></label></div>
        <label>Título SEO<input name="meta_titulo" defaultValue={String(selected?.meta_titulo || selected?.titulo || "")} maxLength={180} required /></label>
        <label>Descripción SEO<textarea name="meta_descripcion" defaultValue={String(selected?.meta_descripcion || selected?.bajada || "")} rows={3} maxLength={500} required /></label>
        <label className="cms-toggle"><input type="checkbox" name="destacado" defaultChecked={Boolean(selected?.destacado)} /> Destacar en el listado</label>
        <button className="button button-primary" disabled={busy}>{busy ? "Guardando…" : selected ? "Guardar cambios" : "Crear borrador"}</button>
      </form>
    </div>}

    {tab === "taxonomia" && <div className="editorial-grid editorial-taxonomy">
      <section className="panel-card"><h2>Categorías</h2><div className="editorial-tag-list">{data.categorias.map((row) => <span key={String(row.id)}><b>{String(row.nombre)}</b><small>{String(row.tipo)}</small></span>)}</div><form className="profile-form" onSubmit={(event) => createTaxonomy(event, "categories")}><label>Tipo<select name="tipo"><option value="NOTICIA">Noticia</option><option value="AYUDA">Ayuda</option></select></label><label>Nombre<input name="nombre" required /></label><label>Slug<input name="slug" placeholder="automático" /></label><label>Descripción<textarea name="descripcion" rows={3} /></label><label>Orden<input type="number" name="orden" min="0" defaultValue="0" /></label><button className="button button-primary" disabled={busy}>Crear categoría</button></form></section>
      <section className="panel-card"><h2>Autores</h2><div className="editorial-tag-list">{data.autores.map((row) => <span key={String(row.id)}><b>{String(row.nombre)}</b><small>{String(row.cargo || "Autor")}</small></span>)}</div><form className="profile-form" onSubmit={(event) => createTaxonomy(event, "authors")}><label>Nombre<input name="nombre" required /></label><label>Cargo<input name="cargo" /></label><label>Biografía<textarea name="biografia" rows={3} /></label><label>URL de avatar<input name="avatar_url" placeholder="https://…" /></label><label>Slug<input name="slug" placeholder="automático" /></label><button className="button button-primary" disabled={busy}>Crear autor</button></form></section>
    </div>}

    {tab === "medios" && <div className="editorial-media-layout"><form className="panel-card profile-form" onSubmit={upload}><h2>Subir imagen</h2><label>Archivo<input type="file" name="file" accept="image/jpeg,image/png,image/webp" required /></label><label>Texto alternativo<input name="texto_alternativo" maxLength={250} required /></label><label>Crédito<input name="credito" maxLength={250} /></label><small>JPEG, PNG o WebP. Máximo 5 MB.</small><button className="button button-primary" disabled={busy}>Subir a biblioteca</button></form><section className="editorial-media-grid">{data.medios.map((row) => <article className="panel-card" key={String(row.id)}><img src={String(row.url)} alt={String(row.texto_alternativo)} /><strong>{String(row.nombre_original)}</strong><small>{String(row.texto_alternativo)}</small></article>)}</section></div>}
  </div>;
}
