/**
 * Select Field Component
 *
 * Renders a dropdown select with static options.
 * Supports optional description, icon, disabled state, and grouping.
 */

import { useMemo, memo } from 'react';
import { Label } from '../ui/label';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '../ui/select';
import { ActionField, ActionFieldOption } from '../../types/action';
import { resolveIcon } from '../../lib/icon-resolver';

interface SelectFieldProps {
  fieldName: string;
  field: ActionField;
  value: string;
  onChange: (value: string) => void;
  error?: string;
}

/**
 * Formats a string value into a readable label.
 * Capitalizes first letter and replaces underscores with spaces.
 */
function formatLabel(value: string): string {
  return value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');
}

/** Group options by their group property. Ungrouped options use '' as key. */
function groupOptions(options: ActionFieldOption[]): Map<string, ActionFieldOption[]> {
  const groups = new Map<string, ActionFieldOption[]>();
  for (const option of options) {
    const key = option.group ?? '';
    const list = groups.get(key);
    if (list) {
      list.push(option);
    } else {
      groups.set(key, [option]);
    }
  }
  return groups;
}

function OptionContent({ option }: { option: ActionFieldOption }) {
  const Icon = resolveIcon(option.icon);

  if (!Icon && !option.description) {
    return <>{option.label}</>;
  }

  return (
    <div className="flex flex-col gap-0.5">
      <span className="flex items-center gap-1.5">
        {Icon && <Icon className="h-3.5 w-3.5 shrink-0 text-slate-500" />}
        {option.label}
      </span>
      {option.description && (
        <span className="text-[11px] text-slate-400 leading-tight">{option.description}</span>
      )}
    </div>
  );
}

export const SelectField = memo(function SelectField({
  fieldName,
  field,
  value,
  onChange,
  error,
}: SelectFieldProps) {
  // Normalize options to handle different PHP formats:
  // - Simple strings: ["foo", "bar"] → [{value: "foo", label: "Foo"}, ...]
  // - Objects with value/label: [{value: "foo", label: "Foo Label"}] → pass through
  // - PHP associative arrays become objects: {key: "Label"} → [{value: "key", label: "Label"}]
  const normalizedOptions = useMemo((): ActionFieldOption[] => {
    if (!field.options) return [];

    // Handle array format (simple strings or {value, label} objects)
    if (Array.isArray(field.options)) {
      return field.options.map((opt) => {
        if (typeof opt === 'string') {
          return { value: opt, label: formatLabel(opt) };
        }
        return opt;
      });
    }

    // Handle object format from PHP associative array: {key: label}
    return Object.entries(field.options).map(([key, label]) => ({
      value: key,
      label: String(label),
    }));
  }, [field.options]);

  const hasGroups = normalizedOptions.some((opt) => opt.group);
  const grouped = useMemo(
    () => (hasGroups ? groupOptions(normalizedOptions) : null),
    [normalizedOptions, hasGroups],
  );

  return (
    <div className="space-y-2">
      <Label htmlFor={fieldName} className="text-slate-900">
        {field.label}
        {field.required && <span className="text-red-600 ml-1">*</span>}
      </Label>

      <Select value={value} onValueChange={onChange}>
        <SelectTrigger id={fieldName} className="border-slate-400">
          <SelectValue placeholder={field.description} />
        </SelectTrigger>
        <SelectContent>
          {grouped
            ? Array.from(grouped.entries()).map(([groupName, options]) => (
                <SelectGroup key={groupName}>
                  {groupName && <SelectLabel>{groupName}</SelectLabel>}
                  {options.map((option) => (
                    <SelectItem
                      key={option.value}
                      value={option.value}
                      disabled={option.disabled}
                    >
                      <OptionContent option={option} />
                    </SelectItem>
                  ))}
                </SelectGroup>
              ))
            : normalizedOptions.map((option) => (
                <SelectItem key={option.value} value={option.value} disabled={option.disabled}>
                  <OptionContent option={option} />
                </SelectItem>
              ))}
        </SelectContent>
      </Select>

      <p className="text-xs text-slate-500">{field.description}</p>
      {error && <p className="text-xs text-red-600">{error}</p>}
    </div>
  );
});
