"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";

type Item = {
  id: number;
  title: string;
  isXrated: number;
  machinetypeId: number | null;
  machinetypeName?: string | null;
  languageId: string | null;
  languageName?: string | null;
};

type Paged<T> = {
  items: T[];
  page: number;
  pageSize: number;
  total: number;
};

export default function ZxdbExplorer({
  initial,
  initialGenres,
  initialLanguages,
  initialMachines,
}: {
  initial?: Paged<Item>;
  initialGenres?: { id: number; name: string }[];
  initialLanguages?: { id: string; name: string }[];
  initialMachines?: { id: number; name: string }[];
}) {
  const [q, setQ] = useState("");
  const [page, setPage] = useState(initial?.page ?? 1);
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<Paged<Item> | null>(initial ?? null);
  const [genres, setGenres] = useState<{ id: number; name: string }[]>(initialGenres ?? []);
  const [languages, setLanguages] = useState<{ id: string; name: string }[]>(initialLanguages ?? []);
  const [machines, setMachines] = useState<{ id: number; name: string }[]>(initialMachines ?? []);
  const [genreId, setGenreId] = useState<number | "">("");
  const [languageId, setLanguageId] = useState<string | "">("");
  const [machinetypeId, setMachinetypeId] = useState<number | "">("");
  const [year, setYear] = useState<string>("");
  const [sort, setSort] = useState<"title" | "id_desc">("id_desc");

  const pageSize = 20;
  const totalPages = useMemo(() => (data ? Math.max(1, Math.ceil(data.total / data.pageSize)) : 1), [data]);

  async function fetchData(query: string, p: number) {
    setLoading(true);
    try {
      const params = new URLSearchParams();
      if (query) params.set("q", query);
      params.set("page", String(p));
      params.set("pageSize", String(pageSize));
      if (genreId !== "") params.set("genreId", String(genreId));
      if (languageId !== "") params.set("languageId", String(languageId));
      if (machinetypeId !== "") params.set("machinetypeId", String(machinetypeId));
      if (year !== "") params.set("year", year);
      if (sort) params.set("sort", sort);
      const res = await fetch(`/api/zxdb/search?${params.toString()}`);
      if (!res.ok) throw new Error(`Failed: ${res.status}`);
      const json: Paged<Item> = await res.json();
      setData(json);
    } catch (e) {
      console.error(e);
      setData({ items: [], page: 1, pageSize, total: 0 });
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    // When navigating via Next.js Links that change ?page=, SSR provides new `initial`.
    // Sync local state from new SSR payload so the list and counter update immediately
    // without an extra client fetch.
    if (initial) {
      setData(initial);
      setPage(initial.page);
    }
  }, [initial]);

  useEffect(() => {
    // Avoid immediate client fetch on first paint if server provided initial data for this exact state
    const initialPage = initial?.page ?? 1;
    if (
      initial &&
      page === initialPage &&
      q === "" &&
      genreId === "" &&
      languageId === "" &&
      machinetypeId === "" &&
      year === "" &&
      sort === "id_desc"
    ) {
      return;
    }
    fetchData(q, page);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [page, genreId, languageId, machinetypeId, year, sort]);

  // Load filter lists on mount only if not provided by server
  useEffect(() => {
    if (initialGenres && initialLanguages && initialMachines) return;
    async function loadLists() {
      try {
        const [g, l, m] = await Promise.all([
          fetch("/api/zxdb/genres", { cache: "force-cache" }).then((r) => r.json()),
          fetch("/api/zxdb/languages", { cache: "force-cache" }).then((r) => r.json()),
          fetch("/api/zxdb/machinetypes", { cache: "force-cache" }).then((r) => r.json()),
        ]);
        setGenres(g.items ?? []);
        setLanguages(l.items ?? []);
        setMachines(m.items ?? []);
      } catch {}
    }
    loadLists();
  }, [initialGenres, initialLanguages, initialMachines]);

  function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    setPage(1);
    fetchData(q, 1);
  }

  return (
    <div>
      <h1 className="mb-3">ZXDB Explorer</h1>
      <form className="row gy-2 gx-2 align-items-center" onSubmit={onSubmit}>
        <div className="col-sm-8 col-md-6 col-lg-4">
          <input
            type="text"
            className="form-control"
            placeholder="Search titles..."
            value={q}
            onChange={(e) => setQ(e.target.value)}
          />
        </div>
        <div className="col-auto">
          <button className="btn btn-primary" type="submit" disabled={loading}>Search</button>
        </div>
        <div className="col-auto">
          <select className="form-select" value={genreId} onChange={(e) => setGenreId(e.target.value === "" ? "" : Number(e.target.value))}>
            <option value="">Genre</option>
            {genres.map((g) => (
              <option key={g.id} value={g.id}>{g.name}</option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <select className="form-select" value={languageId} onChange={(e) => setLanguageId(e.target.value)}>
            <option value="">Language</option>
            {languages.map((l) => (
              <option key={l.id} value={l.id}>{l.name}</option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <select className="form-select" value={machinetypeId} onChange={(e) => setMachinetypeId(e.target.value === "" ? "" : Number(e.target.value))}>
            <option value="">Machine</option>
            {machines.map((m) => (
              <option key={m.id} value={m.id}>{m.name}</option>
            ))}
          </select>
        </div>
        <div className="col-auto">
          <input
            type="number"
            className="form-control"
            style={{ width: 100 }}
            placeholder="Year"
            value={year}
            onChange={(e) => setYear(e.target.value)}
          />
        </div>
        <div className="col-auto">
          <select className="form-select" value={sort} onChange={(e) => setSort(e.target.value as "title" | "id_desc")}>
            <option value="title">Sort: Title</option>
            <option value="id_desc">Sort: Newest</option>
          </select>
        </div>
        {loading && (
          <div className="col-auto text-secondary">Loading...</div>
        )}
      </form>

      <div className="mt-3">
        {data && data.items.length === 0 && !loading && (
          <div className="alert alert-warning">No results.</div>
        )}
        {data && data.items.length > 0 && (
          <div className="table-responsive">
            <table className="table table-striped table-hover align-middle">
              <thead>
                <tr>
                  <th style={{width: 80}}>ID</th>
                  <th>Title</th>
                  <th style={{width: 160}}>Machine</th>
                  <th style={{width: 120}}>Language</th>
                </tr>
              </thead>
              <tbody>
                {data.items.map((it) => (
                  <tr key={it.id}>
                    <td>{it.id}</td>
                    <td>
                      <Link href={`/zxdb/entries/${it.id}`}>{it.title}</Link>
                    </td>
                    <td>
                      {it.machinetypeId != null ? (
                        it.machinetypeName ? (
                          <Link href={`/zxdb/machinetypes/${it.machinetypeId}`}>{it.machinetypeName}</Link>
                        ) : (
                          <span>{it.machinetypeId}</span>
                        )
                      ) : (
                        <span className="text-secondary">-</span>
                      )}
                    </td>
                    <td>
                      {it.languageId ? (
                        it.languageName ? (
                          <Link href={`/zxdb/languages/${it.languageId}`}>{it.languageName}</Link>
                        ) : (
                          <span>{it.languageId}</span>
                        )
                      ) : (
                        <span className="text-secondary">-</span>
                      )}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>

      <div className="d-flex align-items-center gap-2 mt-2">
        <span>
          Page {data?.page ?? 1} / {totalPages}
        </span>
        <div className="ms-auto d-flex gap-2">
          <Link
            className={`btn btn-outline-secondary ${!data || (data.page <= 1) ? "disabled" : ""}`}
            aria-disabled={!data || data.page <= 1}
            href={`/zxdb?page=${Math.max(1, (data?.page ?? 1) - 1)}`}
          >
            Prev
          </Link>
          <Link
            className={`btn btn-outline-secondary ${!data || (data.page >= totalPages) ? "disabled" : ""}`}
            aria-disabled={!data || data.page >= totalPages}
            href={`/zxdb?page=${Math.min(totalPages, (data?.page ?? 1) + 1)}`}
          >
            Next
          </Link>
        </div>
      </div>

      <hr />
      <div className="d-flex flex-wrap gap-2">
        <Link className="btn btn-sm btn-outline-secondary" href="/zxdb/labels">Browse Labels</Link>
        <Link className="btn btn-sm btn-outline-secondary" href="/zxdb/genres">Browse Genres</Link>
        <Link className="btn btn-sm btn-outline-secondary" href="/zxdb/languages">Browse Languages</Link>
        <Link className="btn btn-sm btn-outline-secondary" href="/zxdb/machinetypes">Browse Machines</Link>
      </div>
    </div>
  );
}
