"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import { eventPath } from "@/lib/event-url";
import {
  addMonths,
  eachDayOfInterval,
  endOfMonth,
  endOfWeek,
  format,
  isSameMonth,
  parseISO,
  startOfMonth,
  startOfWeek,
  subMonths,
} from "date-fns";

export type CalendarEvent = {
  id: string;
  slug: string | null;
  title: string;
  city: string | null;
  dayKey: string; // YYYY-MM-DD in East Africa Time
  timeLabel: string;
  soldOut: boolean;
};

const WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
const VISIBLE_PER_CELL = 2;

export default function EventsCalendar({ events }: { events: CalendarEvent[] }) {
  const byDay = useMemo(() => {
    const map = new Map<string, CalendarEvent[]>();
    for (const e of events) {
      const list = map.get(e.dayKey) ?? [];
      list.push(e);
      map.set(e.dayKey, list);
    }
    return map;
  }, [events]);

  // Default to the month (and selected day) of the earliest event.
  const firstKey = useMemo(
    () => events.map((e) => e.dayKey).sort()[0] ?? format(new Date(), "yyyy-MM-dd"),
    [events]
  );
  const [month, setMonth] = useState(() => startOfMonth(parseISO(firstKey)));
  const [selected, setSelected] = useState<string>(firstKey);

  const days = useMemo(() => {
    const gridStart = startOfWeek(startOfMonth(month), { weekStartsOn: 1 });
    const gridEnd = endOfWeek(endOfMonth(month), { weekStartsOn: 1 });
    return eachDayOfInterval({ start: gridStart, end: gridEnd });
  }, [month]);

  const todayKey = format(new Date(), "yyyy-MM-dd");
  const selectedEvents = byDay.get(selected) ?? [];

  return (
    <div className="grid gap-8 lg:grid-cols-[1.6fr_1fr]">
      <div>
        {/* Month header */}
        <div className="flex items-center justify-between">
          <h2 className="text-xl font-black tracking-tight text-white">
            {format(month, "MMMM yyyy")}
          </h2>
          <div className="flex gap-2">
            <NavButton label="Previous month" onClick={() => setMonth((m) => subMonths(m, 1))}>
              ←
            </NavButton>
            <NavButton label="Next month" onClick={() => setMonth((m) => addMonths(m, 1))}>
              →
            </NavButton>
          </div>
        </div>

        {/* Weekday row */}
        <div className="mt-5 grid grid-cols-7 gap-1.5 text-center">
          {WEEKDAYS.map((d) => (
            <div key={d} className="text-[11px] font-semibold uppercase tracking-wider text-muted">
              {d}
            </div>
          ))}
        </div>

        {/* Day cells */}
        <div className="mt-1.5 grid grid-cols-7 gap-1.5">
          {days.map((day) => {
            const key = format(day, "yyyy-MM-dd");
            const dayEvents = byDay.get(key) ?? [];
            const inMonth = isSameMonth(day, month);
            const isSelected = key === selected;
            const hasEvents = dayEvents.length > 0;

            return (
              <button
                key={key}
                type="button"
                disabled={!hasEvents}
                onClick={() => setSelected(key)}
                className={`flex min-h-[78px] flex-col rounded-xl border p-1.5 text-left transition-colors sm:min-h-[96px] ${
                  isSelected
                    ? "border-brand-green bg-brand-green/10"
                    : hasEvents
                    ? "border-line bg-panel hover:border-brand-green/60"
                    : "border-line/60 bg-transparent"
                } ${hasEvents ? "cursor-pointer" : "cursor-default"}`}
              >
                <span
                  className={`text-xs font-semibold ${
                    !inMonth ? "text-muted/40" : key === todayKey ? "text-brand-green-h" : "text-white"
                  }`}
                >
                  {format(day, "d")}
                </span>

                <span className="mt-1 flex flex-1 flex-col gap-1 overflow-hidden">
                  {dayEvents.slice(0, VISIBLE_PER_CELL).map((e) => (
                    <span
                      key={e.id}
                      className="truncate rounded bg-brand-green/20 px-1 py-0.5 text-[10px] font-medium text-brand-green-h"
                      title={e.title}
                    >
                      {e.title}
                    </span>
                  ))}
                  {dayEvents.length > VISIBLE_PER_CELL && (
                    <span className="px-1 text-[10px] font-semibold text-muted">
                      +{dayEvents.length - VISIBLE_PER_CELL} more
                    </span>
                  )}
                </span>
              </button>
            );
          })}
        </div>
      </div>

      {/* Selected-day panel */}
      <aside className="rounded-2xl border border-line bg-panel p-5">
        <h3 className="text-lg font-bold text-white">
          {format(parseISO(selected), "EEEE, d MMMM yyyy")}
        </h3>
        <p className="mt-0.5 text-sm text-muted">
          {selectedEvents.length} {selectedEvents.length === 1 ? "event" : "events"}
        </p>

        {selectedEvents.length === 0 ? (
          <p className="mt-6 text-sm text-muted">No events on this day. Pick a highlighted date.</p>
        ) : (
          <ul className="mt-5 space-y-3">
            {selectedEvents.map((e) => (
              <li key={e.id}>
                <Link
                  href={eventPath(e)}
                  className="block rounded-xl border border-line bg-panel-soft p-3.5 transition-colors hover:border-brand-green"
                >
                  <div className="flex items-center justify-between gap-2">
                    <span className="text-sm font-semibold text-brand-green-h">{e.timeLabel}</span>
                    {e.soldOut && (
                      <span className="rounded-full bg-brand-gold px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider text-[#1a1206]">
                        Sold out
                      </span>
                    )}
                  </div>
                  <p className="mt-1 font-semibold leading-snug text-white">{e.title}</p>
                  {e.city && <p className="mt-0.5 text-xs text-muted">{e.city}</p>}
                </Link>
              </li>
            ))}
          </ul>
        )}
      </aside>
    </div>
  );
}

function NavButton({
  children,
  label,
  onClick,
}: {
  children: React.ReactNode;
  label: string;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      aria-label={label}
      onClick={onClick}
      className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-line text-white hover:border-brand-green"
    >
      {children}
    </button>
  );
}
