// components/projects.jsx — ProjectsPanel: manage local, git, SSH, FTP projects + quick task creation.
// Depends on: React (useState, useCallback, useEffect), Card, get, post from api.js

const SOURCE_ICONS = { local: "\u{1F4C1}", git: "\u{1F517}", ssh: "\u{1F5A5}\uFE0F", ftp: "\u{1F4E1}", url: "\u{1F310}" };
const SOURCE_TYPES = ["local", "git", "ssh", "ftp"];
const PROJECT_TOOLS = ["aider", "claude-code", "roo-code", "vscode", "windsurf", "cursor"];

// ── Hook: useProjects ────────────────────────────────────────
function useProjects() {
  const [projects, setProjects] = useState([]);
  const [loading, setLoading] = useState(true);

  const refresh = useCallback(async () => {
    setLoading(true);
    try {
      const data = await get("/dashboard/projects");
      setProjects(Array.isArray(data) ? data : []);
    } catch (e) {
      console.error("Failed to load projects:", e);
      setProjects([]);
    }
    setLoading(false);
  }, []);

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

  return { projects, loading, refresh };
}

// ── ProjectCard ──────────────────────────────────────────────
function ProjectCard({ project, onRefresh }) {
  const [showQuickTask, setShowQuickTask] = useState(false);
  const [task, setTask] = useState("");
  const [tool, setTool] = useState(project.default_tool || "aider");
  const [priority, setPriority] = useState("medium");
  const [creating, setCreating] = useState(false);
  const [tickets, setTickets] = useState(null);
  const [showTickets, setShowTickets] = useState(false);

  const handleQuickTask = async () => {
    if (!task.trim()) return;
    setCreating(true);
    try {
      await post(`/dashboard/projects/${project.id}/tickets`, {
        task: task.trim(),
        tool: tool,
        priority: priority,
      });
      setTask("");
      setShowQuickTask(false);
      onRefresh();
    } catch (e) {
      console.error("Failed to create task:", e);
    }
    setCreating(false);
  };

  const loadTickets = async () => {
    if (showTickets) { setShowTickets(false); return; }
    try {
      const data = await get(`/dashboard/projects/${project.id}/tickets`);
      setTickets(Array.isArray(data) ? data : []);
      setShowTickets(true);
    } catch (e) {
      console.error("Failed to load tickets:", e);
    }
  };

  const icon = SOURCE_ICONS[project.source_type] || "\u{1F4C1}";

  return (
    <div className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow">
      {/* Header */}
      <div className="flex items-start justify-between">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <span className="text-lg">{icon}</span>
            <h4 className="font-semibold text-gray-900 truncate">{project.name}</h4>
            <span className="text-xs px-2 py-0.5 rounded-full bg-gray-100 text-gray-500">{project.source_type}</span>
            {project.has_git && <span className="text-xs px-1.5 py-0.5 bg-emerald-50 text-emerald-600 rounded">git</span>}
          </div>
          {/* Stack tags */}
          <div className="flex flex-wrap gap-1 mb-1">
            {(project.stack || []).map(s => (
              <span key={s} className="text-xs px-1.5 py-0.5 bg-blue-50 text-blue-600 rounded">{s}</span>
            ))}
            {(project.frameworks || []).map(f => (
              <span key={f} className="text-xs px-1.5 py-0.5 bg-purple-50 text-purple-600 rounded">{f}</span>
            ))}
          </div>
        </div>
        <div className="flex items-center gap-1">
          {project.status === "error" && <span className="text-xs px-2 py-0.5 bg-red-100 text-red-600 rounded">error</span>}
          {project.status === "archived" && <span className="text-xs px-2 py-0.5 bg-gray-100 text-gray-500 rounded">archived</span>}
        </div>
      </div>

      {/* Path */}
      <div className="text-xs text-gray-400 mt-1 truncate font-mono">
        {project.source_path}
        {project.local_path && project.local_path !== project.source_path && (
          <span> &rarr; {project.local_path}</span>
        )}
      </div>

      {/* Stats row */}
      <div className="flex items-center gap-3 mt-2 text-xs text-gray-500">
        <span>{project.ticket_count || 0} tickets</span>
        {project.default_tool && <span>tool: <span className="font-medium text-indigo-600">{project.default_tool}</span></span>}
        {project.description && <span className="truncate">{project.description}</span>}
      </div>

      {/* Actions */}
      <div className="flex items-center gap-2 mt-3">
        <button onClick={() => setShowQuickTask(!showQuickTask)}
          className="text-xs px-2.5 py-1 bg-blue-600 text-white rounded hover:bg-blue-700">
          + Quick task
        </button>
        <button onClick={loadTickets}
          className="text-xs px-2.5 py-1 bg-gray-100 text-gray-600 rounded hover:bg-gray-200">
          {showTickets ? "Hide tickets" : "Tickets"}
        </button>
      </div>

      {/* Quick task form (inline) */}
      {showQuickTask && (
        <div className="mt-3 p-3 bg-blue-50 rounded-lg border border-blue-100">
          <div className="flex gap-2">
            <input
              value={task} onChange={e => setTask(e.target.value)}
              placeholder="What to do?"
              className="flex-1 px-3 py-1.5 border rounded text-sm bg-white"
              onKeyDown={e => e.key === "Enter" && handleQuickTask()}
              autoFocus
            />
            <select value={tool} onChange={e => setTool(e.target.value)}
              className="px-2 py-1.5 border rounded text-xs bg-white">
              {PROJECT_TOOLS.map(t => <option key={t} value={t}>{t}</option>)}
            </select>
            <select value={priority} onChange={e => setPriority(e.target.value)}
              className="px-2 py-1.5 border rounded text-xs bg-white">
              <option value="low">low</option>
              <option value="medium">medium</option>
              <option value="high">high</option>
              <option value="critical">critical</option>
            </select>
            <button onClick={handleQuickTask} disabled={creating || !task.trim()}
              className="px-3 py-1.5 bg-blue-600 text-white text-xs rounded hover:bg-blue-700 disabled:opacity-50">
              {creating ? "..." : "Create"}
            </button>
          </div>
        </div>
      )}

      {/* Tickets list */}
      {showTickets && tickets && (
        <div className="mt-3 space-y-1">
          {tickets.length === 0 ? (
            <p className="text-xs text-gray-400 italic">No tickets for this project.</p>
          ) : tickets.map(t => (
            <div key={t.id} className="flex items-center gap-2 text-xs p-2 bg-gray-50 rounded">
              <span className="font-mono text-gray-400">{t.id}</span>
              <span className={`px-1.5 py-0.5 rounded ${
                t.status === "done" ? "bg-emerald-100 text-emerald-700" :
                t.status === "in_progress" ? "bg-amber-100 text-amber-700" :
                "bg-gray-100 text-gray-600"
              }`}>{t.status}</span>
              <span className="truncate text-gray-700">{t.title || t.task}</span>
              {t.assigned_tool && <span className="text-indigo-500">{t.assigned_tool.tool}</span>}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── AddProjectForm ───────────────────────────────────────────
function AddProjectForm({ onAdded, onCancel }) {
  const [mode, setMode] = useState("local");
  const [path, setPath] = useState("");
  const [gitUrl, setGitUrl] = useState("");
  const [sshHost, setSshHost] = useState("");
  const [sshPath, setSshPath] = useState("");
  const [sshUser, setSshUser] = useState("root");
  const [ftpUrl, setFtpUrl] = useState("");
  const [tool, setTool] = useState("");
  const [name, setName] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");

  const handleAdd = async () => {
    setError("");
    const payload = {};
    if (name) payload.name = name;
    if (tool) payload.default_tool = tool;

    if (mode === "local") {
      if (!path.trim()) { setError("Path is required"); return; }
      payload.path = path;
    } else if (mode === "git") {
      if (!gitUrl.trim()) { setError("Git URL is required"); return; }
      payload.git_url = gitUrl;
    } else if (mode === "ssh") {
      if (!sshHost.trim() || !sshPath.trim()) { setError("Host and path are required"); return; }
      payload.ssh_host = sshHost;
      payload.ssh_path = sshPath;
      payload.ssh_user = sshUser;
    } else if (mode === "ftp") {
      if (!ftpUrl.trim()) { setError("FTP URL is required"); return; }
      payload.ftp_url = ftpUrl;
    }

    setSubmitting(true);
    try {
      await post("/dashboard/projects", payload);
      onAdded();
    } catch (e) {
      setError(e.message || "Failed to add project");
    }
    setSubmitting(false);
  };

  return (
    <div className="bg-white rounded-lg border border-blue-200 p-4 space-y-3">
      <h4 className="font-medium text-blue-900">Add Project</h4>

      {/* Mode tabs */}
      <div className="flex gap-1">
        {SOURCE_TYPES.map(m => (
          <button key={m} onClick={() => setMode(m)}
            className={`px-3 py-1.5 text-xs rounded font-medium ${
              m === mode ? "bg-blue-600 text-white" : "bg-gray-100 text-gray-600 hover:bg-gray-200"
            }`}>
            {SOURCE_ICONS[m]} {m.toUpperCase()}
          </button>
        ))}
      </div>

      {/* Conditional fields */}
      {mode === "local" && (
        <input value={path} onChange={e => setPath(e.target.value)}
          placeholder="~/github/my-project" className="w-full px-3 py-2 border rounded text-sm" />
      )}
      {mode === "git" && (
        <input value={gitUrl} onChange={e => setGitUrl(e.target.value)}
          placeholder="https://github.com/user/repo.git" className="w-full px-3 py-2 border rounded text-sm" />
      )}
      {mode === "ssh" && (
        <div className="grid grid-cols-3 gap-2">
          <input value={sshHost} onChange={e => setSshHost(e.target.value)}
            placeholder="host (192.168.1.50)" className="px-3 py-2 border rounded text-sm" />
          <input value={sshPath} onChange={e => setSshPath(e.target.value)}
            placeholder="/opt/project" className="px-3 py-2 border rounded text-sm" />
          <input value={sshUser} onChange={e => setSshUser(e.target.value)}
            placeholder="user (root)" className="px-3 py-2 border rounded text-sm" />
        </div>
      )}
      {mode === "ftp" && (
        <input value={ftpUrl} onChange={e => setFtpUrl(e.target.value)}
          placeholder="ftp://host/path" className="w-full px-3 py-2 border rounded text-sm" />
      )}

      {/* Common fields */}
      <div className="grid grid-cols-2 gap-2">
        <input value={name} onChange={e => setName(e.target.value)}
          placeholder="Project name (auto-detect)" className="px-3 py-2 border rounded text-sm" />
        <select value={tool} onChange={e => setTool(e.target.value)}
          className="px-3 py-2 border rounded text-sm">
          <option value="">Default tool</option>
          {PROJECT_TOOLS.map(t => <option key={t} value={t}>{t}</option>)}
        </select>
      </div>

      {error && <p className="text-xs text-red-600">{error}</p>}

      <div className="flex gap-2">
        <button onClick={handleAdd} disabled={submitting}
          className="px-4 py-2 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-50">
          {submitting ? "Adding..." : "Add Project"}
        </button>
        <button onClick={onCancel}
          className="px-4 py-2 bg-gray-100 text-gray-700 text-sm rounded hover:bg-gray-200">
          Cancel
        </button>
      </div>
    </div>
  );
}

// ── ProjectsPanel (main) ─────────────────────────────────────
function ProjectsPanel() {
  const { projects, loading, refresh } = useProjects();
  const [showAdd, setShowAdd] = useState(false);
  const [filter, setFilter] = useState("all");
  const [scanning, setScanning] = useState(false);

  const filtered = filter === "all"
    ? projects
    : projects.filter(p => p.source_type === filter);

  const stats = React.useMemo(() => ({
    total: projects.length,
    local: projects.filter(p => p.source_type === "local").length,
    git: projects.filter(p => p.source_type === "git").length,
    ssh: projects.filter(p => p.source_type === "ssh").length,
    totalTickets: projects.reduce((sum, p) => sum + (p.ticket_count || 0), 0),
  }), [projects]);

  const handleScan = async () => {
    const dir = prompt("Directory to scan for projects:", "~/github");
    if (!dir) return;
    setScanning(true);
    try {
      const result = await post("/dashboard/projects/scan", { directory: dir });
      if (result.added > 0) {
        refresh();
      } else {
        alert("No new projects found in " + dir);
      }
    } catch (e) {
      alert("Scan failed: " + (e.message || e));
    }
    setScanning(false);
  };

  if (loading) {
    return <Card title="Projects"><p className="text-gray-500">Loading projects...</p></Card>;
  }

  return (
    <div className="space-y-4">
      {/* Stats */}
      <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-gray-900">{stats.total}</div>
          <div className="text-xs text-gray-500">Total</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-blue-600">{stats.local}</div>
          <div className="text-xs text-gray-500">Local</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-purple-600">{stats.git}</div>
          <div className="text-xs text-gray-500">Git</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-amber-600">{stats.ssh}</div>
          <div className="text-xs text-gray-500">SSH</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-emerald-600">{stats.totalTickets}</div>
          <div className="text-xs text-gray-500">Tickets</div>
        </div>
      </div>

      {/* Toolbar */}
      <div className="flex items-center justify-between flex-wrap gap-2">
        <div className="flex items-center gap-2">
          <select value={filter} onChange={e => setFilter(e.target.value)}
            className="text-sm px-2 py-1 border rounded">
            <option value="all">All types</option>
            {SOURCE_TYPES.map(t => <option key={t} value={t}>{SOURCE_ICONS[t]} {t}</option>)}
          </select>
        </div>
        <div className="flex gap-2">
          <button onClick={() => setShowAdd(!showAdd)}
            className="px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
            + Add Project
          </button>
          <button onClick={handleScan} disabled={scanning}
            className="px-3 py-1.5 bg-gray-100 text-gray-700 text-sm rounded hover:bg-gray-200 disabled:opacity-50">
            {scanning ? "Scanning..." : "Scan Folder"}
          </button>
          <button onClick={refresh}
            className="px-3 py-1.5 bg-gray-100 text-gray-700 text-sm rounded hover:bg-gray-200">
            ↻ Refresh
          </button>
        </div>
      </div>

      {/* Add form */}
      {showAdd && (
        <AddProjectForm
          onAdded={() => { setShowAdd(false); refresh(); }}
          onCancel={() => setShowAdd(false)}
        />
      )}

      {/* Project cards */}
      <div className="space-y-3">
        {filtered.length === 0 ? (
          <Card title="No projects">
            <p className="text-gray-500 text-sm">
              {projects.length === 0
                ? "No projects registered. Add a project or scan a folder to get started."
                : "No projects match the current filter."}
            </p>
          </Card>
        ) : (
          filtered.map(p => <ProjectCard key={p.id} project={p} onRefresh={refresh} />)
        )}
      </div>
    </div>
  );
}
