// Shared UI primitives extracted from ConfigPage.tsx
import { useState, type ReactNode } from 'react';
import { X, Plus, Trash2 } from 'lucide-react';
import { inputCls } from './constants';
import type { KnownSource } from './types';

export function Field({
  label,
  children,
  hint,
}: {
  label: string;
  children: ReactNode;
  hint?: string;
}) {
  return (
    <div className="space-y-1.5">
      <label className="block text-[13px] font-medium text-[var(--text-secondary)]">{label}</label>
      {children}
      {hint && <p className="text-xs text-[var(--text-muted)]">{hint}</p>}
    </div>
  );
}

export function Toggle({
  checked,
  onChange,
}: {
  checked: boolean;
  onChange: (v: boolean) => void;
}) {
  return (
    <button
      type="button"
      onClick={() => onChange(!checked)}
      className={`relative inline-flex h-6 w-11 shrink-0 rounded-full transition-colors duration-200 ${checked ? 'bg-[var(--accent-cyan)]' : 'bg-[var(--bg-hover)]'}`}
    >
      <span
        className={`absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white shadow-sm transition-transform duration-200 ${checked ? 'translate-x-5' : 'translate-x-0'}`}
      />
    </button>
  );
}

export function TagEditor({ tags, onChange }: { tags: string[]; onChange: (t: string[]) => void }) {
  const [input, setInput] = useState('');
  const add = () => {
    const v = input.trim();
    if (v && !tags.includes(v)) {
      onChange([...tags, v]);
      setInput('');
    }
  };
  return (
    <div className="space-y-2">
      <div className="flex flex-wrap gap-1.5">
        {tags.map((t, i) => (
          <span
            key={t}
            className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)]"
          >
            {t}
            <button
              onClick={() => onChange(tags.filter((_, j) => j !== i))}
              className="hover:text-white transition-colors"
            >
              <X className="h-3 w-3" />
            </button>
          </span>
        ))}
      </div>
      <div className="flex gap-2">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), add())}
          placeholder="输入后按 Enter"
          className={inputCls + ' !text-xs'}
        />
        <button
          onClick={add}
          className="px-2 py-1 rounded-lg bg-[var(--accent-cyan)]/10 text-[var(--accent-cyan)] hover:bg-[var(--accent-cyan)]/20 transition-colors text-xs"
        >
          <Plus className="h-3.5 w-3.5" />
        </button>
      </div>
    </div>
  );
}

export function SectionCard({
  title,
  subtitle,
  children,
}: {
  title: string;
  subtitle?: string;
  children: ReactNode;
}) {
  return (
    <div className="rounded-xl border border-[var(--border-color)] bg-[var(--bg-secondary)]/60 overflow-hidden">
      <div className="px-4 py-2.5 border-b border-[var(--border-color)] bg-[var(--bg-tertiary)]/30">
        <div className="flex items-center gap-2">
          <h3 className="text-sm font-medium text-[var(--text-secondary)]">{title}</h3>
          {subtitle && (
            <span className="text-[10px] text-[var(--text-muted)] bg-[var(--bg-tertiary)] px-1.5 py-0.5 rounded">
              {subtitle}
            </span>
          )}
        </div>
      </div>
      <div className="p-4 space-y-4">{children}</div>
    </div>
  );
}

/** 模态框标题栏：图标 + 标题 + X 关闭按钮，与项目模态框惯例一致 */
export function ModalHeader({
  icon,
  title,
  onClose,
}: {
  icon: ReactNode;
  title: string;
  onClose: () => void;
}) {
  return (
    <div className="flex items-center gap-3 shrink-0 px-6 py-4 border-b border-[var(--border-color)] bg-[var(--bg-tertiary)]/50">
      {icon}
      <span className="text-base font-semibold text-[var(--text-primary)]">{title}</span>
      <button
        onClick={onClose}
        className="ml-auto p-2 rounded-lg text-[var(--text-muted)] hover:text-[var(--text-primary)] hover:bg-[var(--overlay-hover)] transition-colors"
        aria-label="关闭"
        title="关闭 (Esc)"
      >
        <X className="h-5 w-5" />
      </button>
    </div>
  );
}

/** 模态框底部按钮区，与项目模态框惯例一致 */
export function ModalFooter({ children }: { children: ReactNode }) {
  return (
    <div className="shrink-0 px-6 py-3 border-t border-[var(--border-color)] bg-[var(--bg-tertiary)]/30 flex items-center gap-3 justify-end">
      {children}
    </div>
  );
}

export function SourceEditor({
  sources,
  onChange,
  knownSources,
  examplePaths,
  showCustom = true,
}: {
  sources: string[];
  onChange: (s: string[]) => void;
  knownSources: KnownSource[];
  examplePaths?: string[];
  showCustom?: boolean;
}) {
  const [customInput, setCustomInput] = useState('');
  const knownKeys = new Set(knownSources.map((k) => k.key));
  const customPaths = sources.filter((s) => !knownKeys.has(s));

  const toggleKnown = (key: string) => {
    if (sources.includes(key)) {
      onChange(sources.filter((s) => s !== key));
    } else {
      onChange([...sources, key]);
    }
  };

  const addCustom = () => {
    const v = customInput.trim();
    if (v && !sources.includes(v)) {
      onChange([...sources, v]);
      setCustomInput('');
    }
  };

  const removeCustom = (path: string) => {
    onChange(sources.filter((s) => s !== path));
  };

  return (
    <div className="space-y-4">
      {/* Known sources as toggles */}
      <div className="space-y-2">
        {knownSources.map((src) => (
          <div key={src.key} className="flex items-center justify-between py-1.5">
            <div className="flex-1 min-w-0">
              <div className="text-sm text-[var(--text-primary)]">{src.label}</div>
              <div className="text-xs text-[var(--text-muted)] font-mono">{src.description}</div>
            </div>
            <Toggle checked={sources.includes(src.key)} onChange={() => toggleKnown(src.key)} />
          </div>
        ))}
      </div>

      {/* Custom paths (only shown when showCustom is true) */}
      {showCustom && (
        <div className="space-y-2">
          <div className="text-xs font-medium text-[var(--text-muted)] uppercase tracking-wider">
            自定义路径
          </div>
          {customPaths.length > 0 && (
            <div className="flex flex-wrap gap-1.5">
              {customPaths.map((p) => (
                <span
                  key={p}
                  className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)] font-mono"
                >
                  {p}
                  <button
                    onClick={() => removeCustom(p)}
                    className="hover:text-white transition-colors"
                  >
                    <X className="h-3 w-3" />
                  </button>
                </span>
              ))}
            </div>
          )}
          <div className="flex gap-2">
            <input
              value={customInput}
              onChange={(e) => setCustomInput(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), addCustom())}
              placeholder="输入绝对路径，如 D:\my-skills"
              className={inputCls + ' !text-xs font-mono'}
            />
            <button
              onClick={addCustom}
              className="px-2 py-1 rounded-lg bg-[var(--accent-cyan)]/10 text-[var(--accent-cyan)] hover:bg-[var(--accent-cyan)]/20 transition-colors text-xs shrink-0"
            >
              <Plus className="h-3.5 w-3.5" />
            </button>
          </div>
          {examplePaths && (
            <p className="text-xs text-[var(--text-muted)]">示例: {examplePaths.join('、')}</p>
          )}
        </div>
      )}
    </div>
  );
}

export interface CheckboxListOption {
  key: string;
  label: string;
  description?: string;
  /** 可选分组标识，配合 groupBy 使用 */
  group?: string;
}

interface CheckboxListProps {
  options: CheckboxListOption[];
  selected: string[];
  onChange: (selected: string[]) => void;
  /** 未在 options 中出现但已选中的值（legacy 数据），以可移除标签形式展示 */
  extraSelected?: string[];
  emptyHint?: string;
  /** 可选：按返回的分组名分组展示（如 "builtin" / "mcp:xxx"） */
  groupBy?: (option: CheckboxListOption) => string;
}

/**
 * 通用勾选列表组件：用 Toggle 切换每个预设选项；额外的 legacy 已选值以可移除标签展示。
 */
export function CheckboxList({
  options,
  selected,
  onChange,
  extraSelected = [],
  emptyHint,
  groupBy,
}: CheckboxListProps) {
  const toggle = (key: string) =>
    onChange(selected.includes(key) ? selected.filter((k) => k !== key) : [...selected, key]);

  const selectedSet = new Set(selected);
  const optionsInList = new Set(options.map((o) => o.key));
  // 仅展示未出现在 options 中的额外已选值
  const extra = extraSelected.filter((k) => !optionsInList.has(k));

  // 分组渲染
  const renderOptions = (opts: CheckboxListOption[]) => (
    <div className="space-y-1">
      {opts.map((option) => (
        <div key={option.key} className="flex items-center justify-between py-1.5 gap-3">
          <div className="flex-1 min-w-0">
            <div className="text-sm text-[var(--text-primary)] font-mono">{option.label}</div>
            {option.description && (
              <div className="text-xs text-[var(--text-muted)] truncate">{option.description}</div>
            )}
          </div>
          <Toggle checked={selectedSet.has(option.key)} onChange={() => toggle(option.key)} />
        </div>
      ))}
    </div>
  );

  let body: ReactNode;
  if (options.length === 0) {
    body = <p className="text-xs text-[var(--text-muted)]">{emptyHint || '无可用选项'}</p>;
  } else if (groupBy) {
    const groups = new Map<string, CheckboxListOption[]>();
    for (const opt of options) {
      const g = groupBy(opt);
      const arr = groups.get(g) ?? [];
      arr.push(opt);
      groups.set(g, arr);
    }
    body = (
      <div className="space-y-3">
        {Array.from(groups.entries()).map(([g, opts]) => (
          <div key={g}>
            <div className="text-[10px] font-medium text-[var(--text-muted)] uppercase tracking-wider mb-1">
              {g}
            </div>
            {renderOptions(opts)}
          </div>
        ))}
      </div>
    );
  } else {
    body = renderOptions(options);
  }

  return (
    <div className="space-y-2">
      {body}
      {extra.length > 0 && (
        <div>
          <div className="text-[10px] font-medium text-[var(--text-muted)] uppercase tracking-wider mb-1">
            其他已选（不在当前选项中）
          </div>
          <div className="flex flex-wrap gap-1.5">
            {extra.map((key) => (
              <span
                key={key}
                className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)] font-mono"
              >
                {key}
                <button onClick={() => toggle(key)} className="hover:text-white transition-colors">
                  <X className="h-3 w-3" />
                </button>
              </span>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

export function MapEntryHeader({
  name,
  onDelete,
  onRename,
}: {
  name: string;
  onDelete: () => void;
  onRename?: (n: string) => void;
}) {
  const [editing, setEditing] = useState(false);
  const [val, setVal] = useState(name);
  return (
    <div className="flex items-center gap-2 px-4 py-2 bg-[var(--bg-tertiary)]/50 border-b border-[var(--border-color)]">
      {editing ? (
        <input
          value={val}
          onChange={(e) => setVal(e.target.value)}
          onBlur={() => {
            setEditing(false);
            onRename?.(val.trim() || name);
          }}
          onKeyDown={(e) =>
            e.key === 'Enter' && (setEditing(false), onRename?.(val.trim() || name))
          }
          className={inputCls + ' !py-1 !text-xs max-w-[200px]'}
          autoFocus
        />
      ) : (
        <span
          className="text-sm font-mono text-[var(--accent-cyan)] cursor-pointer"
          onClick={() => {
            if (onRename) {
              setVal(name);
              setEditing(true);
            }
          }}
        >
          {name}
        </span>
      )}
      <div className="flex-1" />
      <button
        onClick={onDelete}
        className="p-1 rounded text-[rgb(242,90,90)]/60 hover:text-[rgb(242,90,90)] hover:bg-[rgb(242,90,90)]/10 transition-colors"
      >
        <Trash2 className="h-3.5 w-3.5" />
      </button>
    </div>
  );
}
