import { useState } from "react";
import { useTranslation } from "react-i18next";

import type { components } from "../api/schema";
import { useFieldDefinitions, useDeleteFieldDefinition } from "../api/queries";
import { useLang } from "../lib/use-lang";
import { rowStateClass } from "../lib/class-recipes";
import { labelText } from "../lib/labels";
import { byLabel, compareStrings } from "../lib/sort";
import { focusRing } from "../lib/focus-ring";
import { DeleteConfirmDialog } from "../components/delete-confirm-dialog";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import { Input } from "@/components/ui/input";
import { ListSkeleton } from "@/components/ui/skeletons";

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

export function FieldList({
  selectedKey,
  onSelect,
}: {
  selectedKey: string | null;
  onSelect: (def: FieldDefinitionView) => void;
}) {
  const { t } = useTranslation();
  const { data, isLoading, isError } = useFieldDefinitions();
  const deleteField = useDeleteFieldDefinition();
  const lang = useLang();
  const [filter, setFilter] = useState("");

  if (isLoading) return <ListSkeleton rows={6} />;

  if (isError) return <p className="p-4 text-sm text-destructive">{t("fields.loadError")}</p>;
  if (!data || data.length === 0)
    return <p className="p-4 text-sm text-muted-foreground">{t("fields.empty")}</p>;

  const q = filter.trim().toLowerCase();
  const filtered = (data ?? []).filter(
    (d) =>
      !q ||
      labelText(d.labels, lang).toLowerCase().includes(q) ||
      d.key.toLowerCase().includes(q),
  );

  const groups = new Map<string, FieldDefinitionView[]>();

  for (const def of filtered) {
    const key = def.group?.trim() ? def.group : t("fields.other");
    const bucket = groups.get(key) ?? [];

    bucket.push(def);
    groups.set(key, bucket);
  }

  const otherLabel = t("fields.other");
  const entries = [...groups.entries()].sort((a, b) => {
    if (a[0] === otherLabel) return 1;
    if (b[0] === otherLabel) return -1;
    return compareStrings(lang, a[0], b[0]);
  });

  return (
    <div className="flex h-full flex-col">
      <div className="border-b p-2">
        <Input
          aria-label={t("common.filter")}
          placeholder={t("common.filter")}
          value={filter}
          onChange={(e) => setFilter(e.target.value)}
        />
      </div>
      {filtered.length === 0 ? (
        <p className="p-3 text-sm text-muted-foreground">{t("common.noMatches")}</p>
      ) : (
        <ul className="overflow-auto">
          {entries.map(([group, defs]) => (
            <li key={group}>
              <div className="flex items-center justify-between border-b bg-muted px-3 py-1 label-caption">
                <span>{group}</span>
                <Badge variant="secondary">{defs.length}</Badge>
              </div>
              <ul>
                {[...defs].sort(byLabel(lang)).map((def) => (
                  <li
                    key={def.key}
                    className={`flex items-center gap-2 border-b px-3 py-2 text-sm ${rowStateClass(
                      def.key === selectedKey,
                    )}`}
                  >
                    <button
                      type="button"
                      className={cn(
                        "flex min-w-0 flex-1 items-center gap-2 rounded-sm text-left",
                        focusRing,
                      )}
                      aria-pressed={def.key === selectedKey}
                      onClick={() => onSelect(def)}
                    >
                      <span className="min-w-0 truncate font-medium">
                        {labelText(def.labels, lang)}
                      </span>
                      <span className="text-xs text-muted-foreground">{def.key}</span>
                      <Badge variant="secondary" className="shrink-0">
                        {t(`fields.types.${def.data_type}`)}
                      </Badge>
                      {def.required && (
                        <span
                          className="shrink-0 text-xs text-destructive"
                          title={t("fields.required")}
                          aria-label={t("fields.required")}
                        >
                          *
                        </span>
                      )}
                    </button>
                    <DeleteConfirmDialog
                      description={t("actions.confirmDeleteField")}
                      onConfirm={() => deleteField.mutateAsync(def.key)}
                    />
                  </li>
                ))}
              </ul>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
