"use client";

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

type BuildClass = "Rifle" | "Pistol" | "NFA";
type Caliber = string;

type BuildCard = {
  id: string;
  title: string;
  slug: string;
  creator: string;
  caliber: Caliber;
  buildClass: BuildClass;
  price: number;
  votes: number;
  tags: string[];
  coverImageUrl?: string | null;
};

const CLASS_FILTERS: (BuildClass | "all")[] = ["all", "Rifle", "Pistol", "NFA"];

const PRICE_FILTERS = [
  { id: "all", label: "All", min: 0, max: Infinity },
  { id: "sub1k", label: "< $1k", min: 0, max: 1000_00 },
  { id: "1to2k", label: "$1k–$2k", min: 1000_00, max: 2000_00 },
  { id: "2to3k", label: "$2k–$3k", min: 2000_00, max: 3000_00 },
  { id: "3kplus", label: "$3k+", min: 3000_00, max: Infinity },
];

const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";

interface BuildsClientProps {
  initialBuilds: BuildCard[];
  initialError: string | null;
}

/**
 * Client-side component that keeps all the previous interactivity:
 * - filters
 * - optimistic votes
 *
 * It receives the builds from the server but can optionally re-fetch on mount
 * if you want truly live data (kept here as an example but can be removed).
 */
export default function BuildsClient({
  initialBuilds,
  initialError,
}: BuildsClientProps) {
  // --- Remote data state (initialized from server) ---
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(initialError);
  const [builds, setBuilds] = useState<BuildCard[]>(initialBuilds);

  // --- UI state (filters/votes) ---
  const [caliberFilter, setCaliberFilter] = useState<Caliber | "all">("all");
  const [classFilter, setClassFilter] = useState<BuildClass | "all">("all");
  const [priceFilterId, setPriceFilterId] = useState<string>("all");

  const [votes, setVotes] = useState<Record<string, number>>(() =>
    Object.fromEntries(initialBuilds.map((b) => [b.id, b.votes])),
  );

  const activePriceFilter =
    PRICE_FILTERS.find((p) => p.id === priceFilterId) ?? PRICE_FILTERS[0];

  // Optional: client re-fetch to keep data fresh (can be removed if not needed)
  useEffect(() => {
    // If you don't want client refetching, just return early here.
    if (!API_BASE_URL) return;

    let cancelled = false;

    async function run() {
      try {
        setLoading(true);
        setError(null);

        const res = await fetch(`${API_BASE_URL}/api/v1/builds?limit=50`, {
          method: "GET",
          credentials: "include",
          headers: { "Content-Type": "application/json" },
        });

        if (!res.ok) {
          const txt = await res.text().catch(() => "");
          throw new Error(txt || `Failed to load builds (${res.status})`);
        }

        const data = (await res.json()) as BuildCard[];

        if (cancelled) return;

        setBuilds(data);
        setVotes(Object.fromEntries(data.map((b) => [b.id, b.votes])));
      } catch (e: any) {
        if (!cancelled) setError(e?.message || "Failed to load builds feed");
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    // Comment this out if you want *only* server-side fetching:
    // run();

    return () => {
      cancelled = true;
    };
  }, []);

  const CALIBER_FILTERS = useMemo<(Caliber | "all")[]>(() => {
    const uniq = new Set<string>();
    for (const b of builds) {
      const c = (b.caliber ?? "").trim();
      if (c && c !== "—") uniq.add(c);
    }
    return ["all", ...Array.from(uniq).sort()];
  }, [builds]);

  const filteredBuilds = useMemo(() => {
    return builds.filter((build) => {
      const matchesCaliber =
        caliberFilter === "all" || build.caliber === caliberFilter;

      const matchesClass =
        classFilter === "all" || build.buildClass === classFilter;

      const matchesPrice =
        build.price >= activePriceFilter.min &&
        build.price < activePriceFilter.max;

      return matchesCaliber && matchesClass && matchesPrice;
    });
  }, [builds, caliberFilter, classFilter, activePriceFilter]);

  const handleVote = useCallback((id: string, delta: 1 | -1) => {
    setVotes((prev) => ({
      ...prev,
      [id]: (prev[id] ?? 0) + delta,
    }));
  }, []);

  return (
    <>
      {/* Loading / Error (uses same UI as before) */}
      {loading && (
        <div className="mb-6 rounded-lg border border-zinc-800 bg-zinc-950/70 p-4 text-sm text-zinc-400">
          Loading community builds…
        </div>
      )}

      {error && !loading && (
        <div className="mb-6 rounded-lg border border-red-500/30 bg-red-500/10 p-4 text-sm text-red-200">
          {error}
          <div className="mt-2 text-xs text-red-200/80">
            Dev tip: confirm backend route{" "}
            <span className="font-mono">GET /api/v1/builds</span> is
            implemented + CORS is configured.
          </div>
        </div>
      )}

      {/* Filters */}
      <section className="mb-6 rounded-lg border border-zinc-800 bg-zinc-950/70 p-4 space-y-4">
        <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
          <div>
            <h2 className="text-xs font-semibold tracking-[0.16em] uppercase text-zinc-400">
              Filter Builds
            </h2>
            <p className="text-xs text-zinc-500 mt-1">
              Filter by caliber, class, and price range. (Client-side for MVP.)
            </p>
          </div>

          <div className="text-xs text-zinc-500">
            Showing{" "}
            <span className="text-zinc-200 font-medium">
              {filteredBuilds.length}
            </span>{" "}
            of{" "}
            <span className="text-zinc-200 font-medium">{builds.length}</span>{" "}
            builds
          </div>
        </div>

        <div className="grid gap-3 md:grid-cols-3">
          {/* Caliber filter */}
          <div>
            <div className="text-[0.7rem] uppercase tracking-[0.16em] text-zinc-500 mb-1">
              Caliber
            </div>
            <div className="flex flex-wrap gap-2">
              {CALIBER_FILTERS.map((caliber) => (
                <button
                  key={caliber}
                  type="button"
                  onClick={() =>
                    setCaliberFilter(caliber === "all" ? "all" : caliber)
                  }
                  className={`rounded-full border px-3 py-1 text-xs transition-colors ${
                    caliberFilter === caliber
                      ? "border-amber-400/70 bg-amber-400/10 text-amber-200"
                      : "border-zinc-700 bg-zinc-900/60 text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600"
                  }`}
                >
                  {caliber === "all" ? "All" : caliber}
                </button>
              ))}
            </div>
          </div>

          {/* Class filter */}
          <div>
            <div className="text-[0.7rem] uppercase tracking-[0.16em] text-zinc-500 mb-1">
              Class
            </div>
            <div className="flex flex-wrap gap-2">
              {CLASS_FILTERS.map((cls) => (
                <button
                  key={cls}
                  type="button"
                  onClick={() =>
                    setClassFilter(cls === "all" ? "all" : cls)
                  }
                  className={`rounded-full border px-3 py-1 text-xs transition-colors ${
                    classFilter === cls
                      ? "border-amber-400/70 bg-amber-400/10 text-amber-200"
                      : "border-zinc-700 bg-zinc-900/60 text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600"
                  }`}
                >
                  {cls === "all" ? "All" : cls}
                </button>
              ))}
            </div>
          </div>

          {/* Price filter */}
          <div>
            <div className="text-[0.7rem] uppercase tracking-[0.16em] text-zinc-500 mb-1">
              Price Range
            </div>
            <div className="flex flex-wrap gap-2">
              {PRICE_FILTERS.map((range) => (
                <button
                  key={range.id}
                  type="button"
                  onClick={() => setPriceFilterId(range.id)}
                  className={`rounded-full border px-3 py-1 text-xs transition-colors ${
                    priceFilterId === range.id
                      ? "border-amber-400/70 bg-amber-400/10 text-amber-200"
                      : "border-zinc-700 bg-zinc-900/60 text-zinc-300 hover:bg-zinc-800 hover:border-zinc-600"
                  }`}
                >
                  {range.label}
                </button>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* Build list */}
      <section>
        <div className="space-y-4">
          {filteredBuilds.map((build) => (
            <article
              key={build.id}
              className="flex gap-4 rounded-lg border border-zinc-800 bg-zinc-950/70 p-4"
            >
              {/* Votes column */}
              <div className="flex flex-col items-center justify-center gap-1">
                <button
                  type="button"
                  onClick={() => handleVote(build.id, 1)}
                  className="flex h-6 w-6 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900/70 text-xs text-zinc-300 hover:bg-zinc-800 hover:border-zinc-500"
                  aria-label="Upvote"
                  title="Upvote"
                >
                  ▲
                </button>
                <div className="text-xs font-semibold text-amber-200">
                  {votes[build.id] ?? build.votes}
                </div>
                <button
                  type="button"
                  onClick={() => handleVote(build.id, -1)}
                  className="flex h-6 w-6 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900/70 text-xs text-zinc-300 hover:bg-zinc-800 hover:border-zinc-500"
                  aria-label="Downvote"
                  title="Downvote"
                >
                  ▼
                </button>
              </div>

              {/* Thumbnail */}
              <div className="hidden sm:block">
                <div className="overflow-hidden rounded-md border border-zinc-800 bg-zinc-900/80 h-24 w-40">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={
                      build.coverImageUrl ||
                      "https://placehold.co/320x200/png?text=Build+Photo"
                    }
                    alt={`${build.title} cover`}
                    className="h-full w-full object-cover"
                  />
                </div>
              </div>

              {/* Main content */}
              <div className="flex-1">
                <div className="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
                  <div>
                    <div className="text-[0.7rem] uppercase tracking-[0.16em] text-zinc-500 mb-1">
                      {build.buildClass} · {build.caliber}
                    </div>
                    <h3 className="text-lg md:text-xl font-semibold text-zinc-50">
                      <Link
                        href={`/builds/${build.slug}`}
                        className="hover:text-amber-200 transition-colors"
                      >
                        {build.title}
                      </Link>
                    </h3>
                    <p className="text-xs text-zinc-500 mt-1">
                      Posted by{" "}
                      <span className="text-zinc-300">b/{build.creator}</span>{" "}
                      · Build detail page will show the parts list +
                      comments.
                    </p>
                  </div>

                  <div className="text-right mt-1 md:mt-0">
                    <div className="text-xs uppercase tracking-[0.16em] text-zinc-500">
                      Est. Build Cost
                    </div>
                    <div className="text-lg font-semibold text-amber-300">
                      {build.price > 0 ? (
                        <span>
                          {`$${Math.floor(build.price / 100).toLocaleString()}`}
                        </span>
                      ) : (
                        "—"
                      )}
                    </div>
                  </div>
                </div>

                <div className="mt-3 flex flex-wrap items-center gap-2">
                  {build.tags.map((tag) => (
                    <span
                      key={tag}
                      className="rounded-full border border-zinc-700 bg-zinc-900/60 px-2 py-0.5 text-[0.7rem] text-zinc-400"
                    >
                      {tag}
                    </span>
                  ))}

                  <span className="ml-auto text-[0.7rem] text-zinc-500">
                    Comments + save coming soon.
                  </span>
                </div>
              </div>
            </article>
          ))}

          {!loading && !error && filteredBuilds.length === 0 && (
            <div className="rounded-lg border border-zinc-800 bg-zinc-950/70 p-6 text-center text-sm text-zinc-500">
              No builds match those filters yet.
            </div>
          )}
        </div>
      </section>
    </>
  );
}
