// components/tickets.jsx — TicketsPanel with sprint management + multi-tool assignment.
// Depends on: React (useState, useCallback, useEffect), Card, StatusBadge, get, post from api.js

const TICKET_STATUSES = ["backlog", "todo", "in_progress", "in_review", "done", "cancelled"];
const TICKET_PRIORITIES = ["critical", "high", "medium", "low"];
const TICKET_TYPES = ["task", "bug", "feature", "refactor", "test", "docs"];
const TOOLS = ["vscode", "aider", "claude-code", "windsurf", "cursor", "roo-code", "continue", "copilot"];

const STATUS_COLORS = {
  backlog: "bg-gray-100 text-gray-600",
  todo: "bg-blue-100 text-blue-700",
  in_progress: "bg-amber-100 text-amber-700",
  in_review: "bg-purple-100 text-purple-700",
  done: "bg-emerald-100 text-emerald-700",
  cancelled: "bg-red-100 text-red-600",
};

const PRIORITY_COLORS = {
  critical: "bg-red-200 text-red-800",
  high: "bg-orange-100 text-orange-700",
  medium: "bg-yellow-100 text-yellow-700",
  low: "bg-gray-100 text-gray-600",
};

const TYPE_ICONS = {
  task: "📋", bug: "🐛", feature: "✨", refactor: "🔧", test: "🧪", docs: "📄",
};

// ── Hook: useTickets ─────────────────────────────────────────
function useTickets() {
  const [tickets, setTickets] = useState([]);
  const [sprints, setSprints] = useState([]);
  const [loading, setLoading] = useState(true);

  const refreshTickets = useCallback(async () => {
    const data = await get("/dashboard/tickets");
    setTickets(data?.tickets || []);
  }, []);

  const refreshSprints = useCallback(async () => {
    const data = await get("/dashboard/sprints");
    setSprints(data?.sprints || []);
  }, []);

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

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

  return { tickets, sprints, loading, refresh, refreshTickets, refreshSprints };
}

// ── TicketCard ───────────────────────────────────────────────
function TicketCard({ ticket, onUpdate, sprints }) {
  const [expanded, setExpanded] = useState(false);
  const [assigning, setAssigning] = useState(false);

  const handleStatusChange = async (newStatus) => {
    await post(`/dashboard/tickets/${ticket.id}`, { status: newStatus }, "PUT");
    onUpdate();
  };

  const handleAssign = async (tool) => {
    await post(`/dashboard/tickets/${ticket.id}/assign`, { tool });
    setAssigning(false);
    onUpdate();
  };

  return (
    <div className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow">
      <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-sm">{TYPE_ICONS[ticket.type] || "📋"}</span>
            <span className="text-xs font-mono text-gray-400">{ticket.id}</span>
            <span className={`text-xs px-2 py-0.5 rounded-full ${PRIORITY_COLORS[ticket.priority]}`}>
              {ticket.priority}
            </span>
          </div>
          <h4 className="font-medium text-gray-900 truncate">{ticket.title}</h4>
          {ticket.description && expanded && (
            <p className="text-sm text-gray-500 mt-1">{ticket.description}</p>
          )}
        </div>
        <button onClick={() => setExpanded(!expanded)} className="text-gray-400 hover:text-gray-600 ml-2">
          {expanded ? "▲" : "▼"}
        </button>
      </div>

      <div className="flex items-center gap-2 mt-3 flex-wrap">
        <select
          value={ticket.status}
          onChange={(e) => handleStatusChange(e.target.value)}
          className={`text-xs px-2 py-1 rounded border-0 cursor-pointer ${STATUS_COLORS[ticket.status]}`}
        >
          {TICKET_STATUSES.map(s => <option key={s} value={s}>{s.replace("_", " ")}</option>)}
        </select>

        {ticket.assigned_tool ? (
          <span className="text-xs px-2 py-1 bg-indigo-100 text-indigo-700 rounded-full">
            🔧 {ticket.assigned_tool.tool}
            {ticket.assigned_tool.agent_mode && ` (${ticket.assigned_tool.agent_mode})`}
          </span>
        ) : (
          <button
            onClick={() => setAssigning(!assigning)}
            className="text-xs px-2 py-1 bg-gray-100 text-gray-600 rounded hover:bg-gray-200"
          >
            + Assign tool
          </button>
        )}

        {ticket.tags.map(tag => (
          <span key={tag} className="text-xs px-2 py-0.5 bg-sky-50 text-sky-600 rounded">{tag}</span>
        ))}

        {ticket.estimated_hours > 0 && (
          <span className="text-xs text-gray-400">⏱ {ticket.estimated_hours}h</span>
        )}
      </div>

      {assigning && (
        <div className="mt-3 flex flex-wrap gap-1">
          {TOOLS.map(tool => (
            <button
              key={tool}
              onClick={() => handleAssign(tool)}
              className="text-xs px-2 py-1 bg-indigo-50 text-indigo-700 rounded hover:bg-indigo-100"
            >
              {tool}
            </button>
          ))}
        </div>
      )}

      {expanded && ticket.files && ticket.files.length > 0 && (
        <div className="mt-2">
          <span className="text-xs font-medium text-gray-500">Files:</span>
          <div className="flex flex-wrap gap-1 mt-1">
            {ticket.files.map(f => (
              <span key={f} className="text-xs font-mono bg-gray-50 text-gray-500 px-1 rounded">{f}</span>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ── CreateTicketForm ─────────────────────────────────────────
function CreateTicketForm({ sprints, onCreated, onCancel }) {
  const [form, setForm] = useState({
    title: "", description: "", priority: "medium", type: "task",
    sprint_id: "", tags: "", files: "", estimated_hours: 0,
  });

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!form.title.trim()) return;
    await post("/dashboard/tickets", {
      ...form,
      tags: form.tags ? form.tags.split(",").map(t => t.trim()) : [],
      files: form.files ? form.files.split(",").map(f => f.trim()) : [],
    });
    onCreated();
  };

  const field = (name, value) => setForm(prev => ({ ...prev, [name]: value }));

  return (
    <form onSubmit={handleSubmit} className="bg-white rounded-lg border border-blue-200 p-4 space-y-3">
      <h4 className="font-medium text-blue-900">New Ticket</h4>
      <input
        className="w-full px-3 py-2 border rounded text-sm" placeholder="Title *"
        value={form.title} onChange={e => field("title", e.target.value)} required
      />
      <textarea
        className="w-full px-3 py-2 border rounded text-sm" placeholder="Description" rows={2}
        value={form.description} onChange={e => field("description", e.target.value)}
      />
      <div className="grid grid-cols-2 md:grid-cols-4 gap-2">
        <select className="px-2 py-1 border rounded text-sm" value={form.priority}
          onChange={e => field("priority", e.target.value)}>
          {TICKET_PRIORITIES.map(p => <option key={p} value={p}>{p}</option>)}
        </select>
        <select className="px-2 py-1 border rounded text-sm" value={form.type}
          onChange={e => field("type", e.target.value)}>
          {TICKET_TYPES.map(t => <option key={t} value={t}>{t}</option>)}
        </select>
        <select className="px-2 py-1 border rounded text-sm" value={form.sprint_id}
          onChange={e => field("sprint_id", e.target.value)}>
          <option value="">No sprint</option>
          {sprints.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
        </select>
        <input className="px-2 py-1 border rounded text-sm" type="number" step="0.5" min="0"
          placeholder="Hours" value={form.estimated_hours || ""}
          onChange={e => field("estimated_hours", parseFloat(e.target.value) || 0)} />
      </div>
      <input className="w-full px-3 py-2 border rounded text-sm" placeholder="Tags (comma-separated)"
        value={form.tags} onChange={e => field("tags", e.target.value)} />
      <input className="w-full px-3 py-2 border rounded text-sm" placeholder="Files (comma-separated paths)"
        value={form.files} onChange={e => field("files", e.target.value)} />
      <div className="flex gap-2">
        <button type="submit" className="px-4 py-2 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
          Create Ticket
        </button>
        <button type="button" onClick={onCancel} className="px-4 py-2 bg-gray-100 text-gray-700 text-sm rounded hover:bg-gray-200">
          Cancel
        </button>
      </div>
    </form>
  );
}

// ── CreateSprintForm ─────────────────────────────────────────
function CreateSprintForm({ onCreated, onCancel }) {
  const [form, setForm] = useState({ name: "", goal: "", start_date: "", end_date: "" });

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!form.name.trim()) return;
    await post("/dashboard/sprints", form);
    onCreated();
  };

  const field = (name, value) => setForm(prev => ({ ...prev, [name]: value }));

  return (
    <form onSubmit={handleSubmit} className="bg-white rounded-lg border border-green-200 p-4 space-y-3">
      <h4 className="font-medium text-green-900">New Sprint</h4>
      <input className="w-full px-3 py-2 border rounded text-sm" placeholder="Sprint name *"
        value={form.name} onChange={e => field("name", e.target.value)} required />
      <input className="w-full px-3 py-2 border rounded text-sm" placeholder="Sprint goal"
        value={form.goal} onChange={e => field("goal", e.target.value)} />
      <div className="grid grid-cols-2 gap-2">
        <input className="px-2 py-1 border rounded text-sm" type="date"
          value={form.start_date} onChange={e => field("start_date", e.target.value)} />
        <input className="px-2 py-1 border rounded text-sm" type="date"
          value={form.end_date} onChange={e => field("end_date", e.target.value)} />
      </div>
      <div className="flex gap-2">
        <button type="submit" className="px-4 py-2 bg-green-600 text-white text-sm rounded hover:bg-green-700">
          Create Sprint
        </button>
        <button type="button" onClick={onCancel} className="px-4 py-2 bg-gray-100 text-gray-700 text-sm rounded hover:bg-gray-200">
          Cancel
        </button>
      </div>
    </form>
  );
}

// ── SprintCard ───────────────────────────────────────────────
function SprintCard({ sprint, onSelect, selected }) {
  const progressColor = sprint.progress_pct >= 100 ? "bg-emerald-500"
    : sprint.progress_pct >= 50 ? "bg-blue-500" : "bg-amber-500";

  return (
    <div
      onClick={() => onSelect(sprint.id === selected ? null : sprint.id)}
      className={`p-3 rounded-lg border cursor-pointer transition-all ${
        sprint.id === selected ? "border-blue-400 bg-blue-50" : "border-gray-200 bg-white hover:border-gray-300"
      }`}
    >
      <div className="flex items-center justify-between">
        <h4 className="font-medium text-sm">{sprint.name}</h4>
        <span className={`text-xs px-2 py-0.5 rounded ${STATUS_COLORS[sprint.status] || "bg-gray-100 text-gray-600"}`}>
          {sprint.status}
        </span>
      </div>
      {sprint.goal && <p className="text-xs text-gray-500 mt-1">{sprint.goal}</p>}
      <div className="mt-2">
        <div className="flex justify-between text-xs text-gray-500 mb-1">
          <span>{sprint.tickets_done}/{sprint.tickets_total} done</span>
          <span>{sprint.progress_pct}%</span>
        </div>
        <div className="w-full bg-gray-200 rounded-full h-1.5">
          <div className={`${progressColor} h-1.5 rounded-full transition-all`}
            style={{ width: `${Math.min(sprint.progress_pct, 100)}%` }} />
        </div>
      </div>
      {sprint.start_date && (
        <div className="text-xs text-gray-400 mt-1">
          {sprint.start_date} → {sprint.end_date || "..."}
        </div>
      )}
    </div>
  );
}

// ── TicketsPanel (main) ──────────────────────────────────────
function TicketsPanel() {
  const { tickets, sprints, loading, refresh } = useTickets();
  const [showCreateTicket, setShowCreateTicket] = useState(false);
  const [showCreateSprint, setShowCreateSprint] = useState(false);
  const [selectedSprint, setSelectedSprint] = useState(null);
  const [filterStatus, setFilterStatus] = useState("");
  const [filterTool, setFilterTool] = useState("");
  const [view, setView] = useState("list"); // list | board

  const filtered = React.useMemo(() => {
    let result = tickets;
    if (selectedSprint) result = result.filter(t => t.sprint_id === selectedSprint);
    if (filterStatus) result = result.filter(t => t.status === filterStatus);
    if (filterTool) result = result.filter(t => t.assigned_tool?.tool === filterTool);
    return result;
  }, [tickets, selectedSprint, filterStatus, filterTool]);

  const boardColumns = React.useMemo(() => {
    const cols = {};
    TICKET_STATUSES.forEach(s => { cols[s] = []; });
    filtered.forEach(t => { if (cols[t.status]) cols[t.status].push(t); });
    return cols;
  }, [filtered]);

  const stats = React.useMemo(() => ({
    total: tickets.length,
    todo: tickets.filter(t => t.status === "todo").length,
    in_progress: tickets.filter(t => t.status === "in_progress").length,
    done: tickets.filter(t => t.status === "done").length,
    by_tool: TOOLS.reduce((acc, tool) => {
      const count = tickets.filter(t => t.assigned_tool?.tool === tool).length;
      if (count > 0) acc[tool] = count;
      return acc;
    }, {}),
  }), [tickets]);

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

  return (
    <div className="space-y-4">
      {/* Stats bar */}
      <div className="grid grid-cols-2 md:grid-cols-4 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 Tickets</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-blue-600">{stats.todo}</div>
          <div className="text-xs text-gray-500">To Do</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-amber-600">{stats.in_progress}</div>
          <div className="text-xs text-gray-500">In Progress</div>
        </div>
        <div className="bg-white rounded-lg border p-3 text-center">
          <div className="text-2xl font-bold text-emerald-600">{stats.done}</div>
          <div className="text-xs text-gray-500">Done</div>
        </div>
      </div>

      {/* Tool distribution */}
      {Object.keys(stats.by_tool).length > 0 && (
        <div className="bg-white rounded-lg border p-3">
          <h4 className="text-xs font-medium text-gray-500 mb-2">Assigned by Tool</h4>
          <div className="flex flex-wrap gap-2">
            {Object.entries(stats.by_tool).map(([tool, count]) => (
              <span key={tool} className="text-xs px-2 py-1 bg-indigo-50 text-indigo-700 rounded-full">
                {tool}: {count}
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Sprints */}
      <Card title={`Sprints (${sprints.length})`}>
        <div className="grid grid-cols-1 md:grid-cols-3 gap-3 mb-3">
          {sprints.map(s => (
            <SprintCard key={s.id} sprint={s} selected={selectedSprint} onSelect={setSelectedSprint} />
          ))}
        </div>
        <button onClick={() => setShowCreateSprint(!showCreateSprint)}
          className="text-sm text-green-600 hover:text-green-700">
          + New Sprint
        </button>
        {showCreateSprint && (
          <div className="mt-3">
            <CreateSprintForm
              onCreated={() => { setShowCreateSprint(false); refresh(); }}
              onCancel={() => setShowCreateSprint(false)}
            />
          </div>
        )}
      </Card>

      {/* Toolbar */}
      <div className="flex items-center justify-between flex-wrap gap-2">
        <div className="flex items-center gap-2">
          <select className="text-sm px-2 py-1 border rounded" value={filterStatus}
            onChange={e => setFilterStatus(e.target.value)}>
            <option value="">All statuses</option>
            {TICKET_STATUSES.map(s => <option key={s} value={s}>{s.replace("_", " ")}</option>)}
          </select>
          <select className="text-sm px-2 py-1 border rounded" value={filterTool}
            onChange={e => setFilterTool(e.target.value)}>
            <option value="">All tools</option>
            {TOOLS.map(t => <option key={t} value={t}>{t}</option>)}
          </select>
          <div className="flex border rounded overflow-hidden">
            <button onClick={() => setView("list")}
              className={`px-2 py-1 text-xs ${view === "list" ? "bg-blue-600 text-white" : "bg-white text-gray-600"}`}>
              List
            </button>
            <button onClick={() => setView("board")}
              className={`px-2 py-1 text-xs ${view === "board" ? "bg-blue-600 text-white" : "bg-white text-gray-600"}`}>
              Board
            </button>
          </div>
        </div>
        <div className="flex gap-2">
          <button onClick={() => setShowCreateTicket(!showCreateTicket)}
            className="px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
            + New Ticket
          </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>

      {/* Create form */}
      {showCreateTicket && (
        <CreateTicketForm
          sprints={sprints}
          onCreated={() => { setShowCreateTicket(false); refresh(); }}
          onCancel={() => setShowCreateTicket(false)}
        />
      )}

      {/* Board view */}
      {view === "board" && (
        <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-2">
          {TICKET_STATUSES.map(status => (
            <div key={status} className="bg-gray-50 rounded-lg p-2 min-h-[200px]">
              <h5 className={`text-xs font-medium px-2 py-1 rounded mb-2 ${STATUS_COLORS[status]}`}>
                {status.replace("_", " ")} ({boardColumns[status]?.length || 0})
              </h5>
              <div className="space-y-2">
                {(boardColumns[status] || []).map(t => (
                  <TicketCard key={t.id} ticket={t} onUpdate={refresh} sprints={sprints} />
                ))}
              </div>
            </div>
          ))}
        </div>
      )}

      {/* List view */}
      {view === "list" && (
        <div className="space-y-2">
          {filtered.length === 0 ? (
            <Card title="No tickets">
              <p className="text-gray-500 text-sm">Create your first ticket to start tracking tasks across tools.</p>
            </Card>
          ) : (
            filtered.map(t => (
              <TicketCard key={t.id} ticket={t} onUpdate={refresh} sprints={sprints} />
            ))
          )}
        </div>
      )}
    </div>
  );
}
