import { useState, useEffect, useRef, useCallback } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useAuth } from "../auth/AuthContext";
import api from "../api/client";

const BOARD_TYPE_LABELS = {
  vesper: "Vesper", vesper_plus: "Vesper+", vesper_pro: "Vesper Pro",
  chronos: "Chronos", chronos_pro: "Chronos Pro", agnus_mini: "Agnus Mini", agnus: "Agnus",
};

const LIFECYCLE = [
  { key: "manufactured",   label: "Manufactured",   icon: "🔩", color: "#94a3b8",  bg: "#1e2a3a",  accent: "#64748b" },
  { key: "flashed",        label: "Flashed",         icon: "⚡", color: "#60a5fa",  bg: "#1e3a5f",  accent: "#3b82f6" },
  { key: "provisioned",    label: "Provisioned",     icon: "📡", color: "#34d399",  bg: "#064e3b",  accent: "#10b981" },
  { key: "sold",           label: "Sold",            icon: "📦", color: "#c084fc",  bg: "#2e1065",  accent: "#a855f7" },
  { key: "claimed",        label: "Claimed",         icon: "✅", color: "#fb923c",  bg: "#431407",  accent: "#f97316" },
  { key: "decommissioned", label: "Decommissioned",  icon: "🗑", color: "#f87171",  bg: "#450a0a",  accent: "#ef4444" },
];

const STEP_INDEX = Object.fromEntries(LIFECYCLE.map((s, i) => [s.key, i]));
const PROTECTED_STATUSES = ["sold", "claimed"];

function formatHwVersion(v) {
  if (!v) return "—";
  if (/^\d+\.\d+/.test(v)) return `Rev ${v}`;
  const n = parseInt(v, 10);
  if (!isNaN(n)) return `Rev ${n}.0`;
  return `Rev ${v}`;
}

function formatDate(iso) {
  if (!iso) return "—";
  try {
    return new Date(iso).toLocaleString("en-US", {
      year: "numeric", month: "short", day: "numeric",
      hour: "2-digit", minute: "2-digit",
    });
  } catch { return iso; }
}

function toDatetimeLocal(iso) {
  if (!iso) return "";
  try {
    const d = new Date(iso);
    const pad = (n) => String(n).padStart(2, "0");
    return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
  } catch { return ""; }
}

function Field({ label, value, mono = false }) {
  return (
    <div>
      <p className="ui-field-label mb-0.5">{label}</p>
      <p className={`text-sm ${mono ? "font-mono" : ""}`} style={{ color: "var(--text-primary)" }}>
        {value || "—"}
      </p>
    </div>
  );
}

// ─── User Search Modal (for Claimed) ──────────────────────────────────────────

function UserSearchModal({ onSelect, onCancel, existingUsers = [] }) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  const [searching, setSearching] = useState(false);
  const inputRef = useRef(null);

  useEffect(() => { inputRef.current?.focus(); }, []);

  const search = useCallback(async (q) => {
    setSearching(true);
    try {
      const data = await api.get(`/users?search=${encodeURIComponent(q)}&limit=20`);
      setResults(data.users || data || []);
    } catch {
      setResults([]);
    } finally {
      setSearching(false);
    }
  }, []);

  useEffect(() => {
    const t = setTimeout(() => search(query), 300);
    return () => clearTimeout(t);
  }, [query, search]);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center" style={{ backgroundColor: "rgba(0,0,0,0.65)" }}>
      <div className="rounded-xl border p-6 w-full max-w-md shadow-2xl" style={{ backgroundColor: "var(--bg-card)", borderColor: "#f97316aa" }}>
        <div className="flex items-center gap-3 mb-4">
          <div className="w-8 h-8 rounded-lg flex items-center justify-center" style={{ backgroundColor: "#431407", border: "1px solid #f9731640" }}>
            <span>✅</span>
          </div>
          <div>
            <p className="text-xs font-semibold uppercase tracking-wider" style={{ color: "#fb923c" }}>Set as Claimed</p>
            <h2 className="text-sm font-bold" style={{ color: "var(--text-heading)" }}>Assign a User</h2>
          </div>
        </div>
        <p className="text-xs mb-3" style={{ color: "var(--text-muted)" }}>
          A device is "Claimed" when a registered user has been assigned to it. Search and select the user to assign.
        </p>

        {/* Keep existing users option */}
        {existingUsers.length > 0 && (
          <div className="mb-3">
            <p className="text-xs font-medium mb-1.5" style={{ color: "var(--text-muted)" }}>Already assigned</p>
            {existingUsers.map((u) => (
              <button
                key={u.uid}
                type="button"
                onClick={() => onSelect(u, true)}
                className="w-full text-left px-3 py-2.5 text-sm rounded-lg border mb-1.5 flex items-center gap-3 cursor-pointer hover:opacity-80 transition-opacity"
                style={{ backgroundColor: "#431407", borderColor: "#f9731640", color: "var(--text-primary)" }}
              >
                <div className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"
                  style={{ backgroundColor: "#f9731630", color: "#fb923c" }}>
                  {(u.display_name || u.email || "U")[0].toUpperCase()}
                </div>
                <div className="min-w-0 flex-1">
                  <span className="font-medium block truncate">{u.display_name || u.email || u.uid}</span>
                  {u.email && u.display_name && <span className="text-xs block" style={{ color: "var(--text-muted)" }}>{u.email}</span>}
                </div>
                <span className="text-xs flex-shrink-0 px-2 py-0.5 rounded"
                  style={{ backgroundColor: "#f9731620", color: "#fb923c", border: "1px solid #f9731640" }}>
                  Keep
                </span>
              </button>
            ))}
            <div className="flex items-center gap-2 my-3">
              <div className="flex-1 h-px" style={{ backgroundColor: "var(--border-secondary)" }} />
              <span className="text-xs" style={{ color: "var(--text-muted)" }}>or assign a different user</span>
              <div className="flex-1 h-px" style={{ backgroundColor: "var(--border-secondary)" }} />
            </div>
          </div>
        )}

        <div style={{ position: "relative" }} className="mb-3">
          <input
            ref={inputRef}
            type="text"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Search by name or email…"
            className="w-full px-3 py-2 rounded-md text-sm border"
            style={{ backgroundColor: "var(--bg-input)", borderColor: "var(--border-input)", color: "var(--text-primary)" }}
          />
          {searching && <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs" style={{ color: "var(--text-muted)" }}>…</span>}
        </div>
        <div className="rounded-md border overflow-y-auto" style={{ borderColor: "var(--border-secondary)", maxHeight: 220, minHeight: 48 }}>
          {results.length === 0 ? (
            <p className="px-3 py-3 text-sm" style={{ color: "var(--text-muted)" }}>
              {searching ? "Searching…" : query ? "No users found." : "Type to search users…"}
            </p>
          ) : results.map((u) => (
            <button key={u.id || u.uid} type="button" onClick={() => onSelect(u, false)}
              className="w-full text-left px-3 py-2.5 text-sm hover:opacity-80 cursor-pointer border-b last:border-b-0 transition-colors"
              style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-secondary)", color: "var(--text-primary)" }}>
              <span className="font-medium">{u.display_name || u.name || u.email || u.id}</span>
              {u.email && <span className="block text-xs" style={{ color: "var(--text-muted)" }}>{u.email}</span>}
            </button>
          ))}
        </div>
        <div className="flex gap-3 justify-end mt-4">
          <button onClick={onCancel} className="px-4 py-1.5 text-sm rounded-md hover:opacity-80 cursor-pointer"
            style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)" }}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

// ─── Customer Search Modal ─────────────────────────────────────────────────

function CustomerSearchModal({ onSelect, onCancel }) {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  const [searching, setSearching] = useState(false);
  const inputRef = useRef(null);

  useEffect(() => { inputRef.current?.focus(); }, []);

  const search = useCallback(async (q) => {
    setSearching(true);
    try {
      const data = await api.get(`/manufacturing/customers/search?q=${encodeURIComponent(q)}`);
      setResults(data.results || []);
    } catch {
      setResults([]);
    } finally {
      setSearching(false);
    }
  }, []);

  useEffect(() => {
    const t = setTimeout(() => search(query), 250);
    return () => clearTimeout(t);
  }, [query, search]);

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center" style={{ backgroundColor: "rgba(0,0,0,0.6)" }}>
      <div className="rounded-xl border p-6 w-full max-w-md" style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-primary)" }}>
        <h2 className="text-base font-bold mb-4" style={{ color: "var(--text-heading)" }}>Assign to Customer</h2>
        <div style={{ position: "relative" }} className="mb-3">
          <input
            ref={inputRef}
            type="text"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="Search by name, email, phone, org, tags…"
            className="w-full px-3 py-2 rounded-md text-sm border"
            style={{ backgroundColor: "var(--bg-input)", borderColor: "var(--border-input)", color: "var(--text-primary)" }}
          />
          {searching && <span className="absolute right-3 top-1/2 -translate-y-1/2 text-xs" style={{ color: "var(--text-muted)" }}>…</span>}
        </div>
        <div className="rounded-md border overflow-y-auto" style={{ borderColor: "var(--border-secondary)", maxHeight: 260, minHeight: 48 }}>
          {results.length === 0 ? (
            <p className="px-3 py-3 text-sm" style={{ color: "var(--text-muted)" }}>
              {searching ? "Searching…" : query ? "No customers found." : "Type to search customers…"}
            </p>
          ) : results.map((c) => {
            const fullName = [c.name, c.surname].filter(Boolean).join(" ") || c.email || c.id;
            return (
              <button key={c.id} type="button" onClick={() => onSelect(c)}
                className="w-full text-left px-3 py-2.5 text-sm hover:opacity-80 cursor-pointer border-b last:border-b-0 transition-colors"
                style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--border-secondary)", color: "var(--text-primary)" }}>
                <span className="font-semibold block">{fullName}</span>
                {c.organization && <span className="block text-xs" style={{ color: "var(--text-muted)" }}>{c.organization}</span>}
                {c.city && <span className="block text-xs" style={{ color: "var(--text-muted)" }}>{c.city}</span>}
              </button>
            );
          })}
        </div>
        <div className="flex gap-3 justify-end mt-4">
          <button onClick={onCancel} className="px-4 py-1.5 text-sm rounded-md hover:opacity-80 cursor-pointer"
            style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)" }}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

// ─── Delete Device Modal ──────────────────────────────────────────────────────

function DeleteModal({ device, onConfirm, onCancel, deleting }) {
  const isProtected = PROTECTED_STATUSES.includes(device?.mfg_status);
  const [typed, setTyped] = useState("");
  const confirmed = !isProtected || typed === device?.serial_number;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center" style={{ backgroundColor: "rgba(0,0,0,0.6)" }}>
      <div className="rounded-xl border p-6 w-full max-w-md" style={{ backgroundColor: "var(--bg-card)", borderColor: "var(--danger)" }}>
        <h2 className="text-base font-bold mb-2" style={{ color: "var(--danger-text)" }}>
          {isProtected ? "⚠ Delete Protected Device" : "Delete Device"}
        </h2>
        {isProtected ? (
          <>
            <p className="text-sm mb-3" style={{ color: "var(--text-secondary)" }}>
              This device has status <strong>{device.mfg_status}</strong> and is linked to a customer. Deleting it is irreversible.
            </p>
            <p className="text-sm mb-3" style={{ color: "var(--text-secondary)" }}>To confirm, type the serial number exactly:</p>
            <p className="font-mono text-sm mb-3 px-3 py-2 rounded" style={{ backgroundColor: "var(--bg-primary)", color: "var(--text-primary)" }}>{device.serial_number}</p>
            <input type="text" value={typed} onChange={(e) => setTyped(e.target.value)} onPaste={(e) => e.preventDefault()}
              placeholder="Type serial number here…" autoComplete="off"
              className="w-full px-3 py-2 rounded-md text-sm border mb-4 font-mono"
              style={{ backgroundColor: "var(--bg-input)", borderColor: typed === device.serial_number ? "var(--accent)" : "var(--border-input)", color: "var(--text-primary)" }} />
          </>
        ) : (
          <p className="text-sm mb-4" style={{ color: "var(--text-secondary)" }}>
            Are you sure you want to delete <strong className="font-mono">{device?.serial_number}</strong>? This cannot be undone.
          </p>
        )}
        <div className="flex gap-3 justify-end">
          <button onClick={onCancel} className="px-4 py-1.5 text-sm rounded-md hover:opacity-80 cursor-pointer"
            style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)" }}>Cancel</button>
          <button onClick={onConfirm} disabled={!confirmed || deleting}
            className="px-4 py-1.5 text-sm rounded-md font-medium hover:opacity-90 cursor-pointer disabled:opacity-40"
            style={{ backgroundColor: "var(--danger)", color: "#fff" }}>
            {deleting ? "Deleting…" : "Delete Device"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Lifecycle Entry Edit Modal ────────────────────────────────────────────────

function LifecycleEditModal({ entry, stepMeta, isCurrent, onSave, onDelete, onCancel }) {
  const isNew = !entry;
  const [dateVal, setDateVal] = useState(() => isNew ? toDatetimeLocal(new Date().toISOString()) : toDatetimeLocal(entry?.date));
  const [note, setNote] = useState(entry?.note || "");
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [confirmDelete, setConfirmDelete] = useState(false);

  const handleSave = async () => {
    setSaving(true);
    try {
      const isoDate = dateVal ? new Date(dateVal).toISOString() : new Date().toISOString();
      await onSave(isoDate, note);
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    setDeleting(true);
    try {
      await onDelete();
    } finally {
      setDeleting(false);
      setConfirmDelete(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center" style={{ backgroundColor: "rgba(0,0,0,0.75)" }}>
      <div className="rounded-2xl border p-6 w-full max-w-sm shadow-2xl" style={{ backgroundColor: "var(--bg-card)", borderColor: stepMeta.accent + "60" }}>
        {/* Header */}
        <div className="flex items-center gap-3 mb-5">
          <div className="w-9 h-9 rounded-xl flex items-center justify-center text-lg flex-shrink-0"
            style={{ backgroundColor: stepMeta.bg, border: `1px solid ${stepMeta.accent}40` }}>
            {stepMeta.icon}
          </div>
          <div>
            <p className="text-xs font-semibold uppercase tracking-wider mb-0.5" style={{ color: stepMeta.color }}>
              {isNew ? "Create Step" : "Edit Step"}
            </p>
            <h3 className="text-sm font-bold" style={{ color: "var(--text-heading)" }}>{stepMeta.label}</h3>
          </div>
        </div>

        {/* Date field */}
        <div className="mb-4">
          <label className="block text-xs font-medium mb-1.5" style={{ color: "var(--text-muted)" }}>Date &amp; Time</label>
          <input
            type="datetime-local"
            value={dateVal}
            onChange={(e) => setDateVal(e.target.value)}
            className="w-full px-3 py-2 rounded-lg text-sm border"
            style={{ backgroundColor: "var(--bg-input)", borderColor: "var(--border-input)", color: "var(--text-primary)" }}
          />
        </div>

        {/* Note field */}
        <div className="mb-5">
          <label className="block text-xs font-medium mb-1.5" style={{ color: "var(--text-muted)" }}>
            Note <span style={{ fontWeight: 400 }}>(optional)</span>
          </label>
          <textarea
            value={note}
            onChange={(e) => setNote(e.target.value)}
            rows={3}
            placeholder="Add a note about this step…"
            className="w-full px-3 py-2 rounded-lg text-sm border resize-none"
            style={{ backgroundColor: "var(--bg-input)", borderColor: "var(--border-input)", color: "var(--text-primary)" }}
          />
        </div>

        {/* Delete confirm */}
        {confirmDelete && (
          <div className="mb-4 rounded-lg p-3 border text-xs" style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
            Delete this step record permanently?
            <div className="flex gap-2 mt-2">
              <button onClick={() => setConfirmDelete(false)} className="px-3 py-1 rounded cursor-pointer hover:opacity-80"
                style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)" }}>Cancel</button>
              <button onClick={handleDelete} disabled={deleting} className="px-3 py-1 rounded cursor-pointer font-medium hover:opacity-90 disabled:opacity-50"
                style={{ backgroundColor: "var(--danger)", color: "#fff" }}>
                {deleting ? "Deleting…" : "Yes, Delete"}
              </button>
            </div>
          </div>
        )}

        <div className="flex gap-2 justify-between">
          {/* Delete button — only for existing entries that are NOT current */}
          {!isNew && !isCurrent && !confirmDelete ? (
            <button onClick={() => setConfirmDelete(true)}
              className="px-3 py-1.5 text-xs rounded-lg cursor-pointer hover:opacity-80"
              style={{ backgroundColor: "var(--danger-bg)", color: "var(--danger-text)", border: "1px solid var(--danger)" }}>
              Delete Step
            </button>
          ) : <div />}

          <div className="flex gap-2">
            <button onClick={onCancel} className="px-4 py-1.5 text-sm rounded-lg hover:opacity-80 cursor-pointer"
              style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)" }}>Cancel</button>
            <button onClick={handleSave} disabled={saving}
              className="px-4 py-1.5 text-sm rounded-lg font-medium hover:opacity-90 cursor-pointer disabled:opacity-50"
              style={{ backgroundColor: stepMeta.accent, color: "#fff" }}>
              {saving ? "Saving…" : isNew ? "Create" : "Save"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Lifecycle Ladder ────────────────────────────────────────────────────────

function LifecycleLadder({ device, canEdit, onStatusChange, onEditEntry, statusError }) {
  const currentIndex = STEP_INDEX[device?.mfg_status] ?? 0;
  const history = device?.lifecycle_history || [];
  const [hoveredIndex, setHoveredIndex] = useState(null);

  // Map status_id -> last entry in history
  const historyMap = {};
  history.forEach((entry) => {
    historyMap[entry.status_id] = entry;
  });

  return (
    <div>
      {statusError && (
        <div className="text-xs rounded-lg p-2.5 border mb-4"
          style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
          {statusError}
        </div>
      )}

      <div style={{ display: "flex", flexDirection: "column", gap: 0 }}>
        {LIFECYCLE.map((step, i) => {
          const isCurrent = i === currentIndex;
          const isPast = i < currentIndex;
          const isFuture = i > currentIndex;
          const isLast = i === LIFECYCLE.length - 1;
          const entry = historyMap[step.key];
          const hasData = !!entry;
          const isHovered = hoveredIndex === i;

          return (
            <div key={step.key} style={{ display: "flex", alignItems: "stretch", gap: 0 }}>
              {/* Left rail */}
              <div style={{ display: "flex", flexDirection: "column", alignItems: "center", width: 44, flexShrink: 0 }}>
                {/* Step circle — clicking handled on the card now */}
                <div
                  style={{
                    width: 38,
                    height: 38,
                    borderRadius: "50%",
                    border: `2px solid ${isCurrent ? step.accent : isPast ? step.accent + "70" : isHovered && canEdit ? step.accent + "50" : "var(--border-secondary)"}`,
                    backgroundColor: isCurrent ? step.bg : isPast ? step.bg : isHovered && canEdit ? step.bg + "60" : "var(--bg-primary)",
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    fontSize: "1rem",
                    flexShrink: 0,
                    opacity: isFuture && !isHovered ? 0.35 : 1,
                    boxShadow: isCurrent ? `0 0 0 3px ${step.accent}25, 0 0 14px ${step.accent}25` : "none",
                    position: "relative",
                    transition: "all 0.2s",
                    pointerEvents: "none",
                  }}
                >
                  {isPast && (
                    <svg width="14" height="14" viewBox="0 0 14 14" fill="none"
                      style={{ position: "absolute", bottom: -2, right: -2, background: "var(--bg-card)", borderRadius: "50%" }}>
                      <circle cx="7" cy="7" r="6" fill={step.accent} opacity="0.9"/>
                      <path d="M4.5 7L6.2 8.7L9.5 5.3" stroke="white" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  )}
                  <span style={{ fontSize: isCurrent ? "1rem" : "0.85rem" }}>{step.icon}</span>
                </div>

                {/* Connector line */}
                {!isLast && (
                  <div style={{
                    width: 2,
                    flex: 1,
                    minHeight: 12,
                    background: isPast
                      ? `linear-gradient(to bottom, ${step.accent}90, ${LIFECYCLE[i+1].accent}40)`
                      : "var(--border-secondary)",
                    margin: "2px 0",
                    borderRadius: 1,
                    transition: "background 0.3s",
                  }} />
                )}
              </div>

              {/* Right clickable card */}
              <div
                role={canEdit ? "button" : undefined}
                tabIndex={canEdit ? 0 : undefined}
                onMouseEnter={() => setHoveredIndex(i)}
                onMouseLeave={() => setHoveredIndex(null)}
                onClick={(e) => {
                  // Don't trigger if clicking the EDIT button (it has its own handler)
                  if (e.target.closest("[data-edit-btn]")) return;
                  if (!canEdit) return;
                  onStatusChange(step.key);
                }}
                onKeyDown={(e) => {
                  if (e.key === "Enter" || e.key === " ") {
                    if (!canEdit) return;
                    onStatusChange(step.key);
                  }
                }}
                style={{
                  flex: 1,
                  marginLeft: 10,
                  marginBottom: isLast ? 0 : 6,
                  padding: "10px 12px",
                  borderRadius: 10,
                  border: `1px solid ${
                    isCurrent ? step.accent + "60"
                    : isHovered && canEdit ? step.accent + "35"
                    : isPast ? step.accent + "25"
                    : "var(--border-secondary)"
                  }`,
                  backgroundColor: isCurrent
                    ? step.bg
                    : isHovered && canEdit
                    ? step.bg + "55"
                    : isPast
                    ? step.bg + "35"
                    : "transparent",
                  opacity: isFuture && !isHovered ? 0.38 : 1,
                  transition: "all 0.18s",
                  cursor: canEdit ? "pointer" : "default",
                  position: "relative",
                  display: "flex",
                  alignItems: hasData ? "flex-start" : "center",
                  justifyContent: "space-between",
                  gap: 8,
                  minHeight: 44,
                }}
              >
                {/* Content */}
                <div style={{ flex: 1, minWidth: 0 }}>
                  {/* Label row */}
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: hasData ? 3 : 0 }}>
                    <span style={{
                      fontSize: "0.78rem",
                      fontWeight: 700,
                      letterSpacing: "0.05em",
                      textTransform: "uppercase",
                      color: isCurrent ? step.color : isPast ? step.color + "bb" : isHovered ? step.color + "90" : "var(--text-muted)",
                    }}>
                      {step.label}
                    </span>
                    {isCurrent && (
                      <span style={{
                        fontSize: "0.58rem",
                        fontWeight: 700,
                        letterSpacing: "0.1em",
                        textTransform: "uppercase",
                        color: step.color,
                        backgroundColor: step.accent + "22",
                        border: `1px solid ${step.accent}45`,
                        padding: "1px 6px",
                        borderRadius: 4,
                      }}>CURRENT</span>
                    )}
                  </div>

                  {/* Date + set_by */}
                  {hasData && (
                    <p style={{ fontSize: "0.7rem", color: isCurrent ? step.color + "99" : "var(--text-muted)", margin: 0, marginBottom: entry.note ? 2 : 0 }}>
                      {formatDate(entry.date)}
                      {entry.set_by && <span style={{ marginLeft: 6, opacity: 0.65 }}>· {entry.set_by}</span>}
                    </p>
                  )}

                  {/* Note */}
                  {entry?.note && (
                    <p style={{ fontSize: "0.7rem", color: "var(--text-secondary)", margin: 0, marginTop: 1, fontStyle: "italic", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
                      "{entry.note}"
                    </p>
                  )}
                </div>

                {/* EDIT button — only visible on hover */}
                {canEdit && (
                  <button
                    data-edit-btn
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation();
                      onEditEntry(i, entry || null);
                    }}
                    style={{
                      fontSize: "0.58rem",
                      fontWeight: 700,
                      letterSpacing: "0.1em",
                      textTransform: "uppercase",
                      color: isHovered ? step.color : "transparent",
                      backgroundColor: "transparent",
                      border: `1px solid ${isHovered ? step.accent + "55" : "transparent"}`,
                      borderRadius: 5,
                      padding: "2px 8px",
                      cursor: "pointer",
                      flexShrink: 0,
                      alignSelf: "flex-start",
                      transition: "all 0.15s",
                      pointerEvents: isHovered ? "auto" : "none",
                    }}
                    onMouseEnter={(e) => {
                      e.currentTarget.style.backgroundColor = step.bg;
                      e.currentTarget.style.borderColor = step.accent + "80";
                    }}
                    onMouseLeave={(e) => {
                      e.currentTarget.style.backgroundColor = "transparent";
                    }}
                  >
                    EDIT
                  </button>
                )}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ─── Main Component ───────────────────────────────────────────────────────────

export default function DeviceInventoryDetail() {
  const { sn } = useParams();
  const navigate = useNavigate();
  const { hasPermission } = useAuth();
  const canEdit   = hasPermission("manufacturing", "edit");
  const canDelete = hasPermission("manufacturing", "delete");

  const [device, setDevice] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState("");

  const [statusSaving, setStatusSaving] = useState(false);
  const [statusError, setStatusError] = useState("");

  const [nvsDownloading, setNvsDownloading] = useState(false);

  const [assignedCustomer, setAssignedCustomer] = useState(null);
  const [assignSaving, setAssignSaving] = useState(false);
  const [assignError, setAssignError] = useState("");
  const [showCustomerModal, setShowCustomerModal] = useState(false);

  // Claimed user assignment
  const [showUserModal, setShowUserModal] = useState(false);
  const [userSaving, setUserSaving] = useState(false);

  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [deleting, setDeleting] = useState(false);

  // Resolved user info for the assigned users section
  const [resolvedUsers, setResolvedUsers] = useState([]); // [{uid, display_name, email}]

  // Lifecycle edit modal: { stepIndex, entry|null }
  const [editModalData, setEditModalData] = useState(null);

  const loadDevice = async () => {
    setLoading(true);
    setError("");
    try {
      const data = await api.get(`/manufacturing/devices/${sn}`);
      setDevice(data);
      if (data.customer_id) fetchCustomerDetails(data.customer_id);
      if (data.user_list?.length) fetchResolvedUsers(data.user_list);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const fetchCustomerDetails = async (customerId) => {
    try {
      const data = await api.get(`/manufacturing/customers/${customerId}`);
      setAssignedCustomer(data || null);
    } catch {
      setAssignedCustomer(null);
    }
  };

  const fetchResolvedUsers = async (uidList) => {
    const results = await Promise.all(
      uidList.map(async (uid) => {
        try {
          const u = await api.get(`/users/${uid}`);
          return { uid, display_name: u.display_name || "", email: u.email || "" };
        } catch {
          return { uid, display_name: "", email: "" };
        }
      })
    );
    setResolvedUsers(results);
  };

  useEffect(() => { loadDevice(); }, [sn]);

  // ── Status change ──────────────────────────────────────────────────────────
  const handleStatusChange = async (newStatus) => {
    if (newStatus === device?.mfg_status) return; // already current

    if (newStatus === "claimed") {
      // Open user-assign flow: user must pick a user first
      setShowUserModal(true);
      return;
    }
    if (newStatus === "sold" && !device?.customer_id) {
      setShowCustomerModal(true);
      return;
    }
    setStatusError("");
    setStatusSaving(true);
    try {
      const updated = await api.request(`/manufacturing/devices/${sn}/status`, {
        method: "PATCH",
        body: JSON.stringify({ status: newStatus }),
      });
      setDevice(updated);
    } catch (err) {
      setStatusError(err.message);
    } finally {
      setStatusSaving(false);
    }
  };

  // ── Claimed: assign user then set status ───────────────────────────────────
  const handleClaimedUserSelect = async (user, keepExisting = false) => {
    setShowUserModal(false);
    setUserSaving(true);
    setStatusError("");
    try {
      // 1. Add user to device's user_list (skip if keeping the existing user)
      if (!keepExisting) {
        await api.request(`/devices/${device.id}/users`, {
          method: "POST",
          body: JSON.stringify({ user_id: user.id || user.uid }),
        });
      }
      // 2. Set status to claimed (backend guard now passes since user_list is non-empty)
      const updated = await api.request(`/manufacturing/devices/${sn}/status`, {
        method: "PATCH",
        body: JSON.stringify({ status: "claimed", force_claimed: true }),
      });
      setDevice(updated);
      if (updated.user_list?.length) fetchResolvedUsers(updated.user_list);
    } catch (err) {
      setStatusError(err.message);
    } finally {
      setUserSaving(false);
    }
  };

  // ── Customer assign ────────────────────────────────────────────────────────
  const handleSelectCustomer = async (customer) => {
    setShowCustomerModal(false);
    setAssignError("");
    setAssignSaving(true);
    try {
      const updated = await api.request(`/manufacturing/devices/${sn}/assign`, {
        method: "POST",
        body: JSON.stringify({ customer_id: customer.id }),
      });
      setDevice(updated);
      setAssignedCustomer(customer);
    } catch (err) {
      setAssignError(err.message);
    } finally {
      setAssignSaving(false);
    }
  };

  // ── NVS download ───────────────────────────────────────────────────────────
  const downloadNvs = async () => {
    setNvsDownloading(true);
    try {
      const token = localStorage.getItem("access_token");
      const response = await fetch(`/api/manufacturing/devices/${sn}/nvs.bin`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      if (!response.ok) {
        const err = await response.json().catch(() => ({}));
        throw new Error(err.detail || "Download failed");
      }
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${sn}_nvs.bin`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (err) {
      setError(err.message);
    } finally {
      setNvsDownloading(false);
    }
  };

  // ── Device delete ──────────────────────────────────────────────────────────
  const handleDelete = async () => {
    setDeleting(true);
    try {
      const isProtected = PROTECTED_STATUSES.includes(device?.mfg_status);
      const url = `/manufacturing/devices/${sn}${isProtected ? "?force=true" : ""}`;
      await api.request(url, { method: "DELETE" });
      navigate("/manufacturing");
    } catch (err) {
      setError(err.message);
      setShowDeleteModal(false);
    } finally {
      setDeleting(false);
    }
  };

  // ── Lifecycle edit helpers ─────────────────────────────────────────────────
  // Build step_key -> last array index in lifecycle_history
  const history = device?.lifecycle_history || [];
  const historyIndexMap = {};
  history.forEach((entry, idx) => { historyIndexMap[entry.status_id] = idx; });

  const handleEditEntryByStep = (stepIndex, entry) => {
    setEditModalData({ stepIndex, entry });
  };

  const handleSaveLifecycle = async (stepIndex, date, note) => {
    const stepKey = LIFECYCLE[stepIndex]?.key;
    const arrayIndex = historyIndexMap[stepKey];

    if (arrayIndex === undefined) {
      // No existing entry → create on the fly
      const updated = await api.request(`/manufacturing/devices/${sn}/lifecycle`, {
        method: "POST",
        body: JSON.stringify({ status_id: stepKey, date, note }),
      });
      setDevice(updated);
    } else {
      // Edit existing
      const updated = await api.request(`/manufacturing/devices/${sn}/lifecycle`, {
        method: "PATCH",
        body: JSON.stringify({ index: arrayIndex, date, note }),
      });
      setDevice(updated);
    }
    setEditModalData(null);
  };

  const handleDeleteLifecycleStep = async (stepIndex) => {
    const stepKey = LIFECYCLE[stepIndex]?.key;
    const arrayIndex = historyIndexMap[stepKey];
    if (arrayIndex === undefined) { setEditModalData(null); return; }
    const updated = await api.request(`/manufacturing/devices/${sn}/lifecycle/${arrayIndex}`, {
      method: "DELETE",
    });
    setDevice(updated);
    setEditModalData(null);
  };

  // ── Early returns ──────────────────────────────────────────────────────────
  if (loading) {
    return (
      <div className="flex items-center justify-center py-20">
        <p className="text-sm" style={{ color: "var(--text-muted)" }}>Loading…</p>
      </div>
    );
  }

  if (error && !device) {
    return (
      <div className="text-sm rounded-md p-4 border"
        style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
        {error}
      </div>
    );
  }

  const currentStepKey = device?.mfg_status;
  const editStepMeta = editModalData ? LIFECYCLE[editModalData.stepIndex] : null;
  const editIsCurrent = editModalData ? LIFECYCLE[editModalData.stepIndex]?.key === currentStepKey : false;
  const userList = device?.user_list || [];

  return (
    <div style={{ width: "100%" }}>
      {/* Title row */}
      <div className="flex items-start justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold font-mono" style={{ color: "var(--text-heading)" }}>
            {device?.serial_number}
          </h1>
          {device?.device_name && (
            <p className="text-sm mt-0.5" style={{ color: "var(--text-muted)" }}>{device.device_name}</p>
          )}
        </div>
        {canDelete && (
          <button
            onClick={() => setShowDeleteModal(true)}
            className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md font-medium hover:opacity-80 cursor-pointer transition-opacity"
            style={{ backgroundColor: "var(--danger-bg)", color: "var(--danger-text)", border: "1px solid var(--danger)" }}
          >
            <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
            </svg>
            Delete Device
          </button>
        )}
      </div>

      {error && (
        <div className="text-sm rounded-md p-3 mb-4 border"
          style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
          {error}
        </div>
      )}

      {/* 2-column 50/50 grid */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 20, alignItems: "start", width: "100%" }}>

        {/* ── LEFT COLUMN ──────────────────────────────────────────────────── */}
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>

          {/* Device Identity */}
          <div className="ui-section-card">
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Device Identity</h2>
            </div>
            <div className="grid grid-cols-2 gap-4">
              <Field label="Serial Number" value={device?.serial_number} mono />
              <Field label="Batch ID" value={device?.mfg_batch_id} mono />
              <Field label="Hardware Family" value={BOARD_TYPE_LABELS[device?.hw_type] || device?.hw_type} />
              <Field label="HW Version" value={formatHwVersion(device?.hw_version)} />
              <Field label="Created At" value={formatDate(device?.created_at)} />
              {device?.device_name && <Field label="Device Name" value={device.device_name} />}
            </div>
          </div>

          {/* Assign to Customer */}
          {canEdit && (
            <div className="ui-section-card">
              <div className="ui-section-card__title-row">
                <h2 className="ui-section-card__title">Assign to Customer</h2>
              </div>

              {assignError && (
                <div className="text-xs rounded p-2 border mb-3"
                  style={{ backgroundColor: "var(--danger-bg)", borderColor: "var(--danger)", color: "var(--danger-text)" }}>
                  {assignError}
                </div>
              )}

              {device?.customer_id ? (
                <div className="flex items-center gap-3">
                  <div className="flex-1 flex items-center gap-3 px-3 py-2 rounded-md border"
                    style={{ backgroundColor: "var(--bg-primary)", borderColor: "var(--border-secondary)" }}>
                    <div className="w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"
                      style={{ backgroundColor: "var(--badge-blue-bg)", color: "var(--badge-blue-text)" }}>
                      {(assignedCustomer?.name || "?")[0].toUpperCase()}
                    </div>
                    <div className="min-w-0">
                      <p className="text-sm font-semibold" style={{ color: "var(--text-primary)" }}>
                        {[assignedCustomer?.name, assignedCustomer?.surname].filter(Boolean).join(" ") || "Customer"}
                      </p>
                      {assignedCustomer?.organization && <p className="text-xs" style={{ color: "var(--text-muted)" }}>{assignedCustomer.organization}</p>}
                      {assignedCustomer?.city && <p className="text-xs" style={{ color: "var(--text-muted)" }}>{assignedCustomer.city}</p>}
                    </div>
                  </div>
                  <button type="button" onClick={() => setShowCustomerModal(true)} disabled={assignSaving}
                    className="px-3 py-1.5 text-xs rounded-md cursor-pointer hover:opacity-80 disabled:opacity-50"
                    style={{ backgroundColor: "var(--bg-card-hover)", color: "var(--text-secondary)", border: "1px solid var(--border-primary)" }}>
                    Reassign
                  </button>
                </div>
              ) : (
                <div>
                  <p className="text-sm mb-3" style={{ color: "var(--text-muted)" }}>
                    No customer assigned. Assigning a customer will set the device status to <em>Sold</em>.
                  </p>
                  <button type="button" onClick={() => setShowCustomerModal(true)} disabled={assignSaving}
                    className="flex items-center gap-2 px-4 py-2 text-sm rounded-md hover:opacity-90 transition-opacity cursor-pointer disabled:opacity-50"
                    style={{ backgroundColor: "var(--btn-primary)", color: "var(--text-white)" }}>
                    {assignSaving ? "Assigning…" : "+ Assign to Customer"}
                  </button>
                </div>
              )}
            </div>
          )}

          {/* Assigned Users */}
          <div className="ui-section-card">
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">Assigned Users</h2>
            </div>
            {userList.length === 0 ? (
              <p className="text-sm" style={{ color: "var(--text-muted)" }}>
                No users assigned to this device.
              </p>
            ) : (
              <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                {userList.map((uid) => {
                  const resolved = resolvedUsers.find((u) => u.uid === uid);
                  const displayName = resolved?.display_name || "";
                  const email = resolved?.email || "";
                  const initials = (displayName || email || uid)[0]?.toUpperCase() || "U";
                  return (
                    <div key={uid}
                      className="flex items-center gap-3 px-3 py-2 rounded-md border"
                      style={{ backgroundColor: "var(--bg-primary)", borderColor: "var(--border-secondary)" }}>
                      <div className="w-7 h-7 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0"
                        style={{ backgroundColor: "#431407", color: "#fb923c" }}>
                        {initials}
                      </div>
                      <div className="min-w-0">
                        {displayName
                          ? <p className="text-sm font-medium" style={{ color: "var(--text-primary)" }}>{displayName}</p>
                          : <p className="text-sm font-mono" style={{ color: "var(--text-muted)" }}>{uid}</p>
                        }
                        {email && <p className="text-xs" style={{ color: "var(--text-muted)" }}>{email}</p>}
                      </div>
                    </div>
                  );
                })}
              </div>
            )}
          </div>

        </div>

        {/* ── RIGHT COLUMN: Lifecycle ───────────────────────────────────────── */}
        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
        <div className="ui-section-card">
          <div className="ui-section-card__title-row">
            <h2 className="ui-section-card__title">Product Lifecycle</h2>
            {(statusSaving || userSaving) && (
              <span className="text-xs" style={{ color: "var(--text-muted)" }}>Saving…</span>
            )}
          </div>
          <LifecycleLadder
            device={device}
            canEdit={canEdit}
            onStatusChange={handleStatusChange}
            onEditEntry={handleEditEntryByStep}
            statusError={statusError}
          />
        </div>

          {/* NVS Binary */}
          <div className="ui-section-card">
            <div className="ui-section-card__title-row">
              <h2 className="ui-section-card__title">NVS Binary</h2>
            </div>
            <button
              onClick={downloadNvs}
              disabled={nvsDownloading}
              className="px-4 py-2 text-sm rounded-md hover:opacity-90 transition-opacity cursor-pointer disabled:opacity-50 flex items-center gap-2"
              style={{ backgroundColor: "var(--badge-blue-bg)", color: "var(--badge-blue-text)" }}
            >
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
              </svg>
              {nvsDownloading ? "Generating…" : "Download NVS Binary"}
            </button>
            <p className="text-xs mt-2" style={{ color: "var(--text-muted)" }}>
              Encodes serial_number, hw_family, hw_version. Flash at 0x9000.
            </p>
          </div>
        </div>

      </div>

      {/* ── Modals ──────────────────────────────────────────────────────────── */}
      {showCustomerModal && (
        <CustomerSearchModal onSelect={handleSelectCustomer} onCancel={() => setShowCustomerModal(false)} />
      )}
      {showUserModal && (
        <UserSearchModal
          onSelect={handleClaimedUserSelect}
          onCancel={() => setShowUserModal(false)}
          existingUsers={resolvedUsers}
        />
      )}
      {showDeleteModal && (
        <DeleteModal device={device} onConfirm={handleDelete} onCancel={() => setShowDeleteModal(false)} deleting={deleting} />
      )}
      {editModalData && editStepMeta && (
        <LifecycleEditModal
          entry={editModalData.entry}
          stepMeta={editStepMeta}
          isCurrent={editIsCurrent}
          onSave={(date, note) => handleSaveLifecycle(editModalData.stepIndex, date, note)}
          onDelete={() => handleDeleteLifecycleStep(editModalData.stepIndex)}
          onCancel={() => setEditModalData(null)}
        />
      )}
    </div>
  );
}
