"use client";

import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
import { Search } from "lucide-react";
import { DateRangeField } from "@/components/shared/date-picker";
import {
  formatLocalCalendarYmd,
  localCalendarDateFromYmd,
} from "@/lib/trip-dates";
import {
  ACTIVITY_CATEGORIES,
  categoryMeta,
  isActivityCategory,
} from "@/lib/activity-category";
import { VIBES, vibeMeta, isVibe } from "@/lib/vibe";
import type { ActivityCategory, Vibe } from "@/app/generated/prisma/enums";

type GroupSize = "SMALL" | "MEDIUM" | "LARGE";
const GROUP_SIZES: { value: GroupSize; label: string; hint: string }[] = [
  { value: "SMALL", label: "Small", hint: "≤10 — paling akrab" },
  { value: "MEDIUM", label: "Medium", hint: "11–20" },
  { value: "LARGE", label: "Large", hint: "21+" },
];
function isGroupSize(value: unknown): value is GroupSize {
  return (
    typeof value === "string" &&
    GROUP_SIZES.some((g) => g.value === value)
  );
}

export function TripFilter() {
  const router = useRouter();
  const searchParams = useSearchParams();

  const initialCategory = searchParams.get("category");
  const initialVibe = searchParams.get("vibe");
  const initialGroup = searchParams.get("groupSize");
  const [category, setCategory] = useState<ActivityCategory | null>(
    isActivityCategory(initialCategory) ? initialCategory : null
  );
  const [vibe, setVibe] = useState<Vibe | null>(
    isVibe(initialVibe) ? initialVibe : null
  );
  const [groupSize, setGroupSize] = useState<GroupSize | null>(
    isGroupSize(initialGroup) ? initialGroup : null
  );
  const [query, setQuery] = useState(searchParams.get("q") ?? "");
  const [startDate, setStartDate] = useState<Date | null>(() => {
    const from = searchParams.get("from");
    return from ? localCalendarDateFromYmd(from) : null;
  });
  const [endDate, setEndDate] = useState<Date | null>(() => {
    const to = searchParams.get("to");
    return to ? localCalendarDateFromYmd(to) : null;
  });

  function buildParams(overrides?: {
    category?: ActivityCategory | null;
    vibe?: Vibe | null;
    groupSize?: GroupSize | null;
  }) {
    const params = new URLSearchParams();
    const nextCategory =
      overrides && "category" in overrides ? overrides.category : category;
    const nextVibe = overrides && "vibe" in overrides ? overrides.vibe : vibe;
    const nextGroup =
      overrides && "groupSize" in overrides ? overrides.groupSize : groupSize;
    if (nextCategory) params.set("category", nextCategory);
    if (nextVibe) params.set("vibe", nextVibe);
    if (nextGroup) params.set("groupSize", nextGroup);
    if (query.trim()) params.set("q", query.trim());
    if (startDate) params.set("from", formatLocalCalendarYmd(startDate));
    if (endDate) params.set("to", formatLocalCalendarYmd(endDate));
    return params;
  }

  function pushFilters(params: URLSearchParams) {
    const qs = params.toString();
    router.push(`/trips${qs ? `?${qs}` : ""}`);
  }

  function handleSelectCategory(next: ActivityCategory | null) {
    setCategory(next);
    pushFilters(buildParams({ category: next }));
  }

  function handleSelectVibe(next: Vibe | null) {
    setVibe(next);
    pushFilters(buildParams({ vibe: next }));
  }

  function handleSelectGroupSize(next: GroupSize | null) {
    setGroupSize(next);
    pushFilters(buildParams({ groupSize: next }));
  }

  function handleDateChange(dates: [Date | null, Date | null]) {
    const [start, end] = dates;
    setStartDate(start);
    setEndDate(end);

    if (!start && !end) {
      const params = new URLSearchParams();
      if (category) params.set("category", category);
      if (vibe) params.set("vibe", vibe);
      if (groupSize) params.set("groupSize", groupSize);
      if (query.trim()) params.set("q", query.trim());
      pushFilters(params);
    }
  }

  function handleSearch(e: React.FormEvent) {
    e.preventDefault();
    pushFilters(buildParams());
  }

  function handleReset() {
    setCategory(null);
    setVibe(null);
    setGroupSize(null);
    setQuery("");
    setStartDate(null);
    setEndDate(null);
    router.push("/trips");
  }

  const hasFilters = category || vibe || groupSize || query || startDate || endDate;

  return (
    <form
      onSubmit={handleSearch}
      className="rounded-2xl border border-neutral-200 bg-white p-4 shadow-sm sm:p-5"
    >
      {/* Category chips */}
      <div className="mb-4">
        <label className="mb-1.5 block text-xs font-medium text-neutral-500">
          Kategori
        </label>
        <div className="flex flex-wrap gap-1.5">
          <button
            type="button"
            onClick={() => handleSelectCategory(null)}
            aria-pressed={category === null}
            className={`inline-flex items-center gap-1 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
              category === null
                ? "border-primary-600 bg-primary-600 text-white"
                : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
            }`}
          >
            Semua
          </button>
          {ACTIVITY_CATEGORIES.map((c) => {
            const m = categoryMeta(c);
            const active = c === category;
            return (
              <button
                key={c}
                type="button"
                onClick={() => handleSelectCategory(c)}
                aria-pressed={active}
                className={`inline-flex items-center gap-1 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
                  active
                    ? "border-primary-600 bg-primary-600 text-white"
                    : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
                }`}
              >
                <span>{m.icon}</span>
                <span>{m.label}</span>
              </button>
            );
          })}
        </div>
      </div>

      {/* Vibe & Ukuran grup */}
      <div className="mb-4 grid gap-3 sm:grid-cols-2">
        <div>
          <label className="mb-1.5 block text-xs font-medium text-neutral-500">
            Vibe
          </label>
          <div className="flex flex-wrap gap-1.5">
            <button
              type="button"
              onClick={() => handleSelectVibe(null)}
              aria-pressed={vibe === null}
              className={`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
                vibe === null
                  ? "border-secondary-600 bg-secondary-600 text-white"
                  : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
              }`}
            >
              Semua
            </button>
            {VIBES.map((v) => {
              const m = vibeMeta(v);
              const active = vibe === v;
              return (
                <button
                  key={v}
                  type="button"
                  onClick={() => handleSelectVibe(v)}
                  aria-pressed={active}
                  title={m.description}
                  className={`inline-flex items-center gap-1 rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
                    active
                      ? "border-secondary-600 bg-secondary-600 text-white"
                      : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
                  }`}
                >
                  <span aria-hidden>{m.icon}</span>
                  <span>{m.label}</span>
                </button>
              );
            })}
          </div>
        </div>

        <div>
          <label className="mb-1.5 block text-xs font-medium text-neutral-500">
            Ukuran grup
          </label>
          <div className="flex flex-wrap gap-1.5">
            <button
              type="button"
              onClick={() => handleSelectGroupSize(null)}
              aria-pressed={groupSize === null}
              className={`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
                groupSize === null
                  ? "border-primary-600 bg-primary-600 text-white"
                  : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
              }`}
            >
              Semua
            </button>
            {GROUP_SIZES.map((g) => {
              const active = groupSize === g.value;
              return (
                <button
                  key={g.value}
                  type="button"
                  onClick={() => handleSelectGroupSize(g.value)}
                  aria-pressed={active}
                  title={g.hint}
                  className={`rounded-full border px-3 py-1.5 text-xs font-medium transition-colors ${
                    active
                      ? "border-primary-600 bg-primary-600 text-white"
                      : "border-neutral-200 bg-white text-neutral-600 hover:bg-neutral-50"
                  }`}
                >
                  {g.label}
                </button>
              );
            })}
          </div>
        </div>
      </div>

      <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:gap-3">
        {/* Search input */}
        <div className="flex-1">
          <label className="mb-1.5 block text-xs font-medium text-neutral-500">
            Cari trip
          </label>
          <div className="relative">
            <span className="absolute left-3 top-1/2 -translate-y-1/2 text-neutral-400">
              <Search size={16} strokeWidth={1.75} aria-hidden />
            </span>
            <input
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Destinasi, lokasi, atau nama trip..."
              className="w-full rounded-xl border border-neutral-200 bg-neutral-50 py-2.5 pl-9 pr-3 text-sm text-neutral-800 placeholder:text-neutral-400 focus:border-primary-500 focus:bg-white"
            />
          </div>
        </div>

        {/* Date range */}
        <div className="sm:w-64">
          <label className="mb-1.5 block text-xs font-medium text-neutral-500">
            Tanggal
          </label>
          <DateRangeField
            startDate={startDate}
            endDate={endDate}
            onChange={(start, end) => handleDateChange([start, end])}
            minDate={new Date()}
          />
        </div>

        {/* Buttons */}
        <div className="flex gap-2 sm:shrink-0">
          <button
            type="submit"
            className="flex-1 rounded-xl bg-primary-600 px-5 py-2.5 text-sm font-semibold text-white shadow-md shadow-primary-600/20 transition-colors hover:bg-primary-700 sm:flex-none"
          >
            Cari
          </button>
          {hasFilters && (
            <button
              type="button"
              onClick={handleReset}
              className="rounded-xl border border-neutral-200 px-3 py-2.5 text-sm font-medium text-neutral-500 transition-colors hover:bg-neutral-50 hover:text-neutral-700"
            >
              Reset
            </button>
          )}
        </div>
      </div>
    </form>
  );
}
