"use client";

import type { AdapterResult, RegistryAvailability } from "../types";
import { CommercialEmptyState } from "./CommercialEmptyState";
import {
  commercialEntityName,
  fieldLabel,
  friendlyMessage,
  getRegistryPresentation,
  isTechnicalField,
  presentValue,
  registryKindForField,
} from "../presentation";

function availabilityLabel(a: RegistryAvailability): string {
  switch (a) {
    case "loading":
      return "در حال بارگذاری…";
    case "empty":
      return "خالی";
    case "unavailable":
      return "در دسترس نیست";
    case "permission_denied":
      return "بدون دسترسی";
    case "error":
      return "خطا";
    default:
      return "";
  }
}

function PresentedValue({ value, contextKey }: { value: unknown; contextKey?: string }) {
  const presented = presentValue(value);
  if (Array.isArray(presented)) {
    return (
      <div className="grid gap-2">
        {presented.map((item, index) => (
          typeof item === "string" ? (
            <span key={index} className="w-fit rounded-full bg-gray-100 px-2.5 py-1 text-xs text-gray-700">
              {item}
            </span>
          ) : (
            <div key={index} className="rounded-xl border border-gray-100 bg-white p-2">
              <PresentedValue value={item} contextKey={contextKey} />
            </div>
          )
        ))}
      </div>
    );
  }
  if (presented && typeof presented === "object") {
    const entries = Object.entries(presented).filter(([key]) => !isTechnicalField(key));
    const referencedKind = registryKindForField(contextKey);
    const codeEntry = Object.entries(presented).find(([key]) => /(^code$|_code$)/.test(key));
    const explicitName =
      typeof presented.display_name === "string"
        ? presented.display_name
        : typeof presented.title === "string"
          ? presented.title
          : null;
    const objectTitle =
      referencedKind && codeEntry
        ? commercialEntityName(referencedKind, codeEntry[1], explicitName)
        : null;
    return (
      <details className="rounded-xl border border-gray-100 bg-gray-50 p-3">
        <summary className="cursor-pointer text-xs font-semibold text-secondary">
          {objectTitle || "مشاهده جزئیات"}
        </summary>
        <dl className="mt-3 grid gap-3 sm:grid-cols-2">
          {entries.map(([key, nested]) => (
            <div key={key}>
              <dt className="text-[11px] text-gray-500">{fieldLabel(key)}</dt>
              <dd className="mt-1 text-xs text-secondary"><PresentedValue value={nested} contextKey={key} /></dd>
            </div>
          ))}
        </dl>
      </details>
    );
  }
  return <>{presented}</>;
}

/** Generic human-facing catalog list. Implementation identifiers are deliberately hidden. */
export function RegistryBrowser({
  kind,
  title,
  subtitle,
  result,
  codeKey,
  nameKey = "display_name",
  emptyTitle,
}: {
  kind: string;
  title?: string;
  subtitle?: string;
  result: AdapterResult<any[]> | null;
  codeKey: string;
  nameKey?: string;
  emptyTitle?: string;
}) {
  const presentation = getRegistryPresentation(kind);
  const sectionTitle = title || presentation.sectionTitle;
  if (!result || result.availability === "loading") {
    return (
      <section>
        <h3 className="text-sm font-semibold text-secondary">{sectionTitle}</h3>
        <p className="mt-2 text-xs text-gray-500">{availabilityLabel("loading")}</p>
      </section>
    );
  }

  if (result.availability !== "ready" || !result.data.length) {
    return (
      <section>
        <h3 className="text-sm font-semibold text-secondary">{sectionTitle}</h3>
        {subtitle ? <p className="mt-1 text-xs text-gray-500">{subtitle}</p> : null}
        <div className="mt-2">
          <CommercialEmptyState
            title={emptyTitle || presentation.emptyStateTitle}
            description={friendlyMessage(result.message, presentation.emptyStateDescription)}
          />
        </div>
      </section>
    );
  }

  return (
    <section>
      <h3 className="text-sm font-semibold text-secondary">{sectionTitle}</h3>
      {subtitle ? <p className="mt-1 text-xs text-gray-500">{subtitle}</p> : null}
      <ul className="mt-3 grid gap-2 sm:grid-cols-2">
        {result.data.map((raw, idx) => {
          const item = (raw && typeof raw === "object" ? raw : {}) as Record<string, unknown>;
          const code = String(item[codeKey] ?? idx);
          const explicitName = typeof item[nameKey] === "string" ? String(item[nameKey]) : null;
          const name = commercialEntityName(kind, code, explicitName);
          const meta = item.metadata;
          const detailEntries = Object.entries(item).filter(
            ([key, value]) =>
              key !== codeKey &&
              key !== nameKey &&
              key !== "metadata" &&
              !isTechnicalField(key) &&
              value != null
          );
          return (
            <li
              key={code}
              className="rounded-xl border border-gray-100 bg-white px-3 py-2 text-sm shadow-sm"
            >
              <p className="font-medium text-secondary">{name}</p>
              {detailEntries.length ? (
                <dl className="mt-3 space-y-2">
                  {detailEntries.slice(0, 4).map(([key, value]) => (
                    <div key={key} className="flex items-start justify-between gap-3 text-xs">
                      <dt className="text-gray-500">{fieldLabel(key)}</dt>
                      <dd className="text-left text-secondary"><PresentedValue value={value} contextKey={key} /></dd>
                    </div>
                  ))}
                </dl>
              ) : null}
              {meta && typeof meta === "object" && !Array.isArray(meta) ? (
                <div className="mt-3"><PresentedValue value={meta} contextKey="metadata" /></div>
              ) : null}
            </li>
          );
        })}
      </ul>
    </section>
  );
}

/** Renders an arbitrary metadata bag without whitelisting attribute keys. */
export function MetadataBagView({
  title,
  attributes,
  message,
  availability,
}: {
  title: string;
  attributes?: Record<string, unknown> | null;
  message?: string;
  availability?: RegistryAvailability;
}) {
  const entries = attributes ? Object.entries(attributes) : [];
  if (!entries.length) {
    return (
      <CommercialEmptyState
        title={title}
        description={friendlyMessage(message, availabilityLabel(availability || "empty"))}
      />
    );
  }
  return (
    <div className="rounded-2xl border border-gray-100 bg-white p-4">
      <h3 className="text-sm font-semibold text-secondary">{title}</h3>
      <dl className="mt-3 space-y-2">
        {entries.filter(([key]) => !isTechnicalField(key)).map(([key, value]) => (
          <div key={key} className="rounded-xl bg-gray-50 p-3 text-xs">
            <dt className="text-gray-500">{fieldLabel(key)}</dt>
            <dd className="mt-2 text-secondary">
              <PresentedValue value={value} contextKey={key} />
            </dd>
          </div>
        ))}
      </dl>
    </div>
  );
}
