/**
 * work_start — Pick up a task from the issue queue.
 *
 * Context-aware: ONLY works in project group chats.
 * Auto-detects: projectGroupId, role, level, issueId.
 * Picks up only the explicitly requested issue (auto-tick disabled).
 */
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
import { jsonResult } from "openclaw/plugin-sdk";
import type { ToolContext } from "../types.js";
import type { StateLabel } from "../providers/provider.js";
import { selectLevel } from "../model-selector.js";
import { getWorker } from "../projects.js";
import { dispatchTask } from "../dispatch.js";
import { findNextIssue, detectRoleFromLabel, detectLevelFromLabels } from "../services/tick.js";
import { getAllRoleIds, isLevelForRole } from "../roles/index.js";
import { requireWorkspaceDir, resolveProject, resolveProvider, getPluginConfig } from "../tool-helpers.js";
import { loadWorkflow, getActiveLabel } from "../workflow.js";

export function createWorkStartTool(api: OpenClawPluginApi) {
  return (ctx: ToolContext) => ({
    name: "work_start",
    label: "Work Start",
    description: `Pick up a task from the issue queue. ONLY works in project group chats. Handles label transition, level assignment, session creation, dispatch, and audit. Picks up only the explicitly requested issue.`,
    parameters: {
      type: "object",
      required: ["projectGroupId"],
      properties: {
        projectGroupId: { type: "string", description: "Project group ID." },
        issueId: { type: "number", description: "Issue ID. If omitted, picks next by priority." },
        role: { type: "string", enum: getAllRoleIds(), description: "Worker role. Auto-detected from label if omitted." },
        level: { type: "string", description: "Worker level (junior/mid/senior). Auto-detected if omitted." },
      },
    },

    async execute(_id: string, params: Record<string, unknown>) {
      const issueIdParam = params.issueId as number | undefined;
      const roleParam = params.role as string | undefined;
      const groupId = params.projectGroupId as string;
      const levelParam = (params.level ?? params.tier) as string | undefined;
      const workspaceDir = requireWorkspaceDir(ctx);

      if (!groupId) throw new Error("projectGroupId is required");
      const { project } = await resolveProject(workspaceDir, groupId);
      const { provider } = await resolveProvider(project);

      const workflow = await loadWorkflow(workspaceDir, project.name);

      // Find issue
      let issue: { iid: number; title: string; description: string; labels: string[]; web_url: string; state: string };
      let currentLabel: StateLabel;
      if (issueIdParam !== undefined) {
        issue = await provider.getIssue(issueIdParam);
        const label = provider.getCurrentStateLabel(issue);
        if (!label) throw new Error(`Issue #${issueIdParam} has no recognized state label`);
        currentLabel = label;
      } else {
        const next = await findNextIssue(provider, roleParam, workflow);
        if (!next) return jsonResult({ success: false, error: `No issues available. Queue is empty.` });
        issue = next.issue;
        currentLabel = next.label;
      }

      // Detect role
      const detectedRole = detectRoleFromLabel(currentLabel, workflow);
      if (!detectedRole) throw new Error(`Label "${currentLabel}" doesn't map to a role`);
      const role = roleParam ?? detectedRole;
      if (roleParam && roleParam !== detectedRole) throw new Error(`Role mismatch: "${currentLabel}" → ${detectedRole}, requested ${roleParam}`);

      // Check worker availability
      const worker = getWorker(project, role);
      if (worker.active) throw new Error(`${role.toUpperCase()} already active on ${project.name} (issue: ${worker.issueId})`);
      if ((project.roleExecution ?? "parallel") === "sequential") {
        for (const [otherRole, otherWorker] of Object.entries(project.workers)) {
          if (otherRole !== role && otherWorker.active) {
            throw new Error(`Sequential roleExecution: ${otherRole.toUpperCase()} is active`);
          }
        }
      }

      // Get target label from workflow
      const targetLabel = getActiveLabel(workflow, role);

      // Select level
      let selectedLevel: string, levelReason: string, levelSource: string;
      if (levelParam) {
        selectedLevel = levelParam; levelReason = "LLM-selected"; levelSource = "llm";
      } else {
        const labelLevel = detectLevelFromLabels(issue.labels);
        if (labelLevel) {
          if (!isLevelForRole(labelLevel, role)) {
            // Label level belongs to a different role — use heuristic for this role
            const s = selectLevel(issue.title, issue.description ?? "", role);
            selectedLevel = s.level; levelReason = `${role} overrides other role's level "${labelLevel}"`; levelSource = "role-override";
          } else {
            selectedLevel = labelLevel; levelReason = `Label: "${labelLevel}"`; levelSource = "label";
          }
        } else {
          const s = selectLevel(issue.title, issue.description ?? "", role);
          selectedLevel = s.level; levelReason = s.reason; levelSource = "heuristic";
        }
      }

      // Dispatch (pass runtime for direct API access)
      const pluginConfig = getPluginConfig(api);
      const dr = await dispatchTask({
        workspaceDir, agentId: ctx.agentId, groupId, project, issueId: issue.iid,
        issueTitle: issue.title, issueDescription: issue.description ?? "", issueUrl: issue.web_url,
        role, level: selectedLevel, fromLabel: currentLabel, toLabel: targetLabel,
        transitionLabel: (id, from, to) => provider.transitionLabel(id, from as StateLabel, to as StateLabel),
        provider,
        pluginConfig,
        channel: project.channel,
        sessionKey: ctx.sessionKey,
        runtime: api.runtime,
      });

      // Auto-tick disabled per issue #125 - work_start should only pick up the explicitly requested issue
      // The heartbeat service fills parallel slots automatically

      const output: Record<string, unknown> = {
        success: true, project: project.name, groupId, issueId: issue.iid, issueTitle: issue.title,
        role, level: dr.level, model: dr.model, sessionAction: dr.sessionAction,
        announcement: dr.announcement, labelTransition: `${currentLabel} → ${targetLabel}`,
        levelReason, levelSource,
        autoDetected: { role: !roleParam, issueId: issueIdParam === undefined, level: !levelParam },
      };
      // tickPickups removed with auto-tick

      return jsonResult(output);
    },
  });
}
