import { createClient } from "@supabase/supabase-js";
import type { Article } from "./types";
import { rewriteLegacyImageUrl, rewriteLegacyImageUrlsInHtml } from "@/lib/legacy-image";

const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb";

function client() {
  return createClient(SUPABASE_URL, SUPABASE_ANON, {
    db: { schema: SCHEMA as "public" },
    auth: { persistSession: false },
  });
}

interface ImportedPostRow {
  wp_id: number;
  wp_slug: string;
  title: string;
  excerpt: string | null;
  content: string | null;
  author_name: string | null;
  category: string | null;
  tags: string[] | null;
  featured_image: string | null;
  featured_image_alt: string | null;
  status: string;
  wp_published_at: string | null;
}

interface RewriteRow {
  id: string;
  slug: string;
  title: string;
  excerpt: string | null;
  body: string;
  category: string | null;
  tags: string[] | null;
  status: string;
  published_at: string | null;
  created_at: string;
  persona: PersonaJoin | PersonaJoin[] | null;
}

interface PersonaJoin {
  slug: string;
  name: string;
  beat: string | null;
  avatar_url: string | null;
}

const FALLBACK_IMAGE = "/assets/images/article-placeholder.svg";
const REWRITE_FALLBACK_IMAGE = "/assets/images/article-placeholder.svg";

type Section = Article["section"];
const SECTION_TAGS: Record<Section, string[]> = {
  gear: [
    "Audio", "Cameras", "lighting", "Lighting", "Reviews",
    "Blackmagic Design", "blackmagic", "Sony", "Canon", "ARRI", "RED",
    "monitoring", "Test and Measurement",
  ],
  technology: [
    "AI", "Streaming", "OTT", "ip", "IP", "Cloud",
    "AV", "audio-over-IP interfaces",
    "IP Workflows", "Live Production", "Cloud Production",
    "MAM", "Storage", "Encoding",
  ],
  "show-coverage": [
    "NAB", "NAB Show", "NAB 2025", "NAB 2026",
    "IBC", "IBC 2025", "IBC 2026",
    "BroadcastAsia", "BroadcastAsia 2026", "Broadcast Asia 2026",
    "InfoComm", "MPTS",
  ],
  news: [],
};

const SECTION_CATEGORIES: Record<Section, string[]> = {
  gear: ["Gear", "Reviews"],
  technology: ["Technology", "Streaming", "Live Production"],
  "show-coverage": ["Show Coverage"],
  news: [],
};

function authorSlug(name: string | null): string {
  if (!name) return "staff-reporter";
  return (
    name
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-+|-+$/g, "")
      .slice(0, 60) || "staff-reporter"
  );
}

function formatDate(iso: string | null): string {
  if (!iso) return "";
  const d = new Date(iso);
  if (isNaN(d.getTime())) return "";
  return d.toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" });
}

function readTime(content: string | null): string {
  if (!content) return "1 min read";
  const text = content.replace(/<[^>]+>/g, " ");
  const words = text.trim().split(/\s+/).filter(Boolean).length;
  const minutes = Math.max(1, Math.round(words / 200));
  return `${minutes} min read`;
}

function rowToArticle(row: ImportedPostRow, section: Section = "news"): Article {
  const image = row.featured_image
    ? rewriteLegacyImageUrl(row.featured_image)
    : FALLBACK_IMAGE;
  const content = rewriteLegacyImageUrlsInHtml(row.content || "");
  const author = row.author_name || "Broadcast Beat";
  return {
    slug: row.wp_slug,
    section,
    title: row.title,
    excerpt: row.excerpt || "",
    category: (row.category || "NEWS").toUpperCase(),
    date: formatDate(row.wp_published_at),
    author,
    authorSlug: authorSlug(author),
    authorTitle: "Contributor",
    authorAvatar: FALLBACK_IMAGE,
    image,
    alt: row.featured_image_alt || row.title,
    readTime: readTime(row.content),
    tags: row.tags || [],
    content,
  };
}

function inferSectionFromCategory(cat: string | null): Section {
  if (!cat) return "news";
  const c = cat.toLowerCase();
  if (c === "post production" || c === "post-production") return "technology";
  if (c === "streaming" || c === "technology" || c === "live production") return "technology";
  if (c === "sports") return "news";
  if (c === "business") return "news";
  return "news";
}

function rewriteRowToArticle(row: RewriteRow, sectionOverride?: Section): Article {
  const sortedPublishedAt = row.published_at || row.created_at;
  const persona = Array.isArray(row.persona) ? row.persona[0] || null : row.persona || null;
  const author = persona?.name || "Broadcast Beat";
  const personaSlug = persona?.slug || "staff-reporter";
  const avatar = persona?.avatar_url || FALLBACK_IMAGE;
  return {
    slug: row.slug,
    section: sectionOverride || inferSectionFromCategory(row.category),
    title: row.title,
    excerpt: row.excerpt || "",
    category: (row.category || "NEWS").toUpperCase(),
    date: formatDate(sortedPublishedAt),
    author,
    authorSlug: personaSlug,
    authorTitle: persona?.beat ? humanBeat(persona.beat) : "Broadcast Beat",
    authorAvatar: avatar,
    image: REWRITE_FALLBACK_IMAGE,
    alt: row.title,
    readTime: readTime(row.body),
    tags: row.tags || [],
    content: row.body,
  };
}

function humanBeat(beat: string): string {
  return beat
    .split(/[-_]/)
    .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
    .join(" ")
    .replace("M And A", "M&A");
}

const SELECT_COLS =
  "wp_id,wp_slug,title,excerpt,content,author_name,category,tags,featured_image,featured_image_alt,status,wp_published_at";

const REWRITE_SELECT_COLS =
  "id,slug,title,excerpt,body,category,tags,status,published_at,created_at,persona:ai_personas(slug,name,beat,avatar_url)";

function rewriteOrderKey(a: RewriteRow): number {
  return new Date(a.published_at || a.created_at || 0).getTime();
}
function legacyOrderKey(a: ImportedPostRow): number {
  return new Date(a.wp_published_at || 0).getTime();
}

async function fetchPublishedRewrites(limit: number): Promise<RewriteRow[]> {
  try {
    const { data, error } = await client()
      .from("ai_rewritten_articles")
      .select(REWRITE_SELECT_COLS)
      .eq("status", "published")
      .order("published_at", { ascending: false, nullsFirst: false })
      .limit(limit);
    if (error || !data) return [];
    return data as unknown as RewriteRow[];
  } catch {
    return [];
  }
}

export async function getLegacyArticleBySlug(slug: string): Promise<Article | null> {
  try {
    const { data, error } = await client()
      .from("wp_imported_posts")
      .select(SELECT_COLS)
      .eq("wp_slug", slug)
      .eq("status", "published")
      .maybeSingle();
    if (!error && data) return rowToArticle(data as ImportedPostRow);
  } catch {
    // fall through
  }
  // Try AI rewrites
  try {
    const { data, error } = await client()
      .from("ai_rewritten_articles")
      .select(REWRITE_SELECT_COLS)
      .eq("slug", slug)
      .eq("status", "published")
      .maybeSingle();
    if (!error && data) return rewriteRowToArticle(data as unknown as RewriteRow);
  } catch {
    // fall through
  }
  return null;
}

export async function getLegacyRelatedArticles(
  excludeSlug: string,
  category: string | null,
  count: number,
): Promise<Article[]> {
  try {
    let q = client()
      .from("wp_imported_posts")
      .select(SELECT_COLS)
      .eq("status", "published")
      .neq("wp_slug", excludeSlug)
      .order("wp_published_at", { ascending: false })
      .limit(count);
    if (category) q = q.eq("category", category);
    const { data, error } = await q;
    if (error || !data) return [];
    return (data as ImportedPostRow[]).map((r) => rowToArticle(r));
  } catch {
    return [];
  }
}

export async function getLegacyArticlesBySection(
  section: Section,
  limit = 200,
): Promise<Article[]> {
  let legacy: ImportedPostRow[] = [];
  let rewrites: RewriteRow[] = [];

  try {
    let q = client()
      .from("wp_imported_posts")
      .select(SELECT_COLS)
      .eq("status", "published")
      .order("wp_published_at", { ascending: false })
      .limit(limit);
    const tags = SECTION_TAGS[section];
    if (tags.length > 0) q = q.overlaps("tags", tags);
    const { data, error } = await q;
    if (!error && data) legacy = data as ImportedPostRow[];
  } catch {
    // ignore
  }

  try {
    let q = client()
      .from("ai_rewritten_articles")
      .select(REWRITE_SELECT_COLS)
      .eq("status", "published")
      .order("published_at", { ascending: false, nullsFirst: false })
      .limit(limit);
    const cats = SECTION_CATEGORIES[section];
    if (cats.length > 0) q = q.in("category", cats);
    const { data, error } = await q;
    if (!error && data) rewrites = data as unknown as RewriteRow[];
  } catch {
    // ignore
  }

  const merged: Array<{ ts: number; article: Article }> = [
    ...legacy.map((r) => ({ ts: legacyOrderKey(r), article: rowToArticle(r, section) })),
    ...rewrites.map((r) => ({ ts: rewriteOrderKey(r), article: rewriteRowToArticle(r, section) })),
  ];
  merged.sort((a, b) => b.ts - a.ts);
  return merged.slice(0, limit).map((m) => m.article);
}

export async function searchLegacyArticles(
  query: string,
  limit = 50,
): Promise<Article[]> {
  const q = (query || "").trim();
  if (!q) return [];
  const like = `%${q.replace(/[%_]/g, " ")}%`;

  let legacy: ImportedPostRow[] = [];
  let rewrites: RewriteRow[] = [];

  try {
    const { data, error } = await client()
      .from("wp_imported_posts")
      .select(SELECT_COLS)
      .eq("status", "published")
      .or(`title.ilike.${like},excerpt.ilike.${like},author_name.ilike.${like}`)
      .order("wp_published_at", { ascending: false })
      .limit(limit);
    if (!error && data) legacy = data as ImportedPostRow[];
  } catch {
    // ignore
  }

  try {
    const { data, error } = await client()
      .from("ai_rewritten_articles")
      .select(REWRITE_SELECT_COLS)
      .eq("status", "published")
      .or(`title.ilike.${like},excerpt.ilike.${like}`)
      .order("published_at", { ascending: false, nullsFirst: false })
      .limit(limit);
    if (!error && data) rewrites = data as unknown as RewriteRow[];
  } catch {
    // ignore
  }

  const merged: Array<{ ts: number; article: Article }> = [
    ...legacy.map((r) => ({ ts: legacyOrderKey(r), article: rowToArticle(r, "news") })),
    ...rewrites.map((r) => ({ ts: rewriteOrderKey(r), article: rewriteRowToArticle(r) })),
  ];
  merged.sort((a, b) => b.ts - a.ts);
  return merged.slice(0, limit).map((m) => m.article);
}

export async function getLegacyRecentSlugs(limit = 200): Promise<string[]> {
  let legacy: string[] = [];
  let rewrites: string[] = [];
  try {
    const { data } = await client()
      .from("wp_imported_posts")
      .select("wp_slug")
      .eq("status", "published")
      .order("wp_published_at", { ascending: false })
      .limit(limit);
    legacy = (data || []).map((r: { wp_slug: string }) => r.wp_slug);
  } catch {
    // ignore
  }
  try {
    const { data } = await client()
      .from("ai_rewritten_articles")
      .select("slug,published_at")
      .eq("status", "published")
      .order("published_at", { ascending: false, nullsFirst: false })
      .limit(limit);
    rewrites = (data || []).map((r: { slug: string }) => r.slug);
  } catch {
    // ignore
  }
  return [...rewrites, ...legacy].slice(0, limit);
}

export async function getLegacyRecentSitemapEntries(
  limit = 5000,
): Promise<{ slug: string; date: string }[]> {
  const out: { slug: string; date: string }[] = [];
  try {
    const { data } = await client()
      .from("wp_imported_posts")
      .select("wp_slug,wp_published_at")
      .eq("status", "published")
      .order("wp_published_at", { ascending: false })
      .limit(limit);
    for (const r of data || []) {
      out.push({
        slug: (r as any).wp_slug,
        date: (r as any).wp_published_at || new Date().toISOString(),
      });
    }
  } catch {
    // ignore
  }
  try {
    const { data } = await client()
      .from("ai_rewritten_articles")
      .select("slug,published_at,created_at")
      .eq("status", "published")
      .order("published_at", { ascending: false, nullsFirst: false })
      .limit(limit);
    for (const r of data || []) {
      out.push({
        slug: (r as any).slug,
        date: (r as any).published_at || (r as any).created_at || new Date().toISOString(),
      });
    }
  } catch {
    // ignore
  }
  out.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
  return out.slice(0, limit);
}

export async function getRecentAiRewrites(limit = 20): Promise<Article[]> {
  const rows = await fetchPublishedRewrites(limit);
  return rows.map((r) => rewriteRowToArticle(r));
}

export async function getLatestImportedArticles(
  limit = 100,
  offset = 0,
): Promise<{ items: Article[]; total: number }> {
  try {
    const { data, error, count } = await client()
      .from("wp_imported_posts")
      .select(SELECT_COLS, { count: "exact" })
      .eq("status", "published")
      .order("wp_published_at", { ascending: false, nullsFirst: false })
      .range(offset, offset + limit - 1);
    if (error || !data) return { items: [], total: 0 };
    return {
      items: (data as ImportedPostRow[]).map((r) => rowToArticle(r)),
      total: count ?? data.length,
    };
  } catch {
    return { items: [], total: 0 };
  }
}
