import type { Metadata } from 'next';
import Link from 'next/link';
import { businessDate, forVenue, getDb, nextOpening, isWithinSchedule } from '@pintrush/db';
import { ButtonLink } from '@/components/ui/Button';
import { CalendarIcon, QrIcon, TvIcon } from '@/components/ui/icons';
import { CopyButton } from '@/components/host/client';
import { formatBusinessDate, formatDateTime, formatNumber, formatRelative } from '@/components/host/format';
import { EmptyState, linkStyles, PageHeader, Panel, StatCard, StatusBadge } from '@/components/host/ui';
import { requireHost } from '@/lib/auth/session';
import { joinUrl, tvUrl } from '@/lib/server/tokens';
import { siteUrl } from '@/lib/site';
import { roomLiveStatus, type RoomLiveStatus } from '../_lib/data';

export const metadata: Metadata = { title: 'Dashboard' };

const DAY_MS = 86_400_000;

function LiveStatus({ status }: { status: RoomLiveStatus }) {
  if (!status.reachable) return <StatusBadge status="PAUSED" label="Game server unreachable" />;
  if (!status.active) return <StatusBadge status="COMPLETED" label="Idle · attract mode" />;
  return (
    <span className="inline-flex flex-wrap items-center gap-2">
      <StatusBadge status="LIVE" label={status.activeEventKind === 'CHAMPIONSHIP' ? 'Championship live' : 'Always-on live'} />
      {status.activeEventName && <span className="text-sm text-muted">{status.activeEventName}</span>}
    </span>
  );
}

export default async function HostDashboardPage() {
  const { venue } = await requireHost('/host');
  const db = getDb();
  const scope = forVenue(db, venue.id);
  const now = Date.now();
  const tonight = businessDate(venue.timezone, now);
  const site = siteUrl.origin;

  const [rooms, settings, alwaysOnEvents, upcoming, metrics] = await Promise.all([
    scope.rooms.list(),
    scope.venue.settings(),
    scope.events.list({ kind: 'ALWAYS_ON', limit: 20 }),
    scope.events.list({ kind: 'CHAMPIONSHIP', status: ['SCHEDULED', 'LIVE', 'PAUSED'], order: 'asc', limit: 5 }),
    scope.metrics({ from: new Date(now - 7 * DAY_MS), to: new Date(now) }),
  ]);
  const activeRooms = rooms.filter((r) => r.status === 'ACTIVE');
  const roomCards = await Promise.all(
    activeRooms.map(async (room) => ({
      room,
      tv: await tvUrl(site, room),
      join: joinUrl(site, venue.joinCode, room.id),
      status: await roomLiveStatus(room.id),
      tonight: alwaysOnEvents.find((e) => e.roomId === room.id && e.businessDate === tonight) ?? null,
    })),
  );
  const alwaysOnEnabled = settings?.alwaysOn.enabled ?? false;
  const inSchedule = settings ? isWithinSchedule(settings, venue.timezone, now) : false;
  const opensAt = settings ? nextOpening(settings, venue.timezone, now) : null;

  return (
    <div className="flex flex-col gap-8">
      <PageHeader
        kicker={formatBusinessDate(tonight)}
        title={`Tonight at ${venue.name}`}
        description={
          <>
            Guests join at <strong className="font-semibold text-fg">{site.replace(/^https?:\/\//, '')}/join/{venue.joinCode}</strong> — or by scanning the QR code on your TV.
          </>
        }
        actions={
          <ButtonLink href="/host/events/new">
            <CalendarIcon /> New championship
          </ButtonLink>
        }
      />

      <Panel title="Rooms & TV screens" description="Open the TV screen on the bar’s TV browser. Each link only shows the game — it can’t control anything." id="rooms">
        {roomCards.length === 0 ? (
          <EmptyState title="No rooms yet">Contact PintRush support to add a room for your venue.</EmptyState>
        ) : (
          <ul className="grid gap-4 lg:grid-cols-2">
            {roomCards.map(({ room, tv, join, status, tonight: event }) => (
              <li key={room.id} className="flex flex-col gap-4 rounded-2xl border border-line bg-night/40 p-5">
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div>
                    <h3 className="font-display text-lg font-semibold">{room.name}</h3>
                    <p className="mt-1 text-sm text-subtle">
                      Join code <span className="num font-semibold text-amber-soft">{venue.joinCode}</span>
                    </p>
                  </div>
                  <LiveStatus status={status} />
                </div>
                <div className="flex flex-wrap gap-2">
                  <ButtonLink href={tv} target="_blank" rel="noopener noreferrer" prefetch={false} size="sm" variant="accent">
                    <TvIcon /> Open TV screen<span className="sr-only"> (opens in a new tab)</span>
                  </ButtonLink>
                  <CopyButton value={tv} label="Copy TV link" />
                  <ButtonLink href={`/host/rooms/${room.id}/poster`} size="sm" variant="secondary">
                    <QrIcon /> Print QR poster
                  </ButtonLink>
                </div>
                <div className="flex flex-wrap items-center justify-between gap-3 border-t border-line/60 pt-4 text-sm">
                  <span className="text-muted">
                    Tonight’s always-on:{' '}
                    {event ? (
                      <>
                        <StatusBadge status={event.status} />{' '}
                        <Link href={`/host/events/${event.id}`} className={linkStyles}>
                          Control
                        </Link>
                      </>
                    ) : !alwaysOnEnabled ? (
                      <>
                        off ·{' '}
                        <Link href="/host/settings" className={linkStyles}>
                          turn on in Settings
                        </Link>
                      </>
                    ) : inSchedule ? (
                      'starting within a minute'
                    ) : opensAt ? (
                      `opens ${formatDateTime(opensAt, venue.timezone)}`
                    ) : (
                      'no opening hours set'
                    )}
                  </span>
                  <CopyButton value={join} label="Copy join link" />
                </div>
              </li>
            ))}
          </ul>
        )}
      </Panel>

      <div className="grid gap-8 lg:grid-cols-[1.4fr_1fr]">
        <Panel
          title="Upcoming championships"
          actions={
            <Link href="/host/events" className={`${linkStyles} text-sm`}>
              All events
            </Link>
          }
        >
          {upcoming.length === 0 ? (
            <EmptyState title="Nothing scheduled" action={<ButtonLink href="/host/events/new" size="sm">Schedule a championship</ButtonLink>}>
              A championship is a 50-minute hosted show with its own leaderboard — perfect for a quiet weeknight.
            </EmptyState>
          ) : (
            <ul className="divide-y divide-line/60">
              {upcoming.map((e) => (
                <li key={e.id} className="flex flex-wrap items-center justify-between gap-3 py-3 first:pt-0 last:pb-0">
                  <div className="min-w-0">
                    <p className="font-semibold text-fg">{e.name}</p>
                    <p className="text-sm text-muted">
                      {formatDateTime(e.scheduledAt, venue.timezone)}
                      {e.scheduledAt && ` · ${formatRelative(e.scheduledAt.getTime(), now)}`} · {e.room.name}
                    </p>
                  </div>
                  <div className="flex items-center gap-3">
                    <StatusBadge status={e.status} />
                    <ButtonLink href={`/host/events/${e.id}`} size="sm" variant={e.status === 'SCHEDULED' ? 'secondary' : 'primary'}>
                      {e.status === 'SCHEDULED' ? 'Open control' : 'Control'}
                    </ButtonLink>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </Panel>

        <Panel
          title="Last 7 days"
          actions={
            <Link href="/host/metrics" className={`${linkStyles} text-sm`}>
              Metrics
            </Link>
          }
        >
          <dl className="grid grid-cols-2 gap-3">
            <StatCard label="Unique guests" value={formatNumber(metrics.uniqueGuests)} tone="violet" />
            <StatCard label="Joins" value={formatNumber(metrics.joins)} tone="cyan" />
            <StatCard label="Rounds played" value={formatNumber(metrics.roundsCompleted)} tone="lime" />
            <StatCard label="Came back" value={formatNumber(metrics.repeatPlayers)} hint="on 2+ nights" tone="amber" />
          </dl>
        </Panel>
      </div>
    </div>
  );
}
