import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useQuery } from "@tanstack/react-query";
import { qk } from "../lib/queryKeys";
import { X } from "lucide-react";
import { api, type FeedFilters } from "../lib/api";
import { useScrollFade } from "../lib/useScrollFade";
import { inputCls } from "./ui/form";

// Pick channels to narrow the feed to — several OR together, so every other filter then applies
// across all of them. Until this existed the filter was settable only via a shared "?channel=" link:
// the panel had a remove button for something nothing could apply.
//
// It owns its channel query rather than letting the Sidebar hold it: the Sidebar is mounted for the
// whole feed page, but SidePanel only renders its children once the panel is open, so keeping the
// fetch here means a subscription list of a few hundred loads when the picker is actually looked at.
export default function ChannelPicker({
  filters,
  setFilters,
}: {
  filters: FeedFilters;
  setFilters: (f: FeedFilters) => void;
}) {
  const { t } = useTranslation();
  const [query, setQuery] = useState("");
  // Same edge-fade affordance the nav rail and the panel body use to hint at more content.
  const fade = useScrollFade();
  const channelsQuery = useQuery({
    queryKey: qk.channels(),
    queryFn: api.channels,
    staleTime: 5 * 60_000,
  });

  const q = query.trim().toLowerCase();
  const all = channelsQuery.data ?? [];
  const matches = q ? all.filter((c) => (c.title ?? c.id).toLowerCase().includes(q)) : all;
  const picked = filters.channelIds;
  const nameOf = (id: string) => all.find((c) => c.id === id)?.title ?? id;
  const toggle = (id: string) =>
    setFilters({
      ...filters,
      channelIds: picked.includes(id) ? picked.filter((x) => x !== id) : [...picked, id],
    });

  return (
    <>
      {/* The picks sit above the list so they stay visible once the list scrolls away. */}
      {picked.length > 0 && (
        <div className="flex flex-wrap gap-1.5 pb-2">
          {picked.map((id) => (
            <button
              key={id}
              onClick={() => toggle(id)}
              title={t("sidebar.channelRemove", { name: nameOf(id) })}
              className="inline-flex items-center gap-1 max-w-full pl-2.5 pr-1.5 py-1 rounded-full bg-accent text-accent-fg text-xs shadow-sm hover:opacity-90 transition"
            >
              <span className="truncate">{nameOf(id)}</span>
              <X className="w-3 h-3 shrink-0" />
            </button>
          ))}
        </div>
      )}
      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder={t("sidebar.channelSearch")}
        aria-label={t("sidebar.channelSearch")}
        className={inputCls}
      />
      {/* The order isn't arbitrary and isn't alphabetical — say so, or the top of the list looks
          random to anyone who hasn't set a priority. Only while unfiltered: a search reorders nothing
          but does drop the rows that explain it. */}
      {!q && all.length > 0 && (
        <div className="px-2 pt-1.5 text-[11px] text-muted">{t("sidebar.channelOrder")}</div>
      )}
      <div
        ref={fade.ref}
        style={fade.style}
        className="mt-1.5 max-h-44 overflow-y-auto no-scrollbar flex flex-col gap-0.5"
      >
        {matches.length === 0 ? (
          <div className="px-2 py-1.5 text-xs text-muted">
            {channelsQuery.isLoading ? t("sidebar.loading") : t("sidebar.noChannelMatch")}
          </div>
        ) : (
          matches.map((c) => {
            const on = picked.includes(c.id);
            return (
              <button
                key={c.id}
                onClick={() => toggle(c.id)}
                aria-pressed={on}
                // shrink-0 is load-bearing: these are flex children in a max-height box, so without
                // them they squash to ~12px each and clip their own text instead of the box scrolling.
                className={`w-full shrink-0 text-left text-sm px-2 py-1.5 rounded-lg truncate transition ${
                  on ? "text-accent font-medium" : "text-muted hover:text-fg hover:bg-card"
                }`}
              >
                {c.title ?? c.id}
              </button>
            );
          })
        )}
      </div>
    </>
  );
}
