import { Fragment, useState, type ReactNode } from "react";
import { useTranslation } from "react-i18next";

import type { components } from "../api/schema";
import { byLabel } from "../lib/sort";
import { labelText } from "../lib/labels";
import { Input } from "@/components/ui/input";
import { ListSkeleton } from "@/components/ui/skeletons";

type LabelView = components["schemas"]["LabelView"];

/** Filterable, alphabetically-sorted list of labelled records with the standard
 *  loading / error / empty / no-matches states. The filter input stays visible
 *  during load (matching the prior page behaviour). */
export function FilteredRecordList<T extends { id: string; labels: LabelView[] }>({
  records,
  lang,
  isLoading,
  isError,
  loadErrorText,
  emptyText,
  renderRow,
}: {
  records: T[] | undefined;
  lang: string;
  isLoading: boolean;
  isError: boolean;
  loadErrorText: string;
  emptyText: string;
  renderRow: (record: T) => ReactNode;
}) {
  const { t } = useTranslation();
  const [filter, setFilter] = useState("");

  const q = filter.trim().toLowerCase();
  const rows = [...(records ?? [])]
    .filter((r) => !q || labelText(r.labels, lang).toLowerCase().includes(q))
    .sort(byLabel(lang));

  return (
    <>
      <div className="mb-3">
        <Input
          aria-label={t("common.filter")}
          placeholder={t("common.filter")}
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
      </div>
      {isLoading ? (
        <ListSkeleton className="mb-4" rows={5} />
      ) : (
        <ul className="mb-4">
          {isError && <li className="text-sm text-destructive">{loadErrorText}</li>}
          {!isError && records?.length === 0 && (
            <li className="text-sm text-muted-foreground">{emptyText}</li>
          )}
          {!isError && records && records.length > 0 && rows.length === 0 && (
            <li className="text-sm text-muted-foreground">{t("common.noMatches")}</li>
          )}
          {rows.map((r) => (
            <Fragment key={r.id}>{renderRow(r)}</Fragment>
          ))}
        </ul>
      )}
    </>
  );
}
