"use client";

import { useMemo, useState } from "react";
import Link from "next/link";
import {
  type LocationGroup,
  type Stop,
  formatTime12,
  getStopStatus,
} from "./types";

type Props = {
  stops: Stop[];
};

function groupStopsByLocation(stops: Stop[]): LocationGroup[] {
  const map = new Map<string, LocationGroup>();
  for (const s of stops) {
    const key = `${(s.city || "Unknown").trim().toUpperCase()}|${(s.state || "").trim().toUpperCase()}`;
    let group = map.get(key);
    if (!group) {
      group = {
        key,
        city: s.city || "Unknown",
        state: s.state || "",
        venueCount: 0,
        total: 0,
        active: 0,
        draft: 0,
        inactive: 0,
        upcoming: 0,
        nextDate: null,
        firstDate: null,
        lastDate: null,
        sampleVenue: s.location,
        stops: [],
      };
      map.set(key, group);
    }
    group.stops.push(s);
    group.total += 1;
    const status = getStopStatus(s);
    if (status === "active") group.active += 1;
    else if (status === "draft") group.draft += 1;
    else group.inactive += 1;

    if (s.date) {
      if (!group.firstDate || s.date < group.firstDate) group.firstDate = s.date;
      if (!group.lastDate || s.date > group.lastDate) group.lastDate = s.date;
    }
  }
  // post-process: count distinct venues, upcoming stops
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;

  for (const g of map.values()) {
    const venues = new Set(
      g.stops.flatMap((s) => {
        const trimmed = (s.location || "").trim().toLowerCase();
        return trimmed ? [trimmed] : [];
      })
    );
    g.venueCount = Math.max(1, venues.size);
    g.upcoming = g.stops.filter((s) => s.date >= todayStr && getStopStatus(s) !== "inactive").length;
    const future: string[] = [];
    for (const s of g.stops) {
      if (s.date >= todayStr && getStopStatus(s) !== "inactive") {
        future.push(s.date);
      }
    }
    future.sort();
    g.nextDate = future[0] ?? null;
    g.stops.sort((a, b) => (a.date || "").localeCompare(b.date || ""));
  }

  return Array.from(map.values()).sort((a, b) => {
    // active locations with upcoming stops first, sorted by next date; then by city
    if (a.nextDate && !b.nextDate) return -1;
    if (!a.nextDate && b.nextDate) return 1;
    if (a.nextDate && b.nextDate) return a.nextDate.localeCompare(b.nextDate);
    return a.city.localeCompare(b.city);
  });
}

function formatDateLabel(ymd: string | null): string {
  if (!ymd) return "—";
  const d = new Date(ymd + "T00:00:00");
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
}

function formatRange(a: string | null, b: string | null): string {
  if (!a) return "—";
  if (!b || a === b) return formatDateLabel(a);
  return `${formatDateLabel(a)} → ${formatDateLabel(b)}`;
}

export default function StopsLocations({ stops }: Props) {
  const [expandedKey, setExpandedKey] = useState<string | null>(null);
  const [query, setQuery] = useState("");
  const [showOnlyActive, setShowOnlyActive] = useState(false);

  const groups = useMemo(() => groupStopsByLocation(stops), [stops]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    return groups.filter((g) => {
      if (q) {
        const hay = `${g.city} ${g.state} ${g.sampleVenue}`.toLowerCase();
        if (!hay.includes(q)) return false;
      }
      if (showOnlyActive && g.active === 0) return false;
      return true;
    });
  }, [groups, query, showOnlyActive]);

  // Aggregated stats
  const stats = useMemo(() => {
    const totalLocations = groups.length;
    const totalStops = stops.length;
    const totalActive = groups.reduce((sum, g) => sum + g.active, 0);
    const totalUpcoming = groups.reduce((sum, g) => sum + g.upcoming, 0);
    const totalDrafts = groups.reduce((sum, g) => sum + g.draft, 0);
    const totalCities = new Set(groups.map((g) => g.city.toLowerCase())).size;
    const totalVenues = groups.reduce((sum, g) => sum + g.venueCount, 0);
    return { totalLocations, totalStops, totalActive, totalUpcoming, totalDrafts, totalCities, totalVenues };
  }, [groups, stops]);

  if (stops.length === 0) {
    return (
      <div className="rounded-2xl border border-[var(--admin-border)] bg-white p-12 text-center shadow-sm">
        <div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-[var(--admin-bg-subtle)]">
          <svg className="h-7 w-7 text-[var(--admin-text-muted)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z" />
            <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z" />
          </svg>
        </div>
        <h3 className="font-display text-2xl font-medium text-[var(--admin-text-primary)]">
          No locations yet
        </h3>
        <p className="mt-1 text-sm text-[var(--admin-text-secondary)]">
          Create your first stop to see pickup locations here.
        </p>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {/* Stats strip — almanac style */}
      <section className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6">
        {[
          { numeral: "I", label: "Locations", value: stats.totalLocations, hint: `${stats.totalVenues} venues` },
          { numeral: "II", label: "Cities", value: stats.totalCities, hint: "covered" },
          { numeral: "III", label: "Stops", value: stats.totalStops, hint: "all-time" },
          { numeral: "IV", label: "Active", value: stats.totalActive, hint: "live" },
          { numeral: "V", label: "Upcoming", value: stats.totalUpcoming, hint: "in queue" },
          { numeral: "VI", label: "Drafts", value: stats.totalDrafts, hint: "unpublished" },
        ].map((s) => (
          <div
            key={s.numeral}
            className="group relative overflow-hidden rounded-2xl border border-[var(--admin-border)] bg-white p-4 shadow-sm transition-all hover:shadow-md hover:border-[var(--admin-accent)]/30"
          >
            <div className="flex items-start justify-between">
              <div>
                <p className="font-mono text-[9px] uppercase tracking-[0.18em] text-[var(--admin-text-muted)]">
                  {s.numeral} · {s.label}
                </p>
                <p className="mt-2 font-display text-3xl font-medium leading-none text-[var(--admin-text-primary)] tabular-nums">
                  {s.value}
                </p>
                <p className="mt-1.5 font-mono text-[9px] uppercase tracking-wider text-[var(--admin-text-muted)]">
                  {s.hint}
                </p>
              </div>
              <div
                aria-hidden
                className="h-8 w-8 -rotate-3 font-display text-2xl text-[var(--admin-accent)]/15 group-hover:text-[var(--admin-accent)]/30 transition-colors"
              >
                {s.numeral}
              </div>
            </div>
            <div className="mt-3 h-px w-full bg-gradient-to-r from-[var(--admin-accent)]/20 via-[var(--admin-accent)]/40 to-[var(--admin-accent)]/20" />
          </div>
        ))}
      </section>

      {/* Filter bar */}
      <section className="flex flex-wrap items-center gap-3 rounded-2xl border border-[var(--admin-border)] bg-white px-4 py-3 shadow-sm">
        <div className="relative flex-1 min-w-[200px] max-w-md">
          <svg className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--admin-text-muted)]" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
          </svg>
          <input aria-label="Search City, State, Venue..."
            type="search"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Search city, state, venue..."
            className="w-full rounded-lg border border-[var(--admin-border)] bg-white pl-9 pr-3 py-2 text-sm text-[var(--admin-text-primary)] placeholder:text-[var(--admin-text-muted)] focus:border-[var(--admin-accent)] focus:outline-none focus:ring-2 focus:ring-[var(--admin-accent)]/15"
          />
        </div>
        <label className="flex items-center gap-2 cursor-pointer select-none">
          <button
            type="button"
            role="switch"
            aria-checked={showOnlyActive}
            onClick={() => setShowOnlyActive((v) => !v)}
            className={`relative h-5 w-9 rounded-full transition-colors ${showOnlyActive ? "bg-[var(--admin-accent)]" : "bg-stone-300"}`}
          >
            <span
              className={`absolute top-0.5 h-4 w-4 rounded-full bg-white shadow-sm transition-transform ${showOnlyActive ? "translate-x-4" : "translate-x-0.5"}`}
            />
          </button>
          <span className="font-mono text-[10px] uppercase tracking-wider text-[var(--admin-text-secondary)]">
            Active only
          </span>
        </label>
        <span className="ml-auto font-mono text-[10px] uppercase tracking-wider text-[var(--admin-text-muted)]">
          {filtered.length} of {groups.length} locations
        </span>
      </section>

      {/* Location grid */}
      {filtered.length === 0 ? (
        <div className="rounded-2xl border border-dashed border-[var(--admin-border)] bg-white p-10 text-center">
          <p className="font-display text-lg text-[var(--admin-text-primary)]">No locations match.</p>
          <p className="mt-1 text-sm text-[var(--admin-text-secondary)]">Try a different search.</p>
        </div>
      ) : (
        <section className="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3">
          {filtered.map((g, idx) => {
            const isOpen = expandedKey === g.key;
            return (
              <article
                key={g.key}
                className={`
                  group relative overflow-hidden rounded-2xl border bg-white shadow-sm transition-all
                  ${isOpen ? "border-[var(--admin-accent)] shadow-md ring-1 ring-[var(--admin-accent)]/20" : "border-[var(--admin-border)] hover:border-[var(--admin-accent)]/40 hover:shadow-md"}
                `}
              >
                {/* Decorative route number */}
                <div
                  aria-hidden
                  className="pointer-events-none absolute -right-2 -top-3 select-none font-display text-[80px] leading-none font-medium text-[var(--admin-accent)]/[0.06] group-hover:text-[var(--admin-accent)]/[0.1] transition-colors"
                >
                  {String(idx + 1).padStart(2, "0")}
                </div>

                <button
                  type="button"
                  onClick={() => setExpandedKey(isOpen ? null : g.key)}
                  className="block w-full text-left p-5"
                  aria-expanded={isOpen}
                >
                  <div className="flex items-start justify-between gap-3">
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center gap-2">
                        {/* Pin marker */}
                        <span className="inline-flex h-7 w-7 items-center justify-center rounded-full bg-[var(--admin-accent-light)] border border-[var(--admin-accent)]/30">
                          <svg className="h-3.5 w-3.5 text-[var(--admin-accent-text)]" viewBox="0 0 24 24" fill="currentColor">
                            <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z" />
                          </svg>
                        </span>
                        <div className="min-w-0">
                          <h3 className="truncate font-display text-xl font-medium text-[var(--admin-text-primary)]">
                            {g.city}
                            {g.state && (
                              <span className="ml-1.5 font-mono text-xs font-normal text-[var(--admin-text-muted)]">
                                {g.state}
                              </span>
                            )}
                          </h3>
                          <p className="truncate text-xs text-[var(--admin-text-secondary)]">
                            {g.sampleVenue}
                          </p>
                        </div>
                      </div>
                    </div>
                    <div
                      className={`mt-1 h-7 w-7 shrink-0 inline-flex items-center justify-center rounded-full border transition-transform ${
                        isOpen ? "border-[var(--admin-accent)] bg-[var(--admin-accent-light)] text-[var(--admin-accent-text)] rotate-45" : "border-[var(--admin-border)] bg-white text-[var(--admin-text-muted)]"
                      }`}
                      aria-hidden
                    >
                      <svg className="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2.5}>
                        <path strokeLinecap="round" strokeLinejoin="round" d="M12 5v14M5 12h14" />
                      </svg>
                    </div>
                  </div>

                  {/* Stat grid */}
                  <div className="mt-5 grid grid-cols-3 gap-2">
                    <Stat label="Stops" value={g.total} />
                    <Stat label="Active" value={g.active} accent={g.active > 0} />
                    <Stat label="Upcoming" value={g.upcoming} accent={g.upcoming > 0} />
                  </div>

                  {/* Date range + drafts */}
                  <div className="mt-4 flex items-center justify-between border-t border-[var(--admin-border-light)] pt-3 font-mono text-[10px] uppercase tracking-wider">
                    <div className="text-[var(--admin-text-muted)]">
                      {g.firstDate ? (
                        <>
                          <span className="text-[var(--admin-text-secondary)]">{formatRange(g.firstDate, g.lastDate)}</span>
                          {" · "}
                          {g.venueCount > 1 ? `${g.venueCount} venues` : `${g.total} stop${g.total === 1 ? "" : "s"}`}
                        </>
                      ) : (
                        "No dates"
                      )}
                    </div>
                    {g.draft > 0 && (
                      <span className="inline-flex items-center gap-1 rounded-full border border-amber-300 bg-amber-50 px-2 py-0.5 text-amber-800">
                        <span className="h-1.5 w-1.5 rounded-full bg-amber-500" aria-hidden />
                        {g.draft} draft
                      </span>
                    )}
                  </div>

                  {/* Next up ribbon */}
                  {g.nextDate && (
                    <div className="mt-3 flex items-center gap-2 rounded-lg border border-[var(--admin-accent)]/20 bg-gradient-to-r from-[var(--admin-accent-light)] to-transparent px-3 py-2">
                      <span className="font-mono text-[9px] uppercase tracking-[0.18em] text-[var(--admin-accent-text)]">
                        Next →
                      </span>
                      <span className="font-display text-sm font-medium text-[var(--admin-text-primary)]">
                        {formatDateLabel(g.nextDate)}
                      </span>
                    </div>
                  )}
                </button>

                {/* Expanded stop list */}
                {isOpen && (
                  <div className="border-t border-[var(--admin-border)] bg-[var(--admin-bg-subtle)]/40 px-5 py-4">
                    <div className="mb-2 flex items-center justify-between">
                      <h4 className="font-mono text-[10px] uppercase tracking-[0.18em] text-[var(--admin-text-muted)]">
                        All stops · {g.stops.length}
                      </h4>
                      <Link
                        href={`/admin/stops/new?city=${encodeURIComponent(g.city)}&state=${encodeURIComponent(g.state)}`}
                        className="font-mono text-[10px] uppercase tracking-wider text-[var(--admin-accent-text)] hover:underline"
                      >
                        + Add at this city
                      </Link>
                    </div>
                    <ul className="space-y-1">
                      {g.stops.map((s) => {
                        const status = getStopStatus(s);
                        const dot =
                          status === "active"
                            ? "bg-[var(--admin-accent-dot)]"
                            : status === "draft"
                            ? "bg-amber-500"
                            : "bg-stone-400";
                        return (
                          <li key={s.id}>
                            <Link
                              href={`/admin/stops/${s.id}`}
                              className="flex items-center gap-3 rounded-lg border border-transparent bg-white px-3 py-2 transition-colors hover:border-[var(--admin-border)] hover:bg-[var(--admin-bg-subtle)]"
                            >
                              <span className={`h-2 w-2 shrink-0 rounded-full ${dot}`} aria-hidden />
                              <span className="font-mono text-[10px] tabular-nums text-[var(--admin-text-muted)] w-16">
                                {s.date ? new Date(s.date + "T00:00:00").toLocaleDateString("en-US", { month: "short", day: "numeric" }) : "—"}
                              </span>
                              <span className="font-mono text-[10px] tabular-nums text-[var(--admin-text-muted)] w-14">
                                {formatTime12(s.time)}
                              </span>
                              <span className="flex-1 truncate text-xs text-[var(--admin-text-primary)]">
                                {s.location}
                              </span>
                              <span
                                className={`font-mono text-[9px] uppercase tracking-wider ${
                                  status === "active" ? "text-[var(--admin-accent-text)]" : status === "draft" ? "text-amber-700" : "text-[var(--admin-text-muted)]"
                                }`}
                              >
                                {status}
                              </span>
                            </Link>
                          </li>
                        );
                      })}
                    </ul>
                  </div>
                )}
              </article>
            );
          })}
        </section>
      )}
    </div>
  );
}

function Stat({ label, value, accent }: { label: string; value: number; accent?: boolean }) {
  return (
    <div
      className={`rounded-lg border px-2.5 py-2 ${
        accent ? "border-[var(--admin-accent)]/30 bg-[var(--admin-accent-light)]" : "border-[var(--admin-border)] bg-[var(--admin-bg-subtle)]/50"
      }`}
    >
      <p className="font-mono text-[9px] uppercase tracking-wider text-[var(--admin-text-muted)]">{label}</p>
      <p
        className={`mt-0.5 font-display text-xl font-medium tabular-nums leading-none ${
          accent ? "text-[var(--admin-accent-text)]" : "text-[var(--admin-text-primary)]"
        }`}
      >
        {value}
      </p>
    </div>
  );
}
