import { useState } from "react";
import { X } from "lucide-react";
import { cn } from "../../lib/utils";
import type { SettingsMeta } from "../../lib/useSettings";

// ---------------------------------------------------------------------------
// Reusable field components
// ---------------------------------------------------------------------------

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

export function NumberInput({
  value,
  onChange,
  min,
  max,
  step,
  className,
}: {
  value: number;
  onChange: (v: number) => void;
  min?: number;
  max?: number;
  step?: number;
  className?: string;
}) {
  return (
    <input
      type="number"
      value={value}
      onChange={(e) => onChange(Number(e.target.value))}
      min={min}
      max={max}
      step={step}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors",
        className
      )}
    />
  );
}

export function StringInput({
  value,
  onChange,
  placeholder,
  className,
}: {
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  className?: string;
}) {
  return (
    <input
      type="text"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm font-mono text-foreground",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors",
        className
      )}
    />
  );
}

export function TextArea({
  value,
  onChange,
  placeholder,
  rows = 3,
}: {
  value: string;
  onChange: (v: string) => void;
  placeholder?: string;
  rows?: number;
}) {
  return (
    <textarea
      value={value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      rows={rows}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground resize-y",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors"
      )}
    />
  );
}

export function Toggle({
  checked,
  onChange,
}: {
  checked: boolean;
  onChange: (v: boolean) => void;
}) {
  return (
    <button
      type="button"
      role="switch"
      aria-checked={checked}
      onClick={() => onChange(!checked)}
      className={cn(
        "relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
        checked ? "bg-primary" : "bg-raised"
      )}
    >
      <span
        className={cn(
          "inline-block h-4 w-4 rounded-full bg-white transition-transform",
          checked ? "translate-x-6" : "translate-x-1"
        )}
      />
    </button>
  );
}

export function SelectInput({
  value,
  onChange,
  options,
}: {
  value: string;
  onChange: (v: string) => void;
  options: { value: string; label: string }[];
}) {
  return (
    <select
      value={value}
      onChange={(e) => onChange(e.target.value)}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors"
      )}
    >
      {options.map((o) => (
        <option key={o.value} value={o.value}>
          {o.label}
        </option>
      ))}
    </select>
  );
}

/** Role picker dropdown -- selects a single role ID */
export function RolePicker({
  value,
  onChange,
  roles,
  placeholder = "Select a role...",
}: {
  value: string | undefined;
  onChange: (v: string | undefined) => void;
  roles: SettingsMeta["roles"];
  placeholder?: string;
}) {
  return (
    <select
      value={value ?? ""}
      onChange={(e) => onChange(e.target.value || undefined)}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors"
      )}
    >
      <option value="">{placeholder}</option>
      {roles.map((r) => (
        <option key={r.id} value={r.id}>
          {r.name}
        </option>
      ))}
    </select>
  );
}

/** Channel picker dropdown -- selects a single channel ID (text channels only) */
export function ChannelPicker({
  value,
  onChange,
  channels,
  placeholder = "Select a channel...",
}: {
  value: string | undefined;
  onChange: (v: string | undefined) => void;
  channels: SettingsMeta["channels"];
  placeholder?: string;
}) {
  // type 0 = text channel
  const textChannels = channels.filter((c) => c.type === 0);
  return (
    <select
      value={value ?? ""}
      onChange={(e) => onChange(e.target.value || undefined)}
      className={cn(
        "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground",
        "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
        "transition-colors"
      )}
    >
      <option value="">{placeholder}</option>
      {textChannels.map((c) => (
        <option key={c.id} value={c.id}>
          #{c.name}
        </option>
      ))}
    </select>
  );
}

/** Multi-select role picker for color roles */
export function MultiRolePicker({
  selected,
  onChange,
  roles,
}: {
  selected: string[];
  onChange: (v: string[]) => void;
  roles: SettingsMeta["roles"];
}) {
  const available = roles.filter((r) => !selected.includes(r.id));
  const selectedRoles = selected
    .map((id) => roles.find((r) => r.id === id))
    .filter(Boolean) as SettingsMeta["roles"];

  return (
    <div className="space-y-2">
      {selectedRoles.length > 0 && (
        <div className="flex flex-wrap gap-2">
          {selectedRoles.map((r) => (
            <span
              key={r.id}
              className="inline-flex items-center gap-1.5 bg-primary/15 border border-primary/30 rounded-full px-3 py-1 text-xs font-medium"
            >
              <span
                className="w-2.5 h-2.5 rounded-full"
                style={{ backgroundColor: r.color !== "#000000" ? r.color : "#6B7280" }}
              />
              {r.name}
              <button
                type="button"
                onClick={() => onChange(selected.filter((id) => id !== r.id))}
                className="ml-0.5 text-text-tertiary hover:text-destructive transition-colors"
              >
                <X className="w-3 h-3" />
              </button>
            </span>
          ))}
        </div>
      )}
      {available.length > 0 && (
        <select
          value=""
          onChange={(e) => {
            if (e.target.value) onChange([...selected, e.target.value]);
          }}
          className={cn(
            "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground",
            "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
            "transition-colors"
          )}
        >
          <option value="">Add a color role...</option>
          {available.map((r) => (
            <option key={r.id} value={r.id}>
              {r.name}
            </option>
          ))}
        </select>
      )}
    </div>
  );
}

/** OpenTDB category IDs */
const TRIVIA_CATEGORIES: { id: number; name: string }[] = [
  { id: 9, name: "General Knowledge" },
  { id: 10, name: "Books" },
  { id: 11, name: "Film" },
  { id: 12, name: "Music" },
  { id: 13, name: "Musicals & Theatre" },
  { id: 14, name: "Television" },
  { id: 15, name: "Video Games" },
  { id: 16, name: "Board Games" },
  { id: 17, name: "Science & Nature" },
  { id: 18, name: "Computers" },
  { id: 19, name: "Mathematics" },
  { id: 20, name: "Mythology" },
  { id: 21, name: "Sports" },
  { id: 22, name: "Geography" },
  { id: 23, name: "History" },
  { id: 24, name: "Politics" },
  { id: 25, name: "Art" },
  { id: 26, name: "Celebrities" },
  { id: 27, name: "Animals" },
  { id: 28, name: "Vehicles" },
  { id: 29, name: "Comics" },
  { id: 30, name: "Gadgets" },
  { id: 31, name: "Anime & Manga" },
  { id: 32, name: "Cartoons & Animations" },
];

export function CategoryPicker({
  selected,
  onChange,
}: {
  selected: number[];
  onChange: (v: number[]) => void;
}) {
  const available = TRIVIA_CATEGORIES.filter((c) => !selected.includes(c.id));
  const selectedCats = selected
    .map((id) => TRIVIA_CATEGORIES.find((c) => c.id === id))
    .filter(Boolean) as typeof TRIVIA_CATEGORIES;

  return (
    <div className="space-y-2">
      {selectedCats.length > 0 && (
        <div className="flex flex-wrap gap-2">
          {selectedCats.map((c) => (
            <span
              key={c.id}
              className="inline-flex items-center gap-1.5 bg-info/15 border border-info/30 rounded-full px-3 py-1 text-xs font-medium"
            >
              {c.name}
              <button
                type="button"
                onClick={() => onChange(selected.filter((id) => id !== c.id))}
                className="ml-0.5 text-text-tertiary hover:text-destructive transition-colors"
              >
                <X className="w-3 h-3" />
              </button>
            </span>
          ))}
        </div>
      )}
      {available.length > 0 && (
        <select
          value=""
          onChange={(e) => {
            const id = Number(e.target.value);
            if (id) onChange([...selected, id]);
          }}
          className={cn(
            "w-full bg-input border border-border rounded-md px-3 py-2 text-sm text-foreground",
            "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary/30",
            "transition-colors"
          )}
        >
          <option value="">Add a category...</option>
          {available.map((c) => (
            <option key={c.id} value={c.id}>
              {c.name}
            </option>
          ))}
        </select>
      )}
    </div>
  );
}

/** Key-value editor for feature override flags */
export function FeatureOverridesEditor({
  value,
  onChange,
}: {
  value: Record<string, boolean>;
  onChange: (v: Record<string, boolean>) => void;
}) {
  const [newKey, setNewKey] = useState("");
  const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));

  const addFlag = () => {
    const key = newKey.trim().toLowerCase().replace(/\s+/g, "_");
    if (!key || key in value) return;
    onChange({ ...value, [key]: true });
    setNewKey("");
  };

  return (
    <div className="space-y-3">
      {entries.length > 0 && (
        <div className="space-y-2">
          {entries.map(([key, enabled]) => (
            <div
              key={key}
              className="flex items-center justify-between py-1.5"
            >
              <span
                className={cn(
                  "text-sm font-mono",
                  enabled ? "text-foreground" : "text-text-disabled"
                )}
              >
                {key}
              </span>
              <div className="flex items-center gap-3">
                <Toggle
                  checked={enabled}
                  onChange={(v) => onChange({ ...value, [key]: v })}
                />
                <button
                  type="button"
                  onClick={() => {
                    const { [key]: _, ...rest } = value;
                    onChange(rest);
                  }}
                  className="text-text-tertiary hover:text-destructive transition-colors"
                >
                  <X className="w-3.5 h-3.5" />
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
      <div className="flex gap-2">
        <StringInput
          value={newKey}
          onChange={setNewKey}
          placeholder="feature_name"
          className="flex-1"
        />
        <button
          type="button"
          onClick={addFlag}
          disabled={!newKey.trim()}
          className={cn(
            "rounded-md px-4 py-2 text-sm font-medium transition-colors",
            newKey.trim()
              ? "bg-primary/15 text-primary hover:bg-primary/25 border border-primary/30"
              : "bg-raised text-text-disabled cursor-not-allowed"
          )}
        >
          Add
        </button>
      </div>
    </div>
  );
}

export function SectionCard({
  title,
  icon: Icon,
  children,
}: {
  title: string;
  icon: React.ComponentType<{ className?: string }>;
  children: React.ReactNode;
}) {
  return (
    <div className="bg-card rounded-lg border border-border">
      <div className="flex items-center gap-2.5 px-6 py-4 border-b border-border">
        <Icon className="w-4 h-4 text-primary" />
        <h3 className="text-sm font-semibold">{title}</h3>
      </div>
      <div className="px-6 py-5 space-y-5">{children}</div>
    </div>
  );
}
