import { useState, type ReactNode } from "react";
import { GripVertical, Plus, Trash2 } from "lucide-react";

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";

import type {
  DropdownOption,
  DropdownSetting,
} from "@/types/dropdownSettings";

export interface ManageDropdownOptionsDialogProps {
  setting: DropdownSetting;
  children: ReactNode;
}

function makeEmptyOption(settingCode: string, idx: number): DropdownOption {
  return {
    id: `${settingCode}-new-${Date.now()}-${idx}`,
    value: "",
    label: "",
    order: idx + 1,
  };
}

export default function ManageDropdownOptionsDialog({
  setting,
  children,
}: ManageDropdownOptionsDialogProps) {
  const sortedInitial = [...setting.children].sort(
    (a, b) => (a.order ?? 0) - (b.order ?? 0),
  );
  const [options, setOptions] = useState<DropdownOption[]>(sortedInitial);

  const update = (i: number, patch: Partial<DropdownOption>) =>
    setOptions((prev) =>
      prev.map((o, idx) => (idx === i ? { ...o, ...patch } : o)),
    );

  const updateMeta = (
    i: number,
    patch: Partial<NonNullable<DropdownOption["meta"]>>,
  ) =>
    setOptions((prev) =>
      prev.map((o, idx) =>
        idx === i ? { ...o, meta: { ...(o.meta ?? {}), ...patch } } : o,
      ),
    );

  const remove = (i: number) =>
    setOptions((prev) => prev.filter((_, idx) => idx !== i));

  const add = () =>
    setOptions((prev) => [
      ...prev,
      makeEmptyOption(setting.code, prev.length),
    ]);

  const move = (i: number, dir: -1 | 1) =>
    setOptions((prev) => {
      const next = [...prev];
      const target = i + dir;
      if (target < 0 || target >= next.length) return prev;
      const a = next[i] as DropdownOption;
      const b = next[target] as DropdownOption;
      next[i] = { ...b, order: i + 1 };
      next[target] = { ...a, order: target + 1 };
      return next;
    });

  return (
    <Dialog>
      <DialogTrigger asChild>{children}</DialogTrigger>

      <DialogContent className="max-h-[90vh] overflow-y-auto sm:max-w-4xl rounded-3xl">
        <DialogHeader>
          <DialogTitle className="text-2xl font-bold">
            Manage Options · {setting.label}
          </DialogTitle>
          <DialogDescription>
            Add, edit, reorder, or remove options for{" "}
            <span className="font-mono text-slate-700">{setting.code}</span>.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3 py-4">
          <div className="flex items-center justify-between">
            <p className="text-sm text-slate-500">
              {options.length} option{options.length === 1 ? "" : "s"}
            </p>
            <button
              type="button"
              onClick={add}
              className="inline-flex items-center gap-1.5 rounded-xl bg-[#33578D] px-3 py-1.5 text-xs font-medium text-white transition hover:bg-[#33578D]/90"
            >
              <Plus className="h-3.5 w-3.5" />
              Add Option
            </button>
          </div>

          {options.length === 0 ? (
            <div className="rounded-2xl border border-dashed border-slate-200 p-8 text-center text-sm text-slate-500">
              No options yet. Click <span className="font-medium">Add Option</span> to start.
            </div>
          ) : (
            <div className="space-y-2">
              {options.map((opt, i) => (
                <div
                  key={opt.id}
                  className="grid gap-2 rounded-2xl border border-slate-200 bg-white p-3 md:grid-cols-[auto_1fr_1fr_1fr_auto_auto_auto]"
                >
                  <div className="flex items-center gap-1 text-slate-400">
                    <GripVertical className="h-4 w-4" />
                    <div className="flex flex-col">
                      <button
                        type="button"
                        onClick={() => move(i, -1)}
                        aria-label="Move up"
                        disabled={i === 0}
                        className="text-[10px] leading-none text-slate-400 transition hover:text-[#33578D] disabled:opacity-30"
                      >
                        ▲
                      </button>
                      <button
                        type="button"
                        onClick={() => move(i, 1)}
                        aria-label="Move down"
                        disabled={i === options.length - 1}
                        className="text-[10px] leading-none text-slate-400 transition hover:text-[#33578D] disabled:opacity-30"
                      >
                        ▼
                      </button>
                    </div>
                  </div>

                  <div className="space-y-1">
                    <Label className="text-xs">Label *</Label>
                    <Input
                      value={opt.label}
                      onChange={(e) => update(i, { label: e.target.value })}
                      placeholder="Display label"
                    />
                  </div>

                  <div className="space-y-1">
                    <Label className="text-xs">Value</Label>
                    <Input
                      value={opt.value}
                      onChange={(e) => update(i, { value: e.target.value })}
                      placeholder="Stored value"
                      className="font-mono"
                    />
                  </div>

                  <div className="space-y-1">
                    <Label className="text-xs">Note</Label>
                    <Input
                      value={opt.note ?? ""}
                      onChange={(e) => update(i, { note: e.target.value })}
                      placeholder="Helper text"
                    />
                  </div>

                  <div className="space-y-1">
                    <Label className="text-xs">Badge</Label>
                    <Input
                      value={opt.meta?.badge ?? ""}
                      onChange={(e) => updateMeta(i, { badge: e.target.value })}
                      placeholder="—"
                      className="w-20"
                    />
                  </div>

                  <div className="space-y-1">
                    <Label className="text-xs">Color</Label>
                    <Input
                      type="text"
                      value={opt.meta?.color ?? ""}
                      onChange={(e) => updateMeta(i, { color: e.target.value })}
                      placeholder="#…"
                      className="w-24 font-mono"
                    />
                  </div>

                  <div className="flex flex-col items-center justify-between gap-2">
                    <label className="flex items-center gap-1 text-xs text-slate-600">
                      <input
                        type="checkbox"
                        checked={opt.disabled ?? false}
                        onChange={(e) =>
                          update(i, { disabled: e.target.checked })
                        }
                        className="h-3.5 w-3.5 rounded border-slate-300 text-[#33578D] focus:ring-[#33578D]/20"
                      />
                      Off
                    </label>
                    <button
                      type="button"
                      onClick={() => remove(i)}
                      aria-label={`Remove ${opt.label || "option"}`}
                      className="rounded-lg p-1 text-red-500 transition hover:bg-red-50"
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </button>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        <div className="flex justify-end gap-3 border-t border-slate-100 pt-3">
          <Button variant="outline">Cancel</Button>
          <Button className="bg-[#33578D] text-white hover:bg-[#33578D]/90">
            Save Options
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
