"use client";

import { Popover } from "@base-ui/react/popover";
import { Check, ChevronDown } from "lucide-react";
import { useId, useState } from "react";
import type { KeyboardEvent } from "react";
import type { PublicLanguageModel } from "@/lib/public-models";

type ModelSelectorProps = {
  readonly models: readonly PublicLanguageModel[];
  readonly selectedModelId: string;
  readonly disabled?: boolean;
  readonly onSelect: (modelId: string) => void;
};

export function ModelSelector({
  models,
  selectedModelId,
  disabled = false,
  onSelect,
}: ModelSelectorProps) {
  const [open, setOpen] = useState(false);
  const groupName = useId();
  const selectedModel = models.find((model) => model.id === selectedModelId);
  const unavailable = models.length === 0;

  function moveRadioSelection(event: KeyboardEvent<HTMLInputElement>, index: number) {
    const step = event.key === "ArrowDown" || event.key === "ArrowRight"
      ? 1
      : event.key === "ArrowUp" || event.key === "ArrowLeft"
        ? -1
        : 0;
    if (step === 0 || models.length < 2) return;

    event.preventDefault();
    const nextIndex = (index + step + models.length) % models.length;
    const nextModel = models[nextIndex];
    if (!nextModel) return;
    onSelect(nextModel.id);
    setOpen(false);
  }

  return (
    <Popover.Root open={open} onOpenChange={setOpen}>
      <Popover.Trigger
        className="model-selector-trigger"
        type="button"
        disabled={disabled || unavailable}
        aria-label={selectedModel ? `当前模型：${selectedModel.label}，点击切换` : "模型暂不可用"}
      >
        <b>{selectedModel?.label ?? "暂不可用"}</b>
        <ChevronDown aria-hidden="true" />
      </Popover.Trigger>
      <Popover.Portal>
        <Popover.Positioner className="model-selector-positioner" side="top" align="start" sideOffset={8} collisionPadding={12}>
          <Popover.Popup className="model-selector-popup">
            <Popover.Title className="model-selector-title">选择模型</Popover.Title>
            <fieldset className="model-selector-options">
              <legend className="sr-only">选择当前对话使用的模型</legend>
              {models.map((model, index) => (
                <label className="model-selector-option" data-selected={model.id === selectedModelId ? "" : undefined} key={model.id}>
                  <input
                    className="sr-only"
                    type="radio"
                    name={groupName}
                    value={model.id}
                    checked={model.id === selectedModelId}
                    onChange={() => onSelect(model.id)}
                    onClick={() => {
                      if (model.id === selectedModelId) onSelect(model.id);
                      setOpen(false);
                    }}
                    onKeyDown={(event) => moveRadioSelection(event, index)}
                  />
                  <span className="model-selector-copy">
                    <b>{model.label}</b>
                  </span>
                  <Check className="model-selector-check" aria-hidden="true" />
                </label>
              ))}
            </fieldset>
          </Popover.Popup>
        </Popover.Positioner>
      </Popover.Portal>
    </Popover.Root>
  );
}
