import Link from "next/link";
import { notFound } from "next/navigation";
import { PARK_MAP } from "@/lib/parks";
import UptimePill from "@/components/charts/UptimePill";
import WaitTimeTodayChart from "@/components/charts/WaitTimeTodayChart";
import WeeklyStatsChart from "@/components/charts/WeeklyStatsChart";

const BACKEND_URL = process.env.BACKEND_URL ?? "http://localhost:3001";

type Tab = "today" | "7d" | "30d";

interface TodaySample {
  recordedAt: string;
  localTime: string;
  isOpen: boolean;
  waitMinutes: number | null;
  fastLaneMinutes: number | null;
}

interface DailyAggregate {
  localDate: string;
  avgWait: number | null;
  maxWait: number | null;
  avgFastLane: number | null;
  maxFastLane: number | null;
  uptimePct: number;
  sampleCount: number;
}

interface ApiResponse {
  park: { id: string; name: string; shortName: string; timezone: string };
  ride: {
    qtRideId: number;
    slug: string;
    name: string;
    isCoaster: boolean;
    hasFastLane: boolean;
    firstSeen: string;
    lastSeen: string;
  };
  live: {
    isOpen: boolean;
    waitMinutes: number;
    hasFastLane: boolean;
    fastLaneMinutes: number | null;
    lastUpdated: string;
  } | null;
  todayLocal: string;
  today: TodaySample[];
  last7d: DailyAggregate[];
  last30d: DailyAggregate[];
  coverage: { daysWith7d: number; daysWith30d: number; todaySampleCount: number };
}

interface PageProps {
  params: Promise<{ id: string; slug: string }>;
  searchParams: Promise<{ tab?: string }>;
}

function parseTab(raw: string | undefined): Tab {
  if (raw === "7d" || raw === "30d") return raw;
  return "today";
}

export default async function RideDetailPage({ params, searchParams }: PageProps) {
  const { id, slug } = await params;
  const { tab: tabParam } = await searchParams;

  const park = PARK_MAP.get(id);
  if (!park) notFound();

  const tab = parseTab(tabParam);

  const res = await fetch(`${BACKEND_URL}/api/parks/${id}/rides/${slug}`, {
    next: { revalidate: 60 },
  });

  if (res.status === 404) {
    return <NoHistoryYet parkId={id} parkName={park.name} slug={slug} />;
  }

  if (!res.ok) {
    return <ErrorState parkId={id} parkName={park.name} />;
  }

  const data: ApiResponse = await res.json();
  const { ride, live, today, last7d, last30d, coverage } = data;

  const last30dUptime = last30d.length
    ? last30d.reduce((s, d) => s + d.uptimePct * d.sampleCount, 0) /
      Math.max(1, last30d.reduce((s, d) => s + d.sampleCount, 0))
    : 0;
  const totalSamples30d = last30d.reduce((s, d) => s + d.sampleCount, 0);

  return (
    <div style={{ minHeight: "100vh", background: "var(--color-bg)" }}>
      {/* ── Header ─────────────────────────────────────────────────────────── */}
      <header style={{
        position: "sticky",
        top: 0,
        zIndex: 20,
        background: "var(--color-bg)",
        borderBottom: "1px solid var(--color-border)",
        padding: "12px 24px",
        display: "flex",
        alignItems: "center",
        gap: 16,
      }}>
        <Link href={`/park/${id}`} style={{
          fontSize: "0.78rem",
          color: "var(--color-text-secondary)",
          textDecoration: "none",
          display: "flex",
          alignItems: "center",
          gap: 6,
        }}>
          ← {park.shortName}
        </Link>
        <div style={{ width: 1, height: 16, background: "var(--color-border)" }} />
        <span style={{ fontSize: "0.9rem", fontWeight: 600, color: "var(--color-text)", letterSpacing: "-0.01em" }}>
          {ride.name}
        </span>
        {ride.isCoaster && (
          <span style={{ fontSize: "0.7rem", color: "var(--color-text-muted)" }}>🎢 Coaster</span>
        )}
      </header>

      <main style={{ padding: "24px 32px", maxWidth: 1024, margin: "0 auto", display: "flex", flexDirection: "column", gap: 28 }}>

        {/* ── Current state + uptime row ────────────────────────────────────── */}
        <section style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
          <CurrentStatePill live={live} hasFastLane={ride.hasFastLane} />
          {last30d.length > 0 && (
            <UptimePill uptime={last30dUptime} sampleCount={totalSamples30d} label="Uptime · last 30 days" />
          )}
        </section>

        {/* ── Range tabs ────────────────────────────────────────────────────── */}
        <section>
          <RangeTabs parkId={id} slug={slug} active={tab} coverage={coverage} />
        </section>

        {/* ── Charts ────────────────────────────────────────────────────────── */}
        <section>
          {tab === "today" && (
            <TodayPanel
              samples={today}
              hasFastLane={ride.hasFastLane}
              sampleCount={coverage.todaySampleCount}
              parkId={id}
              firstSeen={ride.firstSeen}
            />
          )}
          {tab === "7d" && (
            <RangePanel
              data={last7d}
              hasFastLane={ride.hasFastLane}
              days={coverage.daysWith7d}
              minDays={3}
              windowLabel="7 days"
              firstSeen={ride.firstSeen}
            />
          )}
          {tab === "30d" && (
            <RangePanel
              data={last30d}
              hasFastLane={ride.hasFastLane}
              days={coverage.daysWith30d}
              minDays={10}
              windowLabel="30 days"
              firstSeen={ride.firstSeen}
            />
          )}
        </section>

        {/* ── Attribution ───────────────────────────────────────────────────── */}
        <footer style={{ marginTop: 12, fontSize: "0.68rem", color: "var(--color-text-dim)" }}>
          Wait times via{" "}
          <a href="https://queue-times.com" target="_blank" rel="noopener noreferrer" style={{ color: "var(--color-text-muted)" }}>
            queue-times.com
          </a>
          {ride.hasFastLane && <> · Fast Lane via sixflags.com</>}
          {" · "}Tracking since {formatDate(ride.firstSeen)}
        </footer>
      </main>
    </div>
  );
}

// ── Sub-components ─────────────────────────────────────────────────────────

function CurrentStatePill({
  live,
  hasFastLane,
}: {
  live: ApiResponse["live"];
  hasFastLane: boolean;
}) {
  if (!live) {
    return (
      <div style={{
        padding: "12px 16px",
        background: "var(--color-surface)",
        border: "1px solid var(--color-border)",
        borderRadius: 8,
        minWidth: 140,
      }}>
        <span style={{ fontSize: "0.65rem", textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--color-text-muted)" }}>
          Current
        </span>
        <div style={{ fontSize: "0.95rem", fontWeight: 600, color: "var(--color-text-muted)", marginTop: 4 }}>
          Offline
        </div>
      </div>
    );
  }

  const fg = live.isOpen ? "var(--color-open-text)" : "var(--color-text-muted)";
  const bg = live.isOpen ? "var(--color-open-bg)" : "var(--color-surface)";
  const border = live.isOpen ? "var(--color-open-border)" : "var(--color-border)";

  return (
    <div style={{
      padding: "12px 16px",
      background: bg,
      border: `1px solid ${border}`,
      borderRadius: 8,
      minWidth: 140,
    }}>
      <span style={{ fontSize: "0.65rem", textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--color-text-muted)" }}>
        Right now
      </span>
      <div style={{ fontSize: "1.5rem", fontWeight: 700, color: fg, lineHeight: 1, marginTop: 4 }}>
        {!live.isOpen ? "Closed" : live.waitMinutes > 0 ? `${live.waitMinutes} min` : "Walk-on"}
      </div>
      {hasFastLane && live.isOpen && live.fastLaneMinutes !== null && (
        <div style={{ fontSize: "0.72rem", color: "var(--color-accent)", fontWeight: 600, marginTop: 4 }}>
          ⚡ {live.fastLaneMinutes > 0 ? `${live.fastLaneMinutes} min` : "walk-on"}
        </div>
      )}
    </div>
  );
}

function RangeTabs({
  parkId,
  slug,
  active,
  coverage,
}: {
  parkId: string;
  slug: string;
  active: Tab;
  coverage: ApiResponse["coverage"];
}) {
  const tabs: { id: Tab; label: string; enabled: boolean }[] = [
    { id: "today", label: "Today", enabled: true },
    { id: "7d", label: "7 days", enabled: coverage.daysWith7d >= 1 },
    { id: "30d", label: "30 days", enabled: coverage.daysWith30d >= 1 },
  ];

  return (
    <div style={{ display: "flex", gap: 6, borderBottom: "1px solid var(--color-border)", paddingBottom: 0 }}>
      {tabs.map((t) => {
        const isActive = t.id === active;
        const style: React.CSSProperties = {
          padding: "8px 16px",
          fontSize: "0.78rem",
          fontWeight: 600,
          color: isActive ? "var(--color-text)" : t.enabled ? "var(--color-text-muted)" : "var(--color-text-dim)",
          background: "transparent",
          border: "none",
          borderBottom: isActive ? "2px solid var(--color-accent)" : "2px solid transparent",
          marginBottom: -1,
          textDecoration: "none",
          cursor: t.enabled ? "pointer" : "not-allowed",
        };
        if (!t.enabled) {
          return <span key={t.id} style={style} title="Not enough history yet">{t.label}</span>;
        }
        return (
          <Link key={t.id} href={`/park/${parkId}/ride/${slug}?tab=${t.id}`} style={style}>
            {t.label}
          </Link>
        );
      })}
    </div>
  );
}

function TodayPanel({
  samples,
  hasFastLane,
  sampleCount,
  parkId,
  firstSeen,
}: {
  samples: TodaySample[];
  hasFastLane: boolean;
  sampleCount: number;
  parkId: string;
  firstSeen: string;
}) {
  if (sampleCount < 12) {
    return (
      <EmptyState
        title="Not enough data for today yet"
        body={`We sample every 5 minutes while ${parkId} is open. The chart appears once we've collected about an hour of data. Tracking started ${formatDate(firstSeen)}.`}
      />
    );
  }
  return (
    <div>
      <ChartHeading>Wait time today</ChartHeading>
      <WaitTimeTodayChart samples={samples} hasFastLane={hasFastLane} />
    </div>
  );
}

function RangePanel({
  data,
  hasFastLane,
  days,
  minDays,
  windowLabel,
  firstSeen,
}: {
  data: DailyAggregate[];
  hasFastLane: boolean;
  days: number;
  minDays: number;
  windowLabel: string;
  firstSeen: string;
}) {
  if (days < minDays) {
    return (
      <EmptyState
        title={`Not enough data for the ${windowLabel} view yet`}
        body={`Need at least ${minDays} days of tracking; have ${days}. Tracking started ${formatDate(firstSeen)}.`}
      />
    );
  }

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 28 }}>
      <div>
        <ChartHeading>Regular wait — avg &amp; max per day</ChartHeading>
        <WeeklyStatsChart data={data} hasFastLane={hasFastLane} mode="regular" />
      </div>
      {hasFastLane && (
        <div>
          <ChartHeading>Fast Lane wait — avg &amp; max per day</ChartHeading>
          <WeeklyStatsChart data={data} hasFastLane={hasFastLane} mode="fastLane" />
        </div>
      )}
    </div>
  );
}

function ChartHeading({ children }: { children: React.ReactNode }) {
  return (
    <h3 style={{
      fontSize: "0.72rem",
      fontWeight: 700,
      color: "var(--color-text)",
      letterSpacing: "0.06em",
      textTransform: "uppercase",
      margin: "0 0 12px",
    }}>
      {children}
    </h3>
  );
}

function EmptyState({ title, body }: { title: string; body: string }) {
  return (
    <div style={{
      padding: "20px 24px",
      background: "var(--color-surface)",
      border: "1px dashed var(--color-border)",
      borderRadius: 8,
      color: "var(--color-text-muted)",
      fontSize: "0.82rem",
      lineHeight: 1.55,
    }}>
      <div style={{ fontWeight: 600, color: "var(--color-text-secondary)", marginBottom: 4 }}>
        {title}
      </div>
      {body}
    </div>
  );
}

function NoHistoryYet({ parkId, parkName, slug }: { parkId: string; parkName: string; slug: string }) {
  return (
    <div style={{ minHeight: "100vh", background: "var(--color-bg)", padding: "48px 32px" }}>
      <div style={{ maxWidth: 640, margin: "0 auto" }}>
        <Link href={`/park/${parkId}`} style={{ fontSize: "0.78rem", color: "var(--color-text-secondary)", textDecoration: "none" }}>
          ← {parkName}
        </Link>
        <h1 style={{ fontSize: "1.4rem", fontWeight: 700, color: "var(--color-text)", marginTop: 24, marginBottom: 12 }}>
          No history yet for {decodeURIComponent(slug).replace(/-/g, " ")}
        </h1>
        <p style={{ color: "var(--color-text-muted)", lineHeight: 1.6, fontSize: "0.9rem" }}>
          We start tracking a ride the first time we see it open in the live feed. Check back after the park is open — once we&apos;ve recorded an hour of samples, charts will appear here.
        </p>
      </div>
    </div>
  );
}

function ErrorState({ parkId, parkName }: { parkId: string; parkName: string }) {
  return (
    <div style={{ minHeight: "100vh", background: "var(--color-bg)", padding: "48px 32px" }}>
      <div style={{ maxWidth: 640, margin: "0 auto" }}>
        <Link href={`/park/${parkId}`} style={{ fontSize: "0.78rem", color: "var(--color-text-secondary)", textDecoration: "none" }}>
          ← {parkName}
        </Link>
        <h1 style={{ fontSize: "1.4rem", fontWeight: 700, color: "var(--color-text)", marginTop: 24, marginBottom: 12 }}>
          Could not load ride history
        </h1>
        <p style={{ color: "var(--color-text-muted)", lineHeight: 1.6, fontSize: "0.9rem" }}>
          The backend is unreachable. Try again in a moment.
        </p>
      </div>
    </div>
  );
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      year: "numeric",
    });
  } catch {
    return iso;
  }
}
