import { WeekCalendar } from "@/components/WeekCalendar";
import { MobileCardList } from "@/components/MobileCardList";
import { WeekNav } from "@/components/WeekNav";
import { Legend } from "@/components/Legend";
import { EmptyState } from "@/components/EmptyState";
import { PARKS, groupByRegion } from "@/lib/parks";
import { openDb, getDateRange } from "@/lib/db";
import { getTodayLocal, isWithinOperatingWindow } from "@/lib/env";
import { fetchLiveRides } from "@/lib/scrapers/queuetimes";
import { QUEUE_TIMES_IDS } from "@/lib/queue-times-map";

interface PageProps {
  searchParams: Promise<{ week?: string }>;
}

function getWeekStart(param: string | undefined): string {
  if (param && /^\d{4}-\d{2}-\d{2}$/.test(param)) {
    const d = new Date(param + "T00:00:00");
    if (!isNaN(d.getTime())) {
      d.setDate(d.getDate() - d.getDay());
      return d.toISOString().slice(0, 10);
    }
  }
  const todayIso = getTodayLocal();
  const d = new Date(todayIso + "T00:00:00");
  d.setDate(d.getDate() - d.getDay());
  return d.toISOString().slice(0, 10);
}

function getWeekDates(sundayIso: string): string[] {
  return Array.from({ length: 7 }, (_, i) => {
    const d = new Date(sundayIso + "T00:00:00");
    d.setDate(d.getDate() + i);
    return d.toISOString().slice(0, 10);
  });
}

function getCurrentWeekStart(): string {
  const todayIso = getTodayLocal();
  const d = new Date(todayIso + "T00:00:00");
  d.setDate(d.getDate() - d.getDay());
  return d.toISOString().slice(0, 10);
}

export default async function HomePage({ searchParams }: PageProps) {
  const params = await searchParams;
  const weekStart = getWeekStart(params.week);
  const weekDates = getWeekDates(weekStart);
  const endDate = weekDates[6];
  const today = getTodayLocal();
  const isCurrentWeek = weekStart === getCurrentWeekStart();

  const db = openDb();
  const data = getDateRange(db, weekStart, endDate);
  db.close();

  const scrapedCount = Object.values(data).reduce(
    (sum, parkData) => sum + Object.keys(parkData).length,
    0
  );

  // Fetch live ride counts for parks open today (cached 5 min via Queue-Times).
  // Only shown when the current time is within 1h before open to 1h after close.
  let rideCounts: Record<string, number> = {};
  if (weekDates.includes(today)) {
    const openTodayParks = PARKS.filter((p) => {
      const dayData = data[p.id]?.[today];
      if (!dayData?.isOpen || !QUEUE_TIMES_IDS[p.id] || !dayData.hoursLabel) return false;
      return isWithinOperatingWindow(dayData.hoursLabel);
    });
    const results = await Promise.all(
      openTodayParks.map(async (p) => {
        const result = await fetchLiveRides(QUEUE_TIMES_IDS[p.id], null, 300);
        const count = result ? result.rides.filter((r) => r.isOpen).length : 0;
        return [p.id, count] as [string, number];
      })
    );
    rideCounts = Object.fromEntries(results.filter(([, count]) => count > 0));
  }

  const visibleParks = PARKS.filter((park) =>
    weekDates.some((date) => data[park.id]?.[date]?.isOpen)
  );

  const grouped = groupByRegion(visibleParks);

  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)",
      }}>
        {/* Row 1: Title + park count */}
        <div style={{
          padding: "12px 16px 10px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 12,
        }}>
          <span style={{
            fontSize: "1.1rem",
            fontWeight: 700,
            color: "var(--color-text)",
            letterSpacing: "-0.02em",
          }}>
            Thoosie Calendar
          </span>

          <span style={{
            background: visibleParks.length > 0 ? "var(--color-open-bg)" : "var(--color-surface)",
            border: `1px solid ${visibleParks.length > 0 ? "var(--color-open-border)" : "var(--color-border)"}`,
            borderRadius: 20,
            padding: "4px 14px",
            fontSize: "0.78rem",
            color: visibleParks.length > 0 ? "var(--color-open-hours)" : "var(--color-text-muted)",
            fontWeight: 600,
          }}>
            {visibleParks.length} of {PARKS.length} parks open
          </span>
        </div>

        {/* Row 2: Week nav + legend (legend hidden on mobile) */}
        <div style={{
          padding: "8px 16px 10px",
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 16,
          borderTop: "1px solid var(--color-border-subtle)",
        }}>
          <WeekNav
            weekStart={weekStart}
            weekDates={weekDates}
            isCurrentWeek={isCurrentWeek}
          />
          <div className="hidden sm:flex">
            <Legend />
          </div>
        </div>
      </header>

      {/* ── Main content ───────────────────────────────────────────────────── */}
      <main className="px-4 sm:px-6 pb-12">
        {scrapedCount === 0 ? (
          <EmptyState />
        ) : (
          <>
            {/* Mobile: card list (hidden on lg+) */}
            <div className="lg:hidden">
              <MobileCardList
                grouped={grouped}
                weekDates={weekDates}
                data={data}
                today={today}
                rideCounts={rideCounts}
              />
            </div>

            {/* Desktop: week table (hidden below lg) */}
            <div className="hidden lg:block">
              <WeekCalendar
                parks={visibleParks}
                weekDates={weekDates}
                data={data}
                grouped={grouped}
                rideCounts={rideCounts}
              />
            </div>
          </>
        )}
      </main>
    </div>
  );
}
