import { useTranslation } from "react-i18next";

import type { components } from "../api/schema";
import { useTerms, useAuthorities } from "../api/queries";
import { labelText } from "../lib/labels";
import { formatDate } from "../lib/format-date";

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

/** Renders one flexible field value as human-readable text, resolving term/authority ids
 *  to labels and localized_text to the active language. */
export function FlexibleFieldValue({
  def,
  value,
  lang,
}: {
  def: FieldDefinitionView;
  value: unknown;
  lang: string;
}) {
  switch (def.data_type) {
    case "term":
      return <TermValue vocabularyId={def.vocabulary_id ?? null} value={value} lang={lang} />;
    case "authority":
      return <AuthorityValue kind={def.authority_kind ?? null} value={value} lang={lang} />;
    case "localized_text":
      return <>{pickLocalized(value, lang)}</>;
    case "date":
      return <>{formatDate(value, lang)}</>;
    case "boolean":
      return <BooleanValue value={value} />;
    default:
      return <>{value == null ? "—" : String(value)}</>;
  }
}

function TermValue({
  vocabularyId,
  value,
  lang,
}: {
  vocabularyId: string | null;
  value: unknown;
  lang: string;
}) {
  const { t } = useTranslation();
  const { data: terms, isLoading } = useTerms(vocabularyId ?? undefined);

  if (typeof value !== "string") return <>—</>;
  const term = terms?.find((x) => x.id === value);
  if (term) return <>{labelText(term.labels, lang)}</>;
  if (isLoading) return <span className="text-muted-foreground">…</span>;
  return (
    <span className="text-muted-foreground">
      {value} {t("objects.unknownRef")}
    </span>
  );
}

function AuthorityValue({
  kind,
  value,
  lang,
}: {
  kind: string | null;
  value: unknown;
  lang: string;
}) {
  const { t } = useTranslation();
  const { data: authorities, isLoading } = useAuthorities(kind ?? undefined);

  if (typeof value !== "string") return <>—</>;
  const authority = authorities?.find((x) => x.id === value);
  if (authority) return <>{labelText(authority.labels, lang)}</>;
  if (isLoading) return <span className="text-muted-foreground">…</span>;
  return (
    <span className="text-muted-foreground">
      {value} {t("objects.unknownRef")}
    </span>
  );
}

function BooleanValue({ value }: { value: unknown }) {
  const { t } = useTranslation();
  return <>{value ? t("common.yes") : t("common.no")}</>;
}

function pickLocalized(value: unknown, lang: string): string {
  if (value && typeof value === "object" && !Array.isArray(value)) {
    const map = value as Record<string, string>;
    return map[lang] ?? map.en ?? Object.values(map)[0] ?? "—";
  }
  return value == null ? "—" : String(value);
}
