// components/vms.jsx — VMCard, VMsPanel with extracted sort/selection hooks.
// Depends on: React (useState, useCallback, useMemo), StateBadge, Card, formatDate,
//             formatDuration, formatSize, post (from api.js)

const VM_ACTIONS = {
  stopped: [
    { action: "start", label: "Start", cls: "bg-emerald-100 text-emerald-700 hover:bg-emerald-200" },
    { action: "delete", label: "Delete", cls: "bg-gray-100 text-gray-700 hover:bg-gray-200" },
  ],
  running: [
    { action: "stop", label: "Stop", cls: "bg-red-100 text-red-700 hover:bg-red-200" },
    { action: "pause", label: "Pause", cls: "bg-amber-100 text-amber-700 hover:bg-amber-200" },
    { action: "delete", label: "Delete", cls: "bg-gray-100 text-gray-700 hover:bg-gray-200" },
  ],
  paused: [
    { action: "resume", label: "Resume", cls: "bg-blue-100 text-blue-700 hover:bg-blue-200" },
    { action: "delete", label: "Delete", cls: "bg-gray-100 text-gray-700 hover:bg-gray-200" },
  ],
};

// ── Sort comparators ────────────────────────────────────────
const _VM_STATE_ORDER = { running: 0, paused: 1, stopped: 2 };

function _compareByState(a, b) {
  return (_VM_STATE_ORDER[a.state] ?? 3) - (_VM_STATE_ORDER[b.state] ?? 3);
}
function _compareByName(a, b) {
  return a.name.localeCompare(b.name);
}
function _compareByCreated(a, b) {
  return (a.created_at || 0) - (b.created_at || 0);
}
function _compareByLastStarted(a, b) {
  return (a.last_started_at || 0) - (b.last_started_at || 0);
}
function _compareBySize(a, b) {
  return ((a.memory_mb || 0) * (a.vcpus || 1)) - ((b.memory_mb || 0) * (b.vcpus || 1));
}

const _VM_COMPARATORS = {
  state: _compareByState,
  name: _compareByName,
  created: _compareByCreated,
  last_started: _compareByLastStarted,
  size: _compareBySize,
};

// ── Hook: useVMSort ─────────────────────────────────────────
function useVMSort(vms) {
  const [sortBy, setSortBy] = useState("state");
  const [sortDesc, setSortDesc] = useState(false);

  const sorted = React.useMemo(() => {
    if (!vms) return [];
    const cmp = _VM_COMPARATORS[sortBy] ?? _compareByState;
    const arr = [...vms].sort((a, b) => {
      const r = cmp(a, b);
      return sortDesc ? -r : r;
    });
    return arr;
  }, [vms, sortBy, sortDesc]);

  return { sorted, sortBy, setSortBy, sortDesc, setSortDesc };
}

// ── Hook: useVMSelection ────────────────────────────────────
function useVMSelection(vms) {
  const [selected, setSelected] = useState(new Set());

  const handleSelect = useCallback((vmId) => {
    setSelected(prev => {
      const next = new Set(prev);
      next.has(vmId) ? next.delete(vmId) : next.add(vmId);
      return next;
    });
  }, []);

  const handleSelectAll = useCallback(() => {
    setSelected(prev =>
      prev.size === vms?.length ? new Set() : new Set(vms?.map(vm => vm.id) || [])
    );
  }, [vms]);

  const handleBulkAction = useCallback(async (action, onRefresh) => {
    const vmIds = Array.from(selected);
    if (action === "delete") {
      if (!confirm(`Delete ${vmIds.length} selected VM${vmIds.length > 1 ? 's' : ''}?`)) return;
      await post("/dashboard/vms/bulk-delete", vmIds);
    } else {
      for (const vmId of vmIds) {
        await post(`/dashboard/vms/${vmId}/${action}`, {});
      }
    }
    setSelected(new Set());
    onRefresh();
  }, [selected]);

  return {
    selected, handleSelect, handleSelectAll, handleBulkAction,
    hasSelected: selected.size > 0,
    allSelected: vms?.length > 0 && selected.size === vms.length,
  };
}

// ── VMCard ──────────────────────────────────────────────────
function VMCard({ vm, selected, onSelect, onAction }) {
  const actions = VM_ACTIONS[vm.state] || [];
  return (
    <div className="flex items-start justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
      <div className="flex items-start gap-3">
        <input
          type="checkbox"
          checked={selected}
          onChange={() => onSelect(vm.id)}
          className="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 mt-1"
        />
        <div>
          <div className="flex items-center gap-2 flex-wrap">
            <span className="font-medium text-sm">{vm.name}</span>
            <StateBadge state={vm.state} />
            {vm.tool && <span className="px-1.5 py-0.5 bg-purple-50 text-purple-700 rounded text-xs">{vm.tool}</span>}
          </div>
          <div className="text-xs text-gray-500 mt-1.5 space-y-0.5">
            <div className="flex items-center gap-3">
              <span className="font-mono">{vm.vcpus || 0} vCPU</span>
              <span>·</span>
              <span className="font-mono">{formatSize(vm.memory_mb)}</span>
              {vm.disk_gb > 0 && (
                <><span>·</span><span className="font-mono">{vm.disk_gb} GB disk</span></>
              )}
            </div>
            <div className="flex items-center gap-3">
              {vm.ip ? (
                <span className="font-mono text-blue-600">{vm.ip}</span>
              ) : (
                <span className="text-gray-400">no IP</span>
              )}
              <span>·</span>
              <span>{vm.code_mount || "no mount"}</span>
            </div>
            <div className="flex items-center gap-3">
              {vm.state === "running" && vm.uptime > 0 && (
                <><span className="text-emerald-600">⏱ up {formatDuration(vm.uptime)}</span><span>·</span></>
              )}
              <span>started: {formatDate(vm.last_started_at)}</span>
              <span>·</span>
              <span>created: {formatDate(vm.created_at)}</span>
            </div>
          </div>
        </div>
      </div>
      <div className="flex gap-1">
        {actions.map(a => (
          <button key={a.action} onClick={() => onAction(vm.id, a.action)} className={`px-2 py-1 rounded text-xs ${a.cls}`}>{a.label}</button>
        ))}
      </div>
    </div>
  );
}

// ── VMsPanel (refactored: CC ≤ 6) ──────────────────────────
function VMsPanel({ vms, onRefresh }) {
  const { sorted, sortBy, setSortBy, sortDesc, setSortDesc } = useVMSort(vms);
  const sel = useVMSelection(vms);

  const _formatApiError = (res) => {
    const detail = res?.body?.detail ?? res?.body;
    if (typeof detail === "string") return detail;
    if (detail === undefined) return "";
    if (detail === null) return "null";
    if (typeof detail === "number" || typeof detail === "boolean") return String(detail);
    if (detail instanceof Error) return detail.message;
    if (typeof detail === "object") return JSON.stringify(detail);
    return String(detail);
  };

  const handleAction = async (vmId, action) => {
    const isDelete = action === "delete";
    if (isDelete && !confirm("Delete VM?")) return;

    const endpoint = isDelete ? `/dashboard/vms/${vmId}/delete` : `/dashboard/vms/${vmId}/${action}`;
    const res = await post(endpoint, {});
    if (res?.ok === false) {
      const msg = _formatApiError(res);
      const label = isDelete ? "delete" : `action '${action}'`;
      alert(`VM ${label} failed (HTTP ${res.status}): ${msg}`);
    }
    onRefresh();
  };

  const runningCount = vms?.filter(v => v.state === "running").length || 0;
  const stoppedCount = vms?.filter(v => v.state === "stopped").length || 0;
  const pausedCount = vms?.filter(v => v.state === "paused").length || 0;

  return (
    <Card title={`Virtual Machines (${vms?.length || 0})`}>
      <div className="space-y-3">
        {/* Stats bar */}
        <div className="flex items-center gap-4 text-xs">
          <span className="flex items-center gap-1">
            <span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
            {runningCount} running
          </span>
          <span className="flex items-center gap-1">
            <span className="w-2 h-2 rounded-full bg-amber-500" />
            {pausedCount} paused
          </span>
          <span className="flex items-center gap-1">
            <span className="w-2 h-2 rounded-full bg-gray-400" />
            {stoppedCount} stopped
          </span>
        </div>

        {/* Controls row */}
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-3">
            <input
              type="checkbox"
              checked={sel.allSelected}
              onChange={sel.handleSelectAll}
              className="w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
            />
            <span className="text-sm text-gray-600">
              {sel.selected.size > 0 ? `${sel.selected.size} selected` : "Select all"}
            </span>
          </div>
          
          <div className="flex items-center gap-2">
            <span className="text-xs text-gray-500">Sort by:</span>
            <select 
              value={sortBy} 
              onChange={(e) => setSortBy(e.target.value)}
              className="text-xs border rounded px-2 py-1 bg-white"
            >
              <option value="state">State</option>
              <option value="name">Name</option>
              <option value="created">Created</option>
              <option value="last_started">Last Started</option>
              <option value="size">Size</option>
            </select>
            <button 
              onClick={() => setSortDesc(!sortDesc)}
              className="text-xs px-2 py-1 border rounded hover:bg-gray-50"
              title={sortDesc ? "Descending" : "Ascending"}
            >
              {sortDesc ? "↓" : "↑"}
            </button>

            {sel.hasSelected && (
              <div className="flex gap-2 ml-4">
                <button onClick={() => sel.handleBulkAction("start", onRefresh)} className="px-3 py-1.5 bg-emerald-100 text-emerald-700 rounded text-sm hover:bg-emerald-200">Start</button>
                <button onClick={() => sel.handleBulkAction("stop", onRefresh)} className="px-3 py-1.5 bg-red-100 text-red-700 rounded text-sm hover:bg-red-200">Stop</button>
                <button onClick={() => sel.handleBulkAction("delete", onRefresh)} className="px-3 py-1.5 bg-gray-100 text-gray-700 rounded text-sm hover:bg-gray-200">Delete</button>
              </div>
            )}
          </div>
        </div>

        {/* VM list */}
        <div className="space-y-2">
          {sorted.map(vm => (
            <VMCard
              key={vm.id}
              vm={vm}
              selected={sel.selected.has(vm.id)}
              onSelect={sel.handleSelect}
              onAction={handleAction}
            />
          ))}
          {(!vms || vms.length === 0) && <p className="text-gray-400 text-sm">No VMs configured. Use CLI or API to create.</p>}
        </div>
      </div>
    </Card>
  );
}
