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

export const dynamic = "force-dynamic";

interface NewsItem {
  slug: string;
  title: string;
  published_at: string;
  source_code: string;
}

interface EventItem {
  slug: string | null;
  short_name: string;
  name: string;
  start_date: string;
  city: string | null;
  country: string | null;
}

const SOURCE_CODES: { match: RegExp; code: string }[] = [
  { match: /blackmagic|davinci/i, code: "BMD" },
  { match: /magewell/i, code: "MGW" },
  { match: /aja/i, code: "AJA" },
  { match: /sony/i, code: "SONY" },
  { match: /matrox/i, code: "MTRX" },
  { match: /telestream/i, code: "TLST" },
  { match: /grass valley/i, code: "GV" },
  { match: /lawo/i, code: "LAWO" },
  { match: /calrec/i, code: "CLRC" },
  { match: /zixi/i, code: "ZIXI" },
  { match: /liveu/i, code: "LVU" },
  { match: /netflix/i, code: "NFLX" },
  { match: /youtube/i, code: "YT" },
  { match: /amazon|aws/i, code: "AWS" },
];

function codeFor(title: string): string {
  for (const { match, code } of SOURCE_CODES) if (match.test(title)) return code;
  return "WIRE";
}

function hhmm(iso: string): string {
  const d = new Date(iso);
  const h = String(d.getUTCHours()).padStart(2, "0");
  const m = String(d.getUTCMinutes()).padStart(2, "0");
  return `${h}:${m}`;
}

function fmtEventDate(iso: string): string {
  // Show "MMM DD" (no year) so each row stays compact.
  try {
    return new Date(iso).toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      timeZone: "UTC",
    });
  } catch {
    return iso.slice(5, 10);
  }
}

// Server-side fetches return arrays — but a network/RLS error can throw.
// Each is wrapped so a partial failure renders an empty row rather than
// crashing the whole component (the silent build crash that took down
// the prior incarnation of this component was caused by an uncaught
// throw inside an async server component).
async function loadNews(sb: any): Promise<NewsItem[]> {
  try {
    const [wp, ai] = await Promise.all([
      sb
        .from("wp_imported_posts")
        .select("wp_slug, title, wp_published_at")
        .eq("status", "published")
        .order("wp_published_at", { ascending: false })
        .limit(12),
      sb
        .from("ai_rewritten_articles")
        .select("slug, title, published_at")
        .eq("status", "published")
        .order("published_at", { ascending: false, nullsFirst: false })
        .limit(6),
    ]);
    const items: NewsItem[] = [];
    for (const r of (wp.data || []) as any[]) {
      items.push({
        slug: r.wp_slug,
        title: r.title,
        published_at: r.wp_published_at,
        source_code: codeFor(r.title || ""),
      });
    }
    for (const r of (ai.data || []) as any[]) {
      items.push({
        slug: r.slug,
        title: r.title,
        published_at: r.published_at,
        source_code: codeFor(r.title || ""),
      });
    }
    items.sort(
      (a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime()
    );
    return items.slice(0, 14);
  } catch {
    return [];
  }
}

async function loadEvents(sb: any): Promise<EventItem[]> {
  try {
    const { data } = await sb
      .from("events")
      .select("slug, short_name, name, start_date, city, country")
      .in("status", ["confirmed", "tentative"])
      .gte("start_date", new Date().toISOString().slice(0, 10))
      .order("start_date", { ascending: true })
      .limit(12);
    return ((data || []) as any[]).map((r) => ({
      slug: r.slug || null,
      short_name: r.short_name || r.name,
      name: r.name,
      start_date: r.start_date,
      city: r.city,
      country: r.country,
    }));
  } catch {
    return [];
  }
}

export default async function DoubleTicker() {
  const sb = createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      db: { schema: (process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "av") as "public" },
      auth: { persistSession: false },
    }
  );

  const [news, events] = await Promise.all([loadNews(sb), loadEvents(sb)]);

  // If both queries failed, render nothing — better than a half-blank bar.
  if (news.length === 0 && events.length === 0) return null;

  return (
    <div role="region" aria-label="Live wire and upcoming events">
      {/* Row 1 — Live wire (news, right-to-left). */}
      {news.length > 0 && (
        <div className="bb-tick-bar w-full overflow-hidden">
          <div className="max-w-container mx-auto px-4 h-[34px] flex items-center gap-4">
            <span className="bb-tick-label" aria-label="Live wire">
              <span className="bb-tick-pulse" aria-hidden="true" />
              <span>Live</span>
            </span>
            <div className="overflow-hidden flex-1">
              <div className="bb-marquee">
                {[...news, ...news].map((it, i) => (
                  <Link
                    key={`n-${it.slug}-${i}`}
                    href={`/news/${it.slug}`}
                    className="bb-tick-item"
                  >
                    <span className="bb-tick-time">{hhmm(it.published_at)}</span>
                    <span className="bb-tick-code">{it.source_code}</span>
                    <span className="bb-tick-text">{it.title}</span>
                  </Link>
                ))}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Row 2 — Industry calendar (events, left-to-right, slower). */}
      {events.length > 0 && (
        <div className="bb-tick-bar w-full overflow-hidden">
          <div className="max-w-container mx-auto px-4 h-[34px] flex items-center gap-4">
            <span className="bb-tick-label bb-tick-label--cyan" aria-label="On calendar">
              <span className="bb-tick-pulse bb-tick-pulse--cyan" aria-hidden="true" />
              <span>Calendar</span>
            </span>
            <div className="overflow-hidden flex-1">
              <div className="bb-marquee bb-marquee--reverse bb-marquee--slow">
                {[...events, ...events].map((ev, i) => {
                  const where = [ev.city, ev.country].filter(Boolean).join(", ");
                  const inner = (
                    <span className="bb-tick-item">
                      <span className="bb-tick-time">{fmtEventDate(ev.start_date)}</span>
                      <span className="bb-tick-code bb-tick-code--cyan">{ev.short_name}</span>
                      <span className="bb-tick-text">
                        {ev.name}
                        {where ? ` — ${where}` : ""}
                      </span>
                    </span>
                  );
                  return ev.slug ? (
                    <Link key={`e-${ev.short_name}-${i}`} href={`/events/${ev.slug}`}>
                      {inner}
                    </Link>
                  ) : (
                    <span key={`e-${ev.short_name}-${i}`}>{inner}</span>
                  );
                })}
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
