"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import { eventPath } from "@/lib/event-url";
import { formatEventDate, formatEventTime, formatPriceFrom, nowMs } from "@/lib/format";

export type EventCard = {
  id: string;
  slug: string | null;
  title: string;
  organizer: string | null;
  venue: string | null;
  city: string | null;
  startsAt: string;
  endsAt: string | null;
  coverImageUrl: string | null;
  ageRestriction: string | null;
  category: string | null;
  currency: string;
  priceFromCents: number | null;
  soldOut: boolean;
};

const ALL = "All";

type Timeframe = "upcoming" | "past";

// An event counts as past once its end (or start, if open-ended) is before now.
function isPastEvent(e: EventCard, now: number): boolean {
  return new Date(e.endsAt ?? e.startsAt).getTime() < now;
}

export default function EventsExplorer({ events }: { events: EventCard[] }) {
  const [timeframe, setTimeframe] = useState<Timeframe>("upcoming");
  const [category, setCategory] = useState(ALL);
  const [city, setCity] = useState(ALL);

  // Evaluated once on mount; the upcoming/past split doesn't need to tick live.
  const now = useMemo(() => nowMs(), []);
  const pastCount = useMemo(() => events.filter((e) => isPastEvent(e, now)).length, [events, now]);

  const categories = useMemo(
    () => [ALL, ...uniqueSorted(events.map((e) => e.category))],
    [events]
  );
  const cities = useMemo(() => [ALL, ...uniqueSorted(events.map((e) => e.city))], [events]);

  const filtered = useMemo(() => {
    const list = events.filter(
      (e) =>
        isPastEvent(e, now) === (timeframe === "past") &&
        (category === ALL || e.category === category) &&
        (city === ALL || e.city === city)
    );
    // Upcoming: soonest first (events arrive ascending). Past: most recent first.
    return timeframe === "past" ? [...list].reverse() : list;
  }, [events, timeframe, category, city, now]);

  return (
    <div>
      <div className="mb-6 inline-flex rounded-full border border-line bg-panel p-1">
        <TimeframeTab
          label="Upcoming"
          active={timeframe === "upcoming"}
          onClick={() => setTimeframe("upcoming")}
        />
        <TimeframeTab
          label={pastCount ? `Past · ${pastCount}` : "Past"}
          active={timeframe === "past"}
          onClick={() => setTimeframe("past")}
        />
      </div>

      <div className="space-y-3">
        <FilterRow label="Category" options={categories} active={category} onChange={setCategory} />
        <FilterRow label="City" options={cities} active={city} onChange={setCity} />
      </div>

      <p className="mt-6 text-sm text-muted">
        {filtered.length} {filtered.length === 1 ? "event" : "events"}
        {timeframe === "past" ? " · relive the moments" : ""}
      </p>

      {filtered.length === 0 ? (
        <div className="mt-6 rounded-2xl border border-line bg-panel p-10 text-center">
          <p className="text-white font-semibold">
            {timeframe === "past"
              ? "No past events to show yet."
              : "Nothing matched. Try a different category or city."}
          </p>
          {timeframe !== "past" && (
            <button
              type="button"
              onClick={() => {
                setCategory(ALL);
                setCity(ALL);
              }}
              className="mt-3 text-sm font-semibold text-brand-green-h hover:underline"
            >
              Clear filters
            </button>
          )}
        </div>
      ) : (
        <div className="mt-4 grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
          {filtered.map((e) => (
            <EventGridCard key={e.id} event={e} isPast={timeframe === "past"} />
          ))}
        </div>
      )}
    </div>
  );
}

function TimeframeTab({
  label,
  active,
  onClick,
}: {
  label: string;
  active: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={`rounded-full px-5 py-2 text-sm font-semibold transition-colors ${
        active ? "bg-brand-green text-white" : "text-muted hover:text-white"
      }`}
    >
      {label}
    </button>
  );
}

function FilterRow({
  label,
  options,
  active,
  onChange,
}: {
  label: string;
  options: string[];
  active: string;
  onChange: (v: string) => void;
}) {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <span className="mr-1 w-16 shrink-0 text-xs font-semibold uppercase tracking-wider text-muted">
        {label}
      </span>
      {options.map((opt) => (
        <button
          key={opt}
          type="button"
          onClick={() => onChange(opt)}
          className={`rounded-full border px-3.5 py-1.5 text-sm font-medium transition-colors ${
            active === opt
              ? "border-brand-green bg-brand-green/15 text-brand-green-h"
              : "border-line text-muted hover:border-brand-green/50 hover:text-white"
          }`}
        >
          {opt}
        </button>
      ))}
    </div>
  );
}

function EventGridCard({ event: e, isPast = false }: { event: EventCard; isPast?: boolean }) {
  return (
    <Link
      href={eventPath(e)}
      className={`group flex flex-col rounded-2xl border border-line bg-panel overflow-hidden transition-all duration-200 hover:-translate-y-0.5 hover:border-brand-gold hover:shadow-[0_14px_34px_-18px_rgba(231,184,75,0.55)] motion-reduce:hover:translate-y-0 ${
        e.soldOut && !isPast ? "opacity-70" : ""
      }`}
    >
      <div className="aspect-[16/10] bg-panel-soft relative overflow-hidden">
        {e.coverImageUrl && (
          // eslint-disable-next-line @next/next/no-img-element
          <img
            src={e.coverImageUrl}
            alt={e.title}
            width={640}
            height={400}
            loading="lazy"
            onError={(ev) => {
              const img = ev.currentTarget;
              if (img.src.endsWith("/placeholder-event.svg")) return;
              img.src = "/placeholder-event.svg";
            }}
            className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
          />
        )}
        <div className="absolute top-3 left-3 flex flex-wrap gap-2">
          {e.category && (
            <span className="rounded-full bg-black/55 px-2.5 py-1 text-[11px] font-semibold text-white backdrop-blur">
              {e.category}
            </span>
          )}
          {e.ageRestriction && (
            <span className="rounded-full bg-brand-orange px-2.5 py-1 text-[11px] font-bold text-white">
              {e.ageRestriction}
            </span>
          )}
        </div>
        {isPast ? (
          <span className="absolute top-3 right-3 rounded-full bg-black/55 px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider text-white backdrop-blur">
            Past
          </span>
        ) : (
          e.soldOut && (
            <span className="absolute top-3 right-3 rounded-full bg-brand-gold px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider text-[#1a1206]">
              Sold out
            </span>
          )
        )}
      </div>

      <div className="flex flex-1 flex-col p-5">
        <h3 className="font-bold text-lg leading-snug text-white">{e.title}</h3>
        {e.organizer && <p className="mt-1 text-sm text-brand-green-h">{e.organizer}</p>}

        <div className="mt-3 space-y-1 text-sm text-muted">
          <p>
            {formatEventDate(e.startsAt)} · {formatEventTime(e.startsAt)}
          </p>
          {e.venue && <p className="line-clamp-1">{e.venue}</p>}
        </div>

        <div className="mt-4 flex items-center justify-between pt-2">
          <span className="text-sm font-bold text-white">
            {isPast ? "" : formatPriceFrom(e.priceFromCents, e.currency)}
          </span>
          <span className="text-sm font-semibold text-brand-green-h">
            {isPast ? "Relive it" : e.soldOut ? "View" : "Get tickets"} →
          </span>
        </div>
      </div>
    </Link>
  );
}

function uniqueSorted(values: (string | null)[]): string[] {
  return [...new Set(values.filter((v): v is string => !!v))].sort((a, b) => a.localeCompare(b));
}
