/**
 * `PluginLayoutSelectorSection` — the "Layouts plugins" section building block
 * (ticket #43, F4, carnet §10: "Section `Layouts plugins` dans le sélecteur").
 *
 * Lists every plugin layout contribution currently loaded (disabled/missing
 * plugins never appear — carnet §1.3: only `enabled` plugins are loaded, so
 * there is nothing to filter here beyond what the registry already omits).
 *
 * Presentational only: the caller owns whether selecting a contribution creates
 * a named plugin layout, replaces an unavailable cell, or just previews it.
 */

import type { PluginLayoutContribution } from "@/domain";
import type { PluginRuntimeRegistry } from "@/plugins/runtime";

export interface PluginLayoutChoice {
  pluginId: string;
  pluginDisplayName: string;
  layout: PluginLayoutContribution;
}

function nonEmptyString(value: unknown): string | undefined {
  return typeof value === "string" && value.trim().length > 0 ? value : undefined;
}

function objectOrNull(value: unknown): Record<string, unknown> | null {
  return value !== null && typeof value === "object" ? (value as Record<string, unknown>) : null;
}

function finiteOrder(value: unknown): number {
  return typeof value === "number" && Number.isFinite(value) ? value : 0;
}

function compareText(a: unknown, b: unknown): number {
  return String(a ?? "").localeCompare(String(b ?? ""));
}

export function listPluginLayoutChoices(registry: PluginRuntimeRegistry): PluginLayoutChoice[] {
  return registry
    .layoutContributions()
    .flatMap(({ pluginId, pluginDisplayName, layout }) => {
      const layoutObject = objectOrNull(layout);
      if (!layoutObject) return [];
      const type = nonEmptyString(layoutObject.type);
      const label = nonEmptyString(layoutObject.label);
      if (!type || !label) return [];
      return [
        {
          pluginId,
          pluginDisplayName: nonEmptyString(pluginDisplayName) ?? pluginId,
          layout: {
            ...layout,
            type,
            label,
            order: finiteOrder(layoutObject.order),
            icon: nonEmptyString(layoutObject.icon),
          },
        },
      ];
    })
    .sort(
      (a, b) =>
        (a.layout.order ?? 0) - (b.layout.order ?? 0) ||
        compareText(a.pluginDisplayName, b.pluginDisplayName) ||
        compareText(a.layout.label, b.layout.label),
    );
}

interface PluginLayoutSelectorSectionProps {
  registry: PluginRuntimeRegistry;
  onSelect: (choice: PluginLayoutChoice) => void;
}

export function PluginLayoutSelectorSection({
  registry,
  onSelect,
}: PluginLayoutSelectorSectionProps) {
  const choices = listPluginLayoutChoices(registry);
  if (choices.length === 0) return null;

  return (
    <div role="group" aria-label="Layouts plugins">
      <p className="px-3 pt-2 text-[0.65rem] font-semibold uppercase tracking-wide text-faint">
        Layouts plugins
      </p>
      {choices.map((choice) => (
        <button
          key={`${choice.pluginId}:${choice.layout.type}`}
          type="button"
          role="menuitem"
          aria-label={`create ${choice.layout.label} layout`}
          onClick={() => onSelect(choice)}
          className="flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm text-content hover:bg-raised"
        >
          <span>{choice.layout.label}</span>
          <span className="text-xs text-faint">{choice.pluginDisplayName}</span>
        </button>
      ))}
    </div>
  );
}
