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

// ── Table Export Component ─────────────────────────────────────

function TableExport({ data, filename, title }) {
  const [showMenu, setShowMenu] = useState(false);

  const convertToCSV = (data) => {
    if (!data || data.length === 0) return '';
    
    const headers = Object.keys(data[0]);
    const csvHeaders = headers.join(',');
    
    const csvRows = data.map(row => {
      return headers.map(header => {
        const value = row[header];
        // Handle nested objects and arrays
        if (typeof value === 'object' && value !== null) {
          return `"${JSON.stringify(value).replace(/"/g, '""')}"`;
        }
        // Escape commas and quotes in strings
        if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
          return `"${value.replace(/"/g, '""')}"`;
        }
        return value;
      }).join(',');
    });
    
    return [csvHeaders, ...csvRows].join('\n');
  };

  const downloadCSV = () => {
    const csv = convertToCSV(data);
    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', `${filename}.csv`);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const downloadJSON = () => {
    const json = JSON.stringify(data, null, 2);
    const blob = new Blob([json], { type: 'application/json;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', `${filename}.json`);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const copyToClipboard = (format) => {
    let content;
    if (format === 'csv') {
      content = convertToCSV(data);
    } else {
      content = JSON.stringify(data, null, 2);
    }
    
    navigator.clipboard.writeText(content).then(() => {
      // Show brief success feedback
      const button = event.target;
      const originalText = button.textContent;
      button.textContent = 'Copied!';
      button.className = button.className.replace('bg-gray-100', 'bg-green-100').replace('text-gray-600', 'text-green-600');
      setTimeout(() => {
        button.textContent = originalText;
        button.className = button.className.replace('bg-green-100', 'bg-gray-100').replace('text-green-600', 'text-gray-600');
      }, 2000);
    });
  };

  if (!data || data.length === 0) {
    return null;
  }

  return (
    <div className="relative">
      <button
        onClick={() => setShowMenu(!showMenu)}
        className="text-xs px-2 py-1 rounded bg-gray-100 text-gray-600 hover:bg-gray-200 flex items-center gap-1"
        title="Export table data"
      >
        📊 Export ▼
      </button>
      
      {showMenu && (
        <div className="absolute right-0 mt-1 w-48 bg-white rounded-md shadow-lg border border-gray-200 z-10">
          <div className="py-1">
            <button
              onClick={() => { downloadCSV(); setShowMenu(false); }}
              className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
            >
              📄 Download CSV
            </button>
            <button
              onClick={() => { downloadJSON(); setShowMenu(false); }}
              className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
            >
              📋 Download JSON
            </button>
            <button
              onClick={() => { copyToClipboard('csv'); setShowMenu(false); }}
              className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
            >
              📋 Copy CSV
            </button>
            <button
              onClick={() => { copyToClipboard('json'); setShowMenu(false); }}
              className="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
            >
              📋 Copy JSON
            </button>
          </div>
        </div>
      )}
      
      {/* Close menu when clicking outside */}
      {showMenu && (
        <div
          className="fixed inset-0 z-0"
          onClick={() => setShowMenu(false)}
        />
      )}
    </div>
  );
}

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, isSelected, onSelect }) {
  const catClass = CATEGORY_COLORS[tool.category] || CATEGORY_COLORS.custom;
  
  const handleCardClick = () => {
    onSelect(tool.name);
  };

  return (
    <button
      type="button"
      onClick={handleCardClick}
      className={`bg-white border rounded-lg p-4 hover:shadow-sm transition-shadow text-left w-full ${
        isSelected ? 'border-blue-400 bg-blue-50' : 'border-gray-200'
      }`}
      aria-pressed={isSelected}
      aria-label={`Tool ${tool.name}${isSelected ? ' (selected)' : ''}: ${tool.description}`}
    >
      <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.replaceAll("_", " ")}
          </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>
      )}
    </button>
  );
}

// ── 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>
  );
}

// ── TicketDispatchTable ───────────────────────────────────────

function TicketDispatchTable({ tools, onDispatch }) {
  const [tickets, setTickets] = useState([]);
  const [loading, setLoading] = useState(true);
  const [dispatching, setDispatching] = useState(null);

  const availableTools = tools.filter(t => t.available);

  // Load tickets
  useEffect(() => {
    const loadTickets = async () => {
      try {
        const data = await get("/dashboard/tickets");
        setTickets(data?.tickets || []);
      } catch (e) {
        console.error("Failed to load tickets:", e);
      } finally {
        setLoading(false);
      }
    };
    loadTickets();
  }, []);

  const handleToolSelect = async (ticketId, toolName, mode = "") => {
    setDispatching(ticketId);
    try {
      await post("/dashboard/tools/dispatch", {
        ticket_id: ticketId,
        tool: toolName,
        mode: mode,
        project_dir: "",
      });
      if (onDispatch) onDispatch();
    } catch (e) {
      console.error("Dispatch failed:", e);
    } finally {
      setDispatching(null);
    }
  };

  const getStatusBadgeClass = (status) => {
    if (status === 'done') return 'bg-emerald-100 text-emerald-700';
    if (status === 'in_progress') return 'bg-blue-100 text-blue-700';
    if (status === 'todo') return 'bg-gray-100 text-gray-700';
    return 'bg-yellow-100 text-yellow-700';
  };

  const getPriorityBadgeClass = (priority) => {
    if (priority === 'high') return 'bg-red-100 text-red-700';
    if (priority === 'medium') return 'bg-amber-100 text-amber-700';
    return 'bg-green-100 text-green-700';
  };

  const getToolCategoryClass = (category) => {
    if (category === 'agent_cli') return 'bg-purple-100 text-purple-700';
    if (category === 'ide') return 'bg-blue-100 text-blue-700';
    return 'bg-amber-100 text-amber-700';
  };

  const renderCurrentTool = (currentTool, toolInfo) => {
    if (!currentTool) {
      return <span className="text-xs text-gray-400">None</span>;
    }

    return (
      <div className="flex items-center gap-1">
        <span className="text-xs font-medium">{currentTool.tool}</span>
        {currentTool.agent_mode && (
          <span className="text-xs text-gray-400">({currentTool.agent_mode})</span>
        )}
        {toolInfo && (
          <span className={`text-xs px-1.5 py-0.5 rounded ${getToolCategoryClass(toolInfo.category)}`}>
            {toolInfo.category?.replace('_', ' ')}
          </span>
        )}
      </div>
    );
  };

  const renderStatusBadge = (ticket) => {
    const statusClass = getStatusBadgeClass(ticket.status);
    const displayStatus = ticket.status?.replace('_', ' ') || 'todo';
    
    return (
      <span className={`text-xs px-2 py-0.5 rounded-full ${statusClass}`}>
        {displayStatus}
      </span>
    );
  };

  const renderPriorityBadge = (ticket) => {
    const priorityClass = getPriorityBadgeClass(ticket.priority);
    const displayPriority = ticket.priority || 'medium';
    
    return (
      <span className={`text-xs px-2 py-0.5 rounded ${priorityClass}`}>
        {displayPriority}
      </span>
    );
  };

  if (loading) {
    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 to Ticket</h3>
        <p className="text-sm text-gray-400">Loading tickets...</p>
      </div>
    );
  }

  if (tickets.length === 0) {
    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 to Ticket</h3>
        <p className="text-sm text-gray-400">No tickets found. Create a ticket first to dispatch tools.</p>
      </div>
    );
  }

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-4">
      <div className="flex justify-between items-center mb-3">
        <h3 className="text-sm font-semibold text-gray-700">Dispatch Tool to Ticket</h3>
        {tickets.length > 0 && (
          <TableExport 
            data={tickets.map(ticket => ({
              id: ticket.id,
              title: ticket.title,
              status: ticket.status?.replace('_', ' ') || 'todo',
              priority: ticket.priority || 'medium',
              current_tool: ticket.assigned_tool?.tool || 'None',
              tool_mode: ticket.assigned_tool?.agent_mode || '',
              description: ticket.description || ''
            }))}
            filename="tickets"
            title="Tickets"
          />
        )}
      </div>
      <div className="overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-gray-200 text-xs text-gray-500 uppercase">
              <th className="text-left py-2 px-3">Ticket</th>
              <th className="text-left py-2 px-3">Title</th>
              <th className="text-left py-2 px-3">Status</th>
              <th className="text-left py-2 px-3">Priority</th>
              <th className="text-left py-2 px-3">Current Tool</th>
              <th className="text-left py-2 px-3">Assign Tool</th>
            </tr>
          </thead>
          <tbody>
            {tickets.map(ticket => {
              const currentTool = ticket.assigned_tool;
              const toolInfo = currentTool ? tools.find(t => t.name === currentTool.tool) : null;
              
              return (
                <tr key={ticket.id} className="border-b border-gray-100 hover:bg-gray-50">
                  <td className="py-2 px-3 font-mono text-xs text-gray-600">{ticket.id}</td>
                  <td className="py-2 px-3">
                    <div className="max-w-[200px] truncate" title={ticket.title}>
                      {ticket.title}
                    </div>
                  </td>
                  <td className="py-2 px-3">
                    {renderStatusBadge(ticket)}
                  </td>
                  <td className="py-2 px-3">
                    {renderPriorityBadge(ticket)}
                  </td>
                  <td className="py-2 px-3">
                    {renderCurrentTool(currentTool, toolInfo)}
                  </td>
                  <td className="py-2 px-3">
                    <div className="flex items-center gap-1">
                      <select
                        value=""
                        onChange={(e) => {
                          if (e.target.value) {
                            const [toolName, mode] = e.target.value.split(':');
                            handleToolSelect(ticket.id, toolName, mode);
                            e.target.value = '';
                          }
                        }}
                        disabled={dispatching === ticket.id}
                        className="text-xs border rounded px-2 py-1 disabled:opacity-50"
                      >
                        <option value="">Assign tool...</option>
                        {availableTools.map(tool => (
                          <optgroup key={tool.name} label={tool.name}>
                            <option value={`${tool.name}`}>
                              {tool.name} (default mode)
                            </option>
                            {tool.modes?.map(mode => (
                              <option key={mode} value={`${tool.name}:${mode}`}>
                                {tool.name} ({mode})
                              </option>
                            ))}
                          </optgroup>
                        ))}
                      </select>
                      {dispatching === ticket.id && (
                        <span className="text-xs text-blue-600">Dispatching...</span>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      <p className="text-xs text-gray-400 mt-3">
        Select a tool from the dropdown to dispatch it to the ticket. Tools with multiple modes will show mode options.
      </p>
    </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({ selectedTool, setSelectedTool }) {
  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} 
              isSelected={selectedTool === t.name}
              onSelect={setSelectedTool}
            />
          ))}
          {unavailable.map(t => (
            <ToolCard 
              key={t.name} 
              tool={t} 
              isSelected={selectedTool === t.name}
              onSelect={setSelectedTool}
            />
          ))}
        </div>
      </Card>

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

      <Card title="Job Queue">
        <QueueSummary queue={queue} onStartStop={handleStartStop} />
        {jobs.length > 0 ? (
          <div className="mt-3">
            <div className="flex justify-between items-center mb-2">
              <span className="text-xs text-gray-500">Recent jobs ({jobs.length})</span>
              <TableExport 
                data={jobs.map(job => ({
                  id: job.id,
                  ticket: job.ticket_id,
                  tool: job.tool,
                  mode: job.mode || '',
                  status: job.status,
                  duration: job.duration_s > 0 ? `${job.duration_s}s` : '—',
                  error: job.error || ''
                }))}
                filename="job_queue"
                title="Job Queue"
              />
            </div>
            <div className="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>
          </div>
        ) : (
          <p className="mt-3 text-sm text-gray-400">No jobs yet. Dispatch a tool to a ticket to start.</p>
        )}
      </Card>
    </div>
  );
}
