// components/tools.jsx — ToolsPanel: tool registry, dispatch, job queue.
// Depends on: React (useState, useCallback, useEffect), Card, StatusBadge, get, post from api.js

const CATEGORY_LABELS = {
  ide: "IDE",
  agent_cli: "CLI Agent",
  browser: "Browser",
  custom: "Custom",
};

const CATEGORY_COLORS = {
  ide: "bg-blue-100 text-blue-700",
  agent_cli: "bg-purple-100 text-purple-700",
  browser: "bg-amber-100 text-amber-700",
  custom: "bg-gray-100 text-gray-600",
};

const JOB_STATUS_COLORS = {
  queued: "bg-gray-100 text-gray-600",
  running: "bg-amber-100 text-amber-700",
  done: "bg-emerald-100 text-emerald-700",
  failed: "bg-red-100 text-red-600",
  cancelled: "bg-gray-200 text-gray-500",
};

// ── Hook: useTools ──────────────────────────────────────────

function useTools() {
  const [tools, setTools] = useState([]);
  const [queue, setQueue] = useState(null);
  const [jobs, setJobs] = useState([]);
  const [loading, setLoading] = useState(true);

  const refreshTools = useCallback(async () => {
    const data = await get("/dashboard/tools/");
    setTools(data?.tools || []);
  }, []);

  const refreshQueue = useCallback(async () => {
    const data = await get("/dashboard/tools/queue");
    setQueue(data);
    setJobs(data?.recent_jobs || []);
  }, []);

  const refresh = useCallback(async () => {
    setLoading(true);
    await Promise.all([refreshTools(), refreshQueue()]);
    setLoading(false);
  }, [refreshTools, refreshQueue]);

  useEffect(() => { refresh(); }, [refresh]);

  return { tools, queue, jobs, loading, refresh };
}

// ── ToolCard ────────────────────────────────────────────────

function ToolCard({ tool }) {
  const catClass = CATEGORY_COLORS[tool.category] || CATEGORY_COLORS.custom;
  return (
    <div className="bg-white border border-gray-200 rounded-lg p-4 hover:shadow-sm transition-shadow">
      <div className="flex items-center justify-between mb-2">
        <div className="flex items-center gap-2">
          <span className="font-semibold text-gray-900">{tool.name}</span>
          <span className={`text-xs px-2 py-0.5 rounded-full ${catClass}`}>
            {CATEGORY_LABELS[tool.category] || tool.category}
          </span>
        </div>
        <StatusBadge ok={tool.available} label={tool.available ? "Available" : "Not found"} />
      </div>
      <p className="text-sm text-gray-500 mb-2">{tool.description}</p>
      <div className="flex flex-wrap gap-1">
        {tool.capabilities?.map(cap => (
          <span key={cap} className="text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded">
            {cap.replace(/_/g, " ")}
          </span>
        ))}
      </div>
      {tool.modes?.length > 0 && (
        <div className="mt-2 flex gap-1">
          <span className="text-xs text-gray-400">Modes:</span>
          {tool.modes.map(m => (
            <span key={m} className="text-xs bg-indigo-50 text-indigo-600 px-1.5 py-0.5 rounded">{m}</span>
          ))}
        </div>
      )}
      {tool.binary && (
        <div className="mt-1 text-xs text-gray-400">binary: <code className="bg-gray-50 px-1 rounded">{tool.binary}</code></div>
      )}
    </div>
  );
}

// ── JobRow ──────────────────────────────────────────────────

function JobRow({ job }) {
  const statusClass = JOB_STATUS_COLORS[job.status] || JOB_STATUS_COLORS.queued;
  return (
    <tr className="border-b border-gray-100 hover:bg-gray-50">
      <td className="py-2 px-3 text-xs font-mono text-gray-500">{job.id}</td>
      <td className="py-2 px-3 text-sm">{job.ticket_id}</td>
      <td className="py-2 px-3 text-sm font-medium">{job.tool}</td>
      <td className="py-2 px-3 text-xs">{job.mode}</td>
      <td className="py-2 px-3">
        <span className={`text-xs px-2 py-0.5 rounded-full ${statusClass}`}>{job.status}</span>
      </td>
      <td className="py-2 px-3 text-xs text-gray-500">
        {job.duration_s > 0 ? `${job.duration_s}s` : "—"}
      </td>
      <td className="py-2 px-3 text-xs text-red-500 truncate max-w-[200px]">{job.error || ""}</td>
    </tr>
  );
}

// ── DispatchForm ────────────────────────────────────────────

function DispatchForm({ tools, onDispatch }) {
  const [ticketId, setTicketId] = useState("");
  const [toolName, setToolName] = useState("");
  const [mode, setMode] = useState("");
  const [projectDir, setProjectDir] = useState("");
  const [dispatching, setDispatching] = useState(false);

  const availableTools = tools.filter(t => t.available);
  const selectedTool = tools.find(t => t.name === toolName);

  const handleDispatch = async () => {
    if (!ticketId || !toolName) return;
    setDispatching(true);
    try {
      await post("/dashboard/tools/dispatch", {
        ticket_id: ticketId,
        tool: toolName,
        mode: mode,
        project_dir: projectDir,
      });
      setTicketId("");
      setMode("");
      if (onDispatch) onDispatch();
    } catch (e) {
      console.error("Dispatch failed:", e);
    }
    setDispatching(false);
  };

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-4">
      <h3 className="text-sm font-semibold text-gray-700 mb-3">Dispatch Tool</h3>
      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        <input value={ticketId} onChange={e => setTicketId(e.target.value)}
          placeholder="Ticket ID (TKT-...)" className="border rounded px-3 py-1.5 text-sm" />
        <select value={toolName} onChange={e => { setToolName(e.target.value); setMode(""); }}
          className="border rounded px-3 py-1.5 text-sm">
          <option value="">Select tool...</option>
          {availableTools.map(t => <option key={t.name} value={t.name}>{t.name}</option>)}
        </select>
        <select value={mode} onChange={e => setMode(e.target.value)}
          className="border rounded px-3 py-1.5 text-sm">
          <option value="">Default mode</option>
          {selectedTool?.modes?.map(m => <option key={m} value={m}>{m}</option>)}
        </select>
        <input value={projectDir} onChange={e => setProjectDir(e.target.value)}
          placeholder="Project dir (optional)" className="border rounded px-3 py-1.5 text-sm" />
      </div>
      <button onClick={handleDispatch} disabled={!ticketId || !toolName || dispatching}
        className="mt-3 px-4 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-50">
        {dispatching ? "Dispatching..." : "Dispatch"}
      </button>
    </div>
  );
}

// ── QueueSummary ────────────────────────────────────────────

function QueueSummary({ queue, onStartStop }) {
  if (!queue) return null;
  return (
    <div className="flex items-center gap-4 text-sm">
      <span className="text-gray-500">Queue: <strong>{queue.queue_size || 0}</strong> pending</span>
      <span className="text-gray-500">Total jobs: <strong>{queue.total_jobs || 0}</strong></span>
      {queue.by_status && Object.entries(queue.by_status).map(([s, c]) => (
        <span key={s} className="text-xs text-gray-400">{s}: {c}</span>
      ))}
      <span className={`text-xs font-medium ${queue.running ? "text-emerald-600" : "text-gray-400"}`}>
        {queue.running ? "● Running" : "○ Stopped"}
      </span>
      <button onClick={() => onStartStop(!queue.running)}
        className={`text-xs px-2 py-1 rounded ${queue.running ? "bg-red-100 text-red-600 hover:bg-red-200" : "bg-emerald-100 text-emerald-600 hover:bg-emerald-200"}`}>
        {queue.running ? "Stop" : "Start"}
      </button>
    </div>
  );
}

// ── ToolsPanel (main) ───────────────────────────────────────

function ToolsPanel() {
  const { tools, queue, jobs, loading, refresh } = useTools();

  const handleStartStop = async (start) => {
    await post(`/dashboard/tools/queue/${start ? "start" : "stop"}`, {});
    refresh();
  };

  if (loading) {
    return <Card title="Tools"><p className="text-gray-400 text-sm">Loading...</p></Card>;
  }

  const available = tools.filter(t => t.available);
  const unavailable = tools.filter(t => !t.available);

  return (
    <div className="space-y-6">
      <Card title={`Tool Registry (${available.length}/${tools.length} available)`}>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {available.map(t => <ToolCard key={t.name} tool={t} />)}
          {unavailable.map(t => <ToolCard key={t.name} tool={t} />)}
        </div>
      </Card>

      <Card title="Dispatch">
        <DispatchForm tools={tools} onDispatch={refresh} />
      </Card>

      <Card title="Job Queue">
        <QueueSummary queue={queue} onStartStop={handleStartStop} />
        {jobs.length > 0 ? (
          <div className="mt-3 overflow-x-auto">
            <table className="w-full text-left">
              <thead>
                <tr className="border-b border-gray-200 text-xs text-gray-500 uppercase">
                  <th className="py-2 px-3">ID</th>
                  <th className="py-2 px-3">Ticket</th>
                  <th className="py-2 px-3">Tool</th>
                  <th className="py-2 px-3">Mode</th>
                  <th className="py-2 px-3">Status</th>
                  <th className="py-2 px-3">Duration</th>
                  <th className="py-2 px-3">Error</th>
                </tr>
              </thead>
              <tbody>
                {jobs.map(j => <JobRow key={j.id} job={j} />)}
              </tbody>
            </table>
          </div>
        ) : (
          <p className="mt-3 text-sm text-gray-400">No jobs yet. Dispatch a tool to a ticket to start.</p>
        )}
      </Card>
    </div>
  );
}
