import { Coffee, Snail, Timer, Zap, type LucideIcon } from "lucide-react";
import { GradientIcon } from "~/components/ui/GradientIcon";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select";
import { cn } from "~/lib/utils";
import { CHESS_CLOCK_PRESETS } from "~/lib/draft-timer";

// ─── Types & constants ────────────────────────────────────────────────────────

type TimeUnit = "sec" | "min" | "hr";

export const STANDARD_PRESETS: { value: string; label: string }[] = [
  { value: "15", label: "15 sec" },
  { value: "30", label: "30 sec" },
  { value: "60", label: "1 min" },
  { value: "90", label: "90 sec" },
  { value: "120", label: "2 min" },
  { value: "900", label: "15 min" },
  { value: "3600", label: "1 hr" },
  { value: "7200", label: "2 hr" },
  { value: "14400", label: "4 hr" },
  { value: "28800", label: "8 hr" },
  { value: "43200", label: "12 hr" },
];

export const CHESS_PRESETS: {
  value: string;
  label: string;
  icon: LucideIcon;
  desc: string;
  bankSec: number;
  incrSec: number;
}[] = [
  { ...CHESS_CLOCK_PRESETS[0], label: "Fast",      icon: Zap,    desc: "~1 hour"     },
  { ...CHESS_CLOCK_PRESETS[1], label: "Standard",  icon: Timer,  desc: "~90 minutes" },
  { ...CHESS_CLOCK_PRESETS[2], label: "Slow",      icon: Coffee, desc: "~1 week"     },
  { ...CHESS_CLOCK_PRESETS[3], label: "Very Slow", icon: Snail,  desc: "~2 weeks"    },
];

export function isSlowPreset(s: string): boolean {
  return s === "slow" || s === "very-slow";
}

// ─── Internal helpers ─────────────────────────────────────────────────────────

function secToDisplay(sec: number): [number, TimeUnit] {
  if (sec >= 3600 && sec % 3600 === 0) return [sec / 3600, "hr"];
  if (sec >= 60 && sec % 60 === 0) return [sec / 60, "min"];
  return [sec, "sec"];
}

function displayToSec(amount: string, unit: TimeUnit): number {
  const n = parseFloat(amount) || 0;
  if (unit === "hr") return Math.round(n * 3600);
  if (unit === "min") return Math.round(n * 60);
  return Math.round(n);
}

export function formatSec(sec: number): string {
  if (sec >= 3600 && sec % 3600 === 0) return `${sec / 3600} hr`;
  if (sec >= 60 && sec % 60 === 0) return `${sec / 60} min`;
  return `${sec} sec`;
}

export function formatDraftSpeed(speed: string, mode: "chess_clock" | "standard"): string {
  if (mode === "standard") {
    const s = parseInt(speed, 10);
    if (s >= 3600) return `${s / 3600} hr`;
    if (s >= 60) return `${s / 60} min`;
    return `${s} sec`;
  }
  if (speed.startsWith("custom:")) {
    const [, b, i] = speed.split(":");
    return `Custom (${formatSec(parseInt(b, 10))} bank + ${formatSec(parseInt(i, 10))} / pick)`;
  }
  const map: Record<string, string> = {
    fast: "Fast (1 min + 10 sec)",
    standard: "Standard (2 min + 15 sec)",
    slow: "Slow (8 hr + 1 hr)",
    "very-slow": "Very Slow (12 hr + 1 hr)",
  };
  return map[speed] ?? speed;
}

// ─── Component ────────────────────────────────────────────────────────────────

export interface DraftSpeedPickerProps {
  timerMode: "chess_clock" | "standard";
  value: string;
  onChange: (v: string) => void;
  disabled?: boolean;
}

export function DraftSpeedPicker({ timerMode, value, onChange, disabled }: DraftSpeedPickerProps) {
  const isStdPreset = STANDARD_PRESETS.some((p) => p.value === value);
  const isChessPreset = CHESS_PRESETS.some((p) => p.value === value);
  const isCustom = timerMode === "standard" ? !isStdPreset : !isChessPreset;

  // Derive display values from value prop so they always stay in sync.
  const stdCustomSec = timerMode === "standard" && isCustom ? (parseInt(value, 10) || 90) : 90;
  const [stdCustomAmt, stdCustomUnit] = secToDisplay(stdCustomSec);

  const chessCustomParts = value.startsWith("custom:") ? value.split(":") : [];
  const bankSec = chessCustomParts.length === 3 ? (parseInt(chessCustomParts[1], 10) || 120) : 120;
  const incrSec = chessCustomParts.length === 3 ? (parseInt(chessCustomParts[2], 10) || 15) : 15;
  const [bankAmt, bankUnit] = secToDisplay(bankSec);
  const [incrAmt, incrUnit] = secToDisplay(incrSec);

  if (timerMode === "standard") {
    return (
      <div className="space-y-3">
        <div className="grid grid-cols-3 gap-2">
          {STANDARD_PRESETS.map((p) => (
            <button
              key={p.value}
              type="button"
              disabled={disabled}
              onClick={() => onChange(p.value)}
              className={cn(
                "py-2.5 rounded-lg border-2 text-sm font-semibold transition-all",
                value === p.value ? "border-primary" : "border-border hover:border-primary/60",
                disabled && "opacity-50 cursor-not-allowed"
              )}
            >
              {p.label}
            </button>
          ))}
          <button
            type="button"
            disabled={disabled}
            onClick={() => onChange(isCustom ? value : "90")}
            className={cn(
              "py-2.5 rounded-lg border-2 text-sm font-semibold transition-all",
              isCustom ? "border-primary" : "border-border hover:border-primary/60",
              disabled && "opacity-50 cursor-not-allowed"
            )}
          >
            Custom
          </button>
        </div>
        {isCustom && (
          <div className="flex items-center gap-2 pt-1">
            <Input
              type="number"
              min={1}
              value={stdCustomAmt}
              disabled={disabled}
              onChange={(e) => onChange(String(displayToSec(e.target.value, stdCustomUnit) || 90))}
              className="w-24"
            />
            <UnitSelect
              value={stdCustomUnit}
              onChange={(u) => onChange(String(displayToSec(String(stdCustomAmt), u) || 90))}
              disabled={disabled}
            />
            <span className="text-sm text-muted-foreground">per pick</span>
          </div>
        )}
      </div>
    );
  }

  return (
    <div className="space-y-3">
      <div className="flex flex-col gap-2">
        {CHESS_PRESETS.map((p) => {
          const selected = value === p.value;
          return (
            <button
              key={p.value}
              type="button"
              disabled={disabled}
              onClick={() => onChange(p.value)}
              className={cn(
                "w-full flex items-center justify-between px-4 py-3 rounded-lg border-2 transition-all",
                selected ? "border-primary" : "border-border hover:border-primary/60",
                disabled && "opacity-50 cursor-not-allowed"
              )}
            >
              <div className="flex items-center gap-3">
                <GradientIcon
                  icon={p.icon}
                  className="h-5 w-5 shrink-0"
                  style={selected ? undefined : { stroke: "var(--muted-foreground)" }}
                />
                <div className="text-left">
                  <p className="font-semibold text-sm">{p.label}</p>
                  <p className="text-xs text-muted-foreground">{p.desc}</p>
                </div>
              </div>
              <div className="flex items-center gap-4">
                <div className="text-right">
                  <p className="text-xs uppercase tracking-wider text-muted-foreground">Bank</p>
                  <p className="text-base font-bold">{formatSec(p.bankSec)}</p>
                </div>
                <div className="w-px h-8 bg-border" />
                <div className="text-right">
                  <p className="text-xs uppercase tracking-wider text-muted-foreground">+/Pick</p>
                  <p className="text-base font-bold text-primary">{formatSec(p.incrSec)}</p>
                </div>
              </div>
            </button>
          );
        })}
        <button
          type="button"
          disabled={disabled}
          onClick={() => onChange(isCustom ? value : `custom:${bankSec}:${incrSec}`)}
          className={cn(
            "w-full py-2.5 rounded-lg border-2 text-sm font-semibold transition-all",
            isCustom ? "border-primary" : "border-border hover:border-primary/60",
            disabled && "opacity-50 cursor-not-allowed"
          )}
        >
          Custom
        </button>
      </div>
      {isCustom && (
        <div className="grid grid-cols-2 gap-3 pt-1">
          <div className="space-y-1">
            <Label className="text-xs">Time Bank</Label>
            <div className="flex gap-2">
              <Input
                type="number"
                min={1}
                value={bankAmt}
                disabled={disabled}
                onChange={(e) => onChange(`custom:${displayToSec(e.target.value, bankUnit) || 120}:${incrSec}`)}
                className="w-20"
              />
              <UnitSelect
                value={bankUnit}
                onChange={(u) => onChange(`custom:${displayToSec(String(bankAmt), u) || 120}:${incrSec}`)}
                disabled={disabled}
              />
            </div>
          </div>
          <div className="space-y-1">
            <Label className="text-xs">Per-pick Increment</Label>
            <div className="flex gap-2">
              <Input
                type="number"
                min={1}
                value={incrAmt}
                disabled={disabled}
                onChange={(e) => onChange(`custom:${bankSec}:${displayToSec(e.target.value, incrUnit) || 15}`)}
                className="w-20"
              />
              <UnitSelect
                value={incrUnit}
                onChange={(u) => onChange(`custom:${bankSec}:${displayToSec(String(incrAmt), u) || 15}`)}
                disabled={disabled}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

function UnitSelect({ value, onChange, disabled }: { value: TimeUnit; onChange: (v: TimeUnit) => void; disabled?: boolean }) {
  return (
    <Select value={value} onValueChange={(v) => onChange(v as TimeUnit)} disabled={disabled}>
      <SelectTrigger className="w-24">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectItem value="sec">sec</SelectItem>
        <SelectItem value="min">min</SelectItem>
        <SelectItem value="hr">hr</SelectItem>
      </SelectContent>
    </Select>
  );
}
