"use client";

import { useState, useEffect, useRef } from "react";
import PropertyCard from "@/components/PropertyCard";
import ViewToggle from "@/components/ViewToggle";
import { clientExecute } from "@/lib/api/client";
import { useAuth } from "@/lib/auth-context";
import { Spinner, PropertyCardSkeleton, TopProgressBar } from "@/components/Loading";
import type { Property, Paginated } from "@/lib/types";

const TOWNS   = ["Akim Oda", "New Tafo", "Kade", "Asamankese"];
const RESIDENTIAL_TYPES = ["Single room", "1 bedroom", "2 bedroom", "3 bedroom", "4 bedroom", "Compound house"];
const COMMERCIAL_TYPES  = ["Shop", "Office", "Warehouse", "Storage", "Showroom", "Workshop"];
const TYPES             = [...RESIDENTIAL_TYPES, ...COMMERCIAL_TYPES];
const PRICE_RANGES = [
  { label: "Any price",      min: 0,    max: Infinity },
  { label: "Under GH₵ 500", min: 0,    max: 499 },
  { label: "GH₵ 500 – 1,000", min: 500, max: 1000 },
  { label: "GH₵ 1,000 – 2,000", min: 1000, max: 2000 },
  { label: "Above GH₵ 2,000",   min: 2001, max: Infinity },
];
const SORT_OPTIONS = [
  { label: "Most recent",       value: "recent" },
  { label: "Price: low to high", value: "price-asc" },
  { label: "Price: high to low", value: "price-desc" },
  { label: "Verified first",    value: "verified" },
];
const PER_PAGE = 6;

function Checkbox({ label, checked, onChange }: { label: string; checked: boolean; onChange: (v: boolean) => void }) {
  return (
    <label className="flex items-center gap-2 text-sm cursor-pointer">
      <input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} className="w-4 h-4 accent-forest" />
      {label}
    </label>
  );
}

function Radio({ label, name, checked, onChange }: { label: string; name: string; checked: boolean; onChange: () => void }) {
  return (
    <label className="flex items-center gap-2 text-sm cursor-pointer">
      <input type="radio" name={name} checked={checked} onChange={onChange} className="w-4 h-4 accent-forest" />
      {label}
    </label>
  );
}

export default function ListingsPage() {
  const { user } = useAuth();
  const lastRecorded = useRef<string>("");
  const [view,        setView]        = useState<"grid" | "list">("grid");
  const [query,       setQuery]       = useState("");
  const [category,    setCategory]    = useState<"all" | "residential" | "commercial">("all");
  const [sort,        setSort]        = useState("recent");
  const [towns,       setTowns]       = useState<string[]>(["Akim Oda"]);
  const [types,       setTypes]       = useState<string[]>([]);
  const [priceIdx,    setPriceIdx]    = useState(0);
  const [verifiedOnly, setVerifiedOnly] = useState(false);
  const [page,        setPage]        = useState(1);

  const [items, setItems]   = useState<Property[]>([]);
  const [total, setTotal]   = useState(0);
  const [totalPages, setTotalPages] = useState(1);
  const [loading, setLoading] = useState(true);
  const [error, setError]     = useState<string | null>(null);

  // Apply search params handed over from the home-page SearchBar (?q=…&type=…).
  useEffect(() => {
    const sp = new URLSearchParams(window.location.search);
    const q = sp.get("q")?.trim() ?? "";
    const type = sp.get("type")?.trim() ?? "";
    if (!q && !type) return;
    if (q) setQuery(q);
    if (type) setTypes([type]);
    // An explicit search should not stay pinned to the default town filter.
    setTowns([]);
    setPage(1);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  function toggleTown(t: string, on: boolean) {
    setTowns((prev) => on ? [...prev, t] : prev.filter((x) => x !== t));
    setPage(1);
  }
  function toggleType(t: string, on: boolean) {
    setTypes((prev) => on ? [...prev, t] : prev.filter((x) => x !== t));
    setPage(1);
  }

  // Fetch whenever filters/page change (query is debounced).
  useEffect(() => {
    const { min, max } = PRICE_RANGES[priceIdx];
    const payload: Record<string, unknown> = {
      category, towns, types, verifiedOnly, sort, page, limit: PER_PAGE,
    };
    if (query.trim()) payload.q = query.trim();
    if (min > 0) payload.priceMin = min;
    if (Number.isFinite(max)) payload.priceMax = max;

    let cancelled = false;
    setLoading(true);
    const t = setTimeout(async () => {
      try {
        const res = await clientExecute<Paginated<Property>>("property.find-all", payload);
        if (cancelled) return;
        setItems(res.items);
        setTotal(res.total);
        setTotalPages(res.totalPages);
        setError(null);

        // Record the search for signed-in tenants (skip duplicate consecutive terms).
        const term = query.trim();
        if (user && term.length >= 2 && lastRecorded.current !== term) {
          lastRecorded.current = term;
          const filterBits = [
            towns.length ? towns.join(", ") : null,
            types.length ? `${types.length} type${types.length > 1 ? "s" : ""}` : null,
            verifiedOnly ? "verified only" : null,
          ].filter(Boolean).join(" · ");
          clientExecute("recent-search.record", {
            term,
            filters: filterBits || undefined,
            results: res.total,
          }).catch(() => { /* ignore */ });
        }
      } catch {
        if (!cancelled) setError("Couldn't load listings. Please try again.");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }, 250);

    return () => { cancelled = true; clearTimeout(t); };
  }, [towns, types, priceIdx, verifiedOnly, query, sort, category, page]);

  function clearFilters()  { setTowns([]); setTypes([]); setPriceIdx(0); setVerifiedOnly(false); setQuery(""); setCategory("all"); setPage(1); }

  const from = total === 0 ? 0 : (page - 1) * PER_PAGE + 1;
  const to = Math.min(page * PER_PAGE, total);

  return (
    <div className="max-w-6xl mx-auto px-6 py-8">

      {/* Search & sort bar */}
      <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 mb-6">
        <div className="flex items-center gap-3 bg-white border border-mist rounded-pill shadow-card pl-5 pr-2 py-2 flex-1">
          <svg className="w-4 h-4 text-ink-soft shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <circle cx="11" cy="11" r="7" /><path d="M21 21l-4.35-4.35" strokeLinecap="round" />
          </svg>
          <input
            type="text"
            value={query}
            onChange={(e) => { setQuery(e.target.value); setPage(1); }}
            placeholder="Search by town, type, or address…"
            className="flex-1 bg-transparent border-none outline-none text-sm text-ink placeholder:text-ink-soft py-1.5"
          />
          {query && (
            <button onClick={() => { setQuery(""); setPage(1); }} className="text-ink-soft hover:text-ink text-lg leading-none px-1">×</button>
          )}
        </div>
        <select
          value={sort}
          onChange={(e) => { setSort(e.target.value); setPage(1); }}
          className="bg-white border border-mist rounded-pill px-5 py-3 text-sm text-ink-soft outline-none"
        >
          {SORT_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
        </select>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-[260px_1fr] gap-8 items-start">

        {/* Filters sidebar */}
        <aside className="bg-white border border-mist rounded-md p-5 lg:sticky lg:top-[96px]">
          <div className="flex justify-between items-center mb-4">
            <h3 className="font-semibold text-base">Filter results</h3>
            <button onClick={clearFilters} className="text-xs text-ink-soft hover:text-clay transition-colors">Clear all</button>
          </div>

          {/* Category */}
          <div className="mb-5">
            <span className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">Category</span>
            <div className="flex flex-col gap-2">
              {(["all", "residential", "commercial"] as const).map((c) => (
                <Radio key={c} label={c === "all" ? "All listings" : c.charAt(0).toUpperCase() + c.slice(1)} name="category"
                  checked={category === c} onChange={() => { setCategory(c); setPage(1); }} />
              ))}
            </div>
          </div>

          <div className="mb-5">
            <span className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">Town</span>
            <div className="flex flex-col gap-2">
              {TOWNS.map((t) => (
                <Checkbox key={t} label={t} checked={towns.includes(t)} onChange={(v) => toggleTown(t, v)} />
              ))}
            </div>
          </div>

          <div className="mb-5">
            <span className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">
              {category === "commercial" ? "Commercial type" : category === "residential" ? "House type" : "Property type"}
            </span>
            <div className="flex flex-col gap-2">
              {(category === "commercial" ? COMMERCIAL_TYPES : category === "residential" ? RESIDENTIAL_TYPES : TYPES).map((t) => (
                <Checkbox key={t} label={t} checked={types.includes(t)} onChange={(v) => toggleType(t, v)} />
              ))}
            </div>
          </div>

          <div className="mb-5">
            <span className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">Price range</span>
            <div className="flex flex-col gap-2">
              {PRICE_RANGES.map((r, i) => (
                <Radio key={r.label} name="price" label={r.label} checked={priceIdx === i} onChange={() => { setPriceIdx(i); setPage(1); }} />
              ))}
            </div>
          </div>

          <div className="mb-5">
            <span className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">Trust</span>
            <Checkbox label="Verified properties only" checked={verifiedOnly} onChange={(v) => { setVerifiedOnly(v); setPage(1); }} />
          </div>

          <button onClick={() => setPage(1)}
            className="w-full inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
            Apply filters
          </button>
        </aside>

        {/* Results */}
        <div>
          <div className="flex flex-wrap items-center justify-between gap-3 mb-5">
            <div className="flex items-center gap-2.5 text-sm text-ink-soft">
              {loading && <span className="text-forest"><Spinner size="sm" /></span>}
              {loading
                ? "Searching listings…"
                : total === 0
                ? "No properties match your filters"
                : <>Showing <strong className="text-ink">{from}–{to}</strong> of <strong className="text-ink">{total}</strong> {total === 1 ? "house" : "houses"}</>
              }
            </div>
            <ViewToggle view={view} onChange={setView} />
          </div>

          {loading && <TopProgressBar className="mb-5" />}

          {error ? (
            <div className="bg-white border border-mist rounded-md py-16 text-center">
              <h3 className="font-display font-semibold text-lg text-forest-deep mb-2">{error}</h3>
              <button onClick={() => setPage((p) => p)} className="mt-2 inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">Retry</button>
            </div>
          ) : loading ? (
            <div className={view === "grid" ? "grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-5" : "flex flex-col gap-5"}>
              {Array.from({ length: PER_PAGE }).map((_, i) => (
                <PropertyCardSkeleton key={i} layout={view} />
              ))}
            </div>
          ) : items.length === 0 ? (
            <div className="bg-white border border-mist rounded-md py-16 text-center">
              <svg className="w-12 h-12 text-mist mx-auto mb-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4">
                <circle cx="11" cy="11" r="7" /><path d="M21 21l-4.35-4.35" strokeLinecap="round" />
              </svg>
              <h3 className="font-display font-semibold text-lg text-forest-deep mb-2">No properties found</h3>
              <p className="text-sm text-ink-soft mb-6">Try adjusting your filters or search term.</p>
              <button onClick={clearFilters}
                className="inline-flex items-center justify-center font-semibold text-sm px-6 py-3 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors">
                Clear filters
              </button>
            </div>
          ) : (
            <div className={view === "grid" ? "grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-5" : "flex flex-col gap-5"}>
              {items.map((p) => <PropertyCard key={p.id} property={p} layout={view} />)}
            </div>
          )}

          {/* Pagination */}
          {totalPages > 1 && !loading && (
            <div className="flex justify-center gap-2 mt-10">
              <button
                onClick={() => setPage((p) => Math.max(1, p - 1))}
                disabled={page === 1}
                className="w-9 h-9 rounded-sm border border-mist bg-white text-ink-soft font-mono text-sm hover:border-forest hover:text-forest transition-colors disabled:opacity-40"
              >
                ‹
              </button>
              {Array.from({ length: totalPages }, (_, i) => i + 1).map((n) => (
                <button key={n} onClick={() => setPage(n)}
                  className={`w-9 h-9 rounded-sm border font-mono text-sm transition-colors ${
                    n === page ? "bg-forest border-forest text-white" : "bg-white border-mist text-ink-soft hover:border-forest hover:text-forest"
                  }`}>
                  {n}
                </button>
              ))}
              <button
                onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                disabled={page === totalPages}
                className="w-9 h-9 rounded-sm border border-mist bg-white text-ink-soft font-mono text-sm hover:border-forest hover:text-forest transition-colors disabled:opacity-40"
              >
                ›
              </button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
