"use client";

import { useState } from "react";
import type { StaffingRequirement } from "@nexus/shared";
import { uuid } from "~/lib/uuid.js";

function makeEmptyPreset(): StaffingRequirement {
  return {
    id: uuid(),
    role: "",
    requiredSkills: [],
    preferredSkills: [],
    hoursPerDay: 8,
    headcount: 1,
  };
}

interface PresetRowProps {
  preset: StaffingRequirement;
  onChange: (preset: StaffingRequirement) => void;
  onDelete: () => void;
}

function PresetRow({ preset, onChange, onDelete }: PresetRowProps) {
  function update<K extends keyof StaffingRequirement>(key: K, value: StaffingRequirement[K]) {
    onChange({ ...preset, [key]: value });
  }

  return (
    <div className="border border-gray-200 rounded-lg p-3 bg-white">
      <div className="flex flex-wrap items-center gap-2">
        {/* Role */}
        <input
          type="text"
          value={preset.role}
          onChange={(e) => update("role", e.target.value)}
          placeholder="Role name"
          className="app-input flex-1 min-w-32"
          aria-label="Role name"
        />

        {/* Required Skills */}
        <div className="flex flex-col gap-0.5 flex-1 min-w-40">
          <label className="text-xs text-gray-400">Required skills (comma-sep)</label>
          <input
            type="text"
            value={preset.requiredSkills.join(", ")}
            onChange={(e) =>
              update(
                "requiredSkills",
                e.target.value
                  .split(",")
                  .map((s) => s.trim())
                  .filter(Boolean),
              )
            }
            placeholder="e.g. 3D Modeling, Lighting"
            className="app-input"
            aria-label="Required skills"
          />
        </div>

        {/* Hours per day */}
        <div className="flex flex-col gap-0.5 w-24">
          <label className="text-xs text-gray-400">h/day</label>
          <input
            type="number"
            value={preset.hoursPerDay}
            min={0}
            max={24}
            step={0.5}
            onChange={(e) => update("hoursPerDay", parseFloat(e.target.value) || 0)}
            className="app-input"
            aria-label="Hours per day"
          />
        </div>

        {/* Headcount */}
        <div className="flex flex-col gap-0.5 w-20">
          <label className="text-xs text-gray-400">Count</label>
          <input
            type="number"
            value={preset.headcount}
            min={1}
            max={20}
            onChange={(e) => update("headcount", parseInt(e.target.value, 10) || 1)}
            className="app-input"
            aria-label="Headcount"
          />
        </div>

        {/* Delete */}
        <button
          type="button"
          onClick={onDelete}
          className="app-action-danger-btn self-end mb-0.5"
          aria-label="Remove preset"
        >
          ×
        </button>
      </div>

      {/* Preferred skills (secondary row) */}
      <div className="mt-2">
        <label className="text-xs text-gray-400">Preferred skills (optional)</label>
        <input
          type="text"
          value={(preset.preferredSkills ?? []).join(", ")}
          onChange={(e) =>
            update(
              "preferredSkills",
              e.target.value
                .split(",")
                .map((s) => s.trim())
                .filter(Boolean),
            )
          }
          placeholder="e.g. Compositing, Art Direction"
          className="app-input mt-0.5"
          aria-label="Preferred skills"
        />
      </div>
    </div>
  );
}

interface RolePresetsEditorProps {
  initialPresets: StaffingRequirement[];
  /** Called with the current presets array when the user clicks Save */
  onSave: (presets: StaffingRequirement[]) => void;
  isSaving?: boolean;
  saveError?: string | null;
}

export function RolePresetsEditor({
  initialPresets,
  onSave,
  isSaving = false,
  saveError = null,
}: RolePresetsEditorProps) {
  const [presets, setPresets] = useState<StaffingRequirement[]>(initialPresets);

  function addPreset() {
    setPresets((prev) => [...prev, makeEmptyPreset()]);
  }

  function removePreset(idx: number) {
    setPresets((prev) => prev.filter((_, i) => i !== idx));
  }

  function updatePreset(idx: number, updated: StaffingRequirement) {
    setPresets((prev) => prev.map((p, i) => (i === idx ? updated : p)));
  }

  return (
    <div>
      <div className="space-y-3 max-h-[50vh] overflow-y-auto">
        {presets.length === 0 && (
          <p className="text-sm text-gray-400 text-center py-8">
            No role presets yet. Click &ldquo;+ Add Role&rdquo; to define default staffing.
          </p>
        )}
        {presets.map((preset, idx) => (
          <PresetRow
            key={preset.id}
            preset={preset}
            onChange={(updated) => updatePreset(idx, updated)}
            onDelete={() => removePreset(idx)}
          />
        ))}
      </div>

      <div className="mt-3">
        <button
          type="button"
          onClick={addPreset}
          className="flex items-center gap-1.5 text-sm text-brand-600 hover:text-brand-800 font-medium"
        >
          <span className="text-lg leading-none">+</span> Add Role
        </button>
      </div>

      {saveError && (
        <div className="mt-2 px-3 py-2 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700">
          {saveError}
        </div>
      )}

      <div className="flex justify-end mt-4">
        <button
          type="button"
          onClick={() => onSave(presets)}
          disabled={isSaving}
          className="px-4 py-2 bg-brand-600 text-white rounded-lg hover:bg-brand-700 text-sm font-medium disabled:opacity-50"
        >
          {isSaving ? "Saving…" : "Save Presets"}
        </button>
      </div>
    </div>
  );
}
