import Link from "next/link";
import { notFound } from "next/navigation";
import { db } from "@/lib/db";
import { requireConfAccess } from "@/lib/rbac";
import { Card, EmptyState, PageHeader, btn, input, Field } from "@/components/ui";
import { dayKey, fmtDay } from "@/lib/utils";
import { SESSION_TYPES, SESSION_TYPE_COLORS } from "@/lib/constants";
import { AgendaBoard, type BoardLane } from "@/components/agenda-board";
import { createSession, createTrack, deleteSession, deleteTrack, updateSession, updateTrack } from "../actions";

export const metadata = { title: "Agenda" };

const TZ_OFFSET = "+05:30";

function toLocalInput(d: Date): string {
  return d.toLocaleString("sv-SE", { timeZone: "Asia/Kolkata" }).slice(0, 16).replace(" ", "T");
}

function confDays(startAt: Date, endAt: Date): string[] {
  const days: string[] = [];
  const cursor = new Date(`${dayKey(startAt)}T12:00:00${TZ_OFFSET}`);
  while (dayKey(cursor) <= dayKey(endAt) && days.length < 30) {
    days.push(dayKey(cursor));
    cursor.setDate(cursor.getDate() + 1);
  }
  return days;
}

export default async function AgendaPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<{ error?: string; day?: string; edit?: string }>;
}) {
  const { id } = await params;
  const { error, day: dayParam, edit } = await searchParams;
  await requireConfAccess(id, "agenda.manage");

  const conf = await db.conference.findUnique({ where: { id }, select: { startAt: true, endAt: true } });
  if (!conf) notFound();
  const days = confDays(conf.startAt, conf.endAt);

  const [tracks, rooms, speakers, allSessions] = await Promise.all([
    db.track.findMany({ where: { conferenceId: id }, orderBy: { name: "asc" }, include: { _count: { select: { sessions: true } } } }),
    db.room.findMany({ where: { conferenceId: id }, orderBy: { name: "asc" }, include: { venue: true } }),
    db.speaker.findMany({ where: { conferenceId: id }, orderBy: { name: "asc" } }),
    db.session.findMany({
      where: { conferenceId: id },
      orderBy: { startAt: "asc" },
      include: { track: true, room: { include: { venue: true } }, speakers: { include: { speaker: true } } },
    }),
  ]);

  const sessionsByDay = new Map<string, typeof allSessions>();
  for (const s of allSessions) {
    const k = dayKey(s.startAt);
    if (!sessionsByDay.has(k)) sessionsByDay.set(k, []);
    sessionsByDay.get(k)!.push(s);
  }
  const day = dayParam && days.includes(dayParam) ? dayParam : days.find((d) => sessionsByDay.has(d)) ?? days[0];
  const daySessions = sessionsByDay.get(day) ?? [];

  // hall lanes for the selected day
  const fmtT = (d: Date) => d.toLocaleTimeString("en-IN", { hour: "numeric", minute: "2-digit", hour12: true, timeZone: "Asia/Kolkata" });
  const laneMap = new Map<string, BoardLane>();
  for (const s of daySessions) {
    const key = s.roomId ?? "none";
    if (!laneMap.has(key)) {
      laneMap.set(key, {
        key,
        title: s.room?.name ?? "No hall assigned",
        sub: s.room ? [s.room.venue?.name, s.room.capacity ? `${s.room.capacity} seats` : null].filter(Boolean).join(" · ") : "assign a hall when editing",
        sessions: [],
      });
    }
    laneMap.get(key)!.sessions.push({
      id: s.id,
      title: s.title,
      type: s.type,
      typeCls: SESSION_TYPE_COLORS[s.type] ?? "",
      start: fmtT(s.startAt),
      end: fmtT(s.endAt),
      durationMin: Math.round((s.endAt.getTime() - s.startAt.getTime()) / 60000),
      trackName: s.track?.name,
      trackColor: s.track?.color,
      speakers: s.speakers.map(({ speaker }) => speaker.name),
      mode: s.mode,
    });
  }
  const lanes = [...laneMap.values()].sort((a, b) => (a.key === "none" ? 1 : b.key === "none" ? -1 : a.title.localeCompare(b.title)));

  const editing = edit ? allSessions.find((s) => s.id === edit) : undefined;
  const defaultStart = `${day}T10:00`;
  const defaultEnd = `${day}T11:00`;

  return (
    <main>
      <PageHeader
        title="Agenda builder"
        sub="Day-wise schedule per hall. Drag sessions to reorder — durations and gaps are preserved, times reflow. Conflicts are rejected on save."
        action={<Link href={`/dashboard/c/${id}/venue`} className={btn.secondary}>🏛️ Manage venue & halls</Link>}
      />
      {error && <div className="mb-5 rounded-lg border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-600">⚠️ {error}</div>}

      {/* Day tabs */}
      <div className="mb-6 flex flex-wrap gap-2">
        {days.map((d, i) => {
          const count = sessionsByDay.get(d)?.length ?? 0;
          const active = d === day;
          return (
            <Link
              key={d}
              href={`/dashboard/c/${id}/agenda?day=${d}`}
              className={`rounded-xl border px-4 py-2 text-sm transition ${
                active
                  ? "border-transparent bg-gradient-to-r from-indigo-500 to-violet-500 font-semibold text-white shadow-md shadow-indigo-500/25"
                  : "border-white/70 bg-white/60 text-zinc-400 backdrop-blur hover:bg-white/90"
              }`}
            >
              <span className="font-semibold">Day {i + 1}</span>
              <span className={`ml-2 text-xs ${active ? "text-white/80" : "text-zinc-500"}`}>
                {fmtDay(new Date(`${d}T12:00:00${TZ_OFFSET}`)).split(",")[0]} · {count}
              </span>
            </Link>
          );
        })}
      </div>

      <div className="grid gap-6 xl:grid-cols-5">
        <div className="xl:col-span-3">
          <h2 className="mb-3 text-sm font-semibold uppercase tracking-wider text-zinc-400">{fmtDay(new Date(`${day}T12:00:00${TZ_OFFSET}`))}</h2>
          {lanes.length === 0 ? (
            <EmptyState title={`Nothing scheduled on this day`} body="Add a session with the form on the right — pick this day's date and a hall, and it appears here as a draggable card." />
          ) : (
            <AgendaBoard confId={id} day={day} lanes={lanes} />
          )}
        </div>

        <div className="space-y-4 xl:col-span-2">
          {/* Create / edit session */}
          <Card className="p-5">
            <div className="flex items-center justify-between">
              <h2 className="text-sm font-semibold text-zinc-200">{editing ? "Edit session" : "Add session"}</h2>
              {editing && (
                <div className="flex gap-2">
                  <form action={deleteSession.bind(null, id, editing.id)}>
                    <button className="text-xs text-red-600 hover:underline">Delete</button>
                  </form>
                  <Link href={`/dashboard/c/${id}/agenda?day=${day}`} className="text-xs text-zinc-500 hover:underline">Cancel</Link>
                </div>
              )}
            </div>
            <form
              action={editing ? updateSession.bind(null, id, editing.id) : createSession.bind(null, id)}
              key={editing?.id ?? "new"}
              className="mt-4 space-y-3"
            >
              <input type="hidden" name="day" value={day} />
              <Field name="title" title="Title *">
                <input id="title" name="title" required defaultValue={editing?.title ?? ""} className={input} placeholder="Opening Keynote: …" />
              </Field>
              <div className="grid grid-cols-2 gap-3">
                <Field name="startAt" title="Starts *">
                  <input id="startAt" name="startAt" type="datetime-local" required defaultValue={editing ? toLocalInput(editing.startAt) : defaultStart} className={input} />
                </Field>
                <Field name="endAt" title="Ends *">
                  <input id="endAt" name="endAt" type="datetime-local" required defaultValue={editing ? toLocalInput(editing.endAt) : defaultEnd} className={input} />
                </Field>
                <Field name="type" title="Type">
                  <select id="type" name="type" className={input} defaultValue={editing?.type ?? "TALK"}>
                    {SESSION_TYPES.map((t) => <option key={t} value={t}>{t[0] + t.slice(1).toLowerCase()}</option>)}
                  </select>
                </Field>
                <Field name="mode" title="Mode">
                  <select id="mode" name="mode" className={input} defaultValue={editing?.mode ?? "PHYSICAL"}>
                    <option value="PHYSICAL">Physical</option>
                    <option value="VIRTUAL">Virtual</option>
                    <option value="HYBRID">Hybrid</option>
                  </select>
                </Field>
                <Field name="trackId" title="Track">
                  <select id="trackId" name="trackId" className={input} defaultValue={editing?.trackId ?? ""}>
                    <option value="">No track</option>
                    {tracks.map((t) => <option key={t.id} value={t.id}>{t.name}</option>)}
                  </select>
                </Field>
                <Field name="roomId" title="Hall">
                  <select id="roomId" name="roomId" className={input} defaultValue={editing?.roomId ?? ""}>
                    <option value="">No hall</option>
                    {rooms.map((r) => (
                      <option key={r.id} value={r.id}>
                        {r.venue ? `${r.venue.name} › ` : ""}{r.name}{r.capacity ? ` (${r.capacity})` : ""}
                      </option>
                    ))}
                  </select>
                </Field>
              </div>
              <Field name="speakerIds" title="Speakers (Cmd/Ctrl-click for multiple)">
                <select id="speakerIds" name="speakerIds" multiple size={Math.min(4, Math.max(2, speakers.length))} className={input} defaultValue={editing?.speakers.map((x) => x.speakerId) ?? []}>
                  {speakers.map((s) => <option key={s.id} value={s.id}>{s.name}</option>)}
                </select>
              </Field>
              <Field name="abstract" title="Abstract">
                <textarea id="abstract" name="abstract" rows={2} defaultValue={editing?.abstract ?? ""} className={input} />
              </Field>
              <button className={`${btn.primary} w-full`}>{editing ? "Save changes" : "Add to agenda"}</button>
            </form>
          </Card>

          {/* Track management */}
          <Card className="p-5">
            <h2 className="text-sm font-semibold text-zinc-200">Tracks</h2>
            <p className="mt-0.5 text-xs text-zinc-500">Thematic streams across all days — deleting a track keeps its sessions.</p>
            <div className="mt-3 space-y-2">
              {tracks.map((t) => (
                <form key={t.id} action={updateTrack.bind(null, id, t.id)} className="flex items-center gap-2">
                  <input name="color" type="color" defaultValue={t.color} className="h-8 w-9 shrink-0 cursor-pointer rounded-lg border border-white/80 bg-white/70" />
                  <input name="name" defaultValue={t.name} className={`${input} py-1.5`} />
                  <span className="shrink-0 text-[11px] tabular-nums text-zinc-500">{t._count.sessions}</span>
                  <button className={btn.smSecondary}>Save</button>
                  <button formAction={deleteTrack.bind(null, id, t.id)} className="rounded-md px-1.5 py-1 text-xs text-zinc-600 transition hover:bg-red-500/10 hover:text-red-600" title="Delete track">✕</button>
                </form>
              ))}
            </div>
            <form action={createTrack.bind(null, id)} className="mt-3 flex gap-2 border-t border-zinc-800/60 pt-3">
              <input name="color" type="color" defaultValue="#0ea5e9" className="h-9 w-10 shrink-0 cursor-pointer rounded-lg border border-white/80 bg-white/70" />
              <input name="name" placeholder="New track name" required className={input} />
              <button className={btn.smSecondary}>Add</button>
            </form>
          </Card>
        </div>
      </div>
    </main>
  );
}
