/**
 * Tracker MCP tools — tracker.items.*, tracker.votes.*, tracker.comments.*, tracker.public.*
 *
 * Backed by: platform-service (port 4003) — items, votes, comments, public modules.
 * All tools require admin role minimum.
 */

import { z } from 'zod';
import { registerTool } from '../tools/registry.js';
import { config } from '../../lib/config.js';
import {
  trackerItemsList,
  trackerItemsStats,
  trackerItemsGet,
  trackerItemsCreate,
  trackerItemsUpdateStatus,
  trackerItemsDelete,
  trackerVotesToggle,
  trackerVotesList,
  trackerCommentsList,
  trackerCommentsAdd,
  trackerCommentsDelete,
  trackerPublicRoadmap,
  trackerPublicStats,
} from '../../lib/platform-client.js';
import type { McpToolRequest } from '../tools/types.js';

const tokenOf = (req: McpToolRequest) => req.headers.authorization?.slice(7);

// ── tracker.items.stats ───────────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.stats',
  description:
    'Aggregate tracker item counts by type, status, and priority for the product scoped to the request. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID to scope the stats'),
  }),
  async execute(args, req) {
    return trackerItemsStats({ token: tokenOf(req), requestId: req.id, productId: args.productId });
  },
});

// ── tracker.items.list ────────────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.list',
  description:
    'List tracker items (bugs, feature requests, tasks, improvements). Filter by type, status, priority, visibility, or free text. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
    type: z
      .enum(['bug', 'feature', 'task', 'improvement'])
      .optional()
      .describe('Filter by item type'),
    status: z
      .enum(['open', 'in_progress', 'in_review', 'closed', 'wont_fix'])
      .optional()
      .describe('Filter by status'),
    priority: z
      .enum(['critical', 'high', 'medium', 'low'])
      .optional()
      .describe('Filter by priority'),
    visibility: z
      .enum(['public', 'internal'])
      .optional()
      .describe('Filter by visibility (public = on roadmap)'),
    q: z.string().optional().describe('Full-text search across title and description'),
    sortBy: z
      .enum(['createdAt', 'updatedAt', 'voteCount', 'priority'])
      .optional()
      .default('createdAt'),
    sortOrder: z.enum(['asc', 'desc']).optional().default('desc'),
    limit: z.coerce.number().min(1).max(config.QUERY_MAX_LIMIT).default(config.QUERY_DEFAULT_LIMIT),
    offset: z.coerce.number().min(0).default(0),
  }),
  async execute(args, req) {
    return trackerItemsList(args, {
      token: tokenOf(req),
      requestId: req.id,
      productId: args.productId,
    });
  },
});

// ── tracker.items.get ─────────────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.get',
  description:
    'Get a single tracker item by ID including voteCount, commentCount, labels, assignee, and targetRelease. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID (trk_…)'),
  }),
  async execute(args, req) {
    return trackerItemsGet(args.itemId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.items.create ──────────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.create',
  description:
    'Create a new tracker item. Sets status=open automatically. Visibility defaults to internal — set to public to surface on the roadmap. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
    type: z.enum(['bug', 'feature', 'task', 'improvement']),
    priority: z.enum(['critical', 'high', 'medium', 'low']).default('medium'),
    title: z.string().min(1).max(250).describe('Item title'),
    description: z.string().optional().describe('Detailed description (markdown supported)'),
    labels: z.array(z.string()).optional().describe('Label tags'),
    assignee: z.string().optional().describe('Assignee user ID or email'),
    visibility: z.enum(['public', 'internal']).optional().default('internal'),
    targetRelease: z.string().optional().describe('Target release version string'),
  }),
  async execute(args, req) {
    return trackerItemsCreate(args, {
      token: tokenOf(req),
      requestId: req.id,
      productId: args.productId,
    });
  },
});

// ── tracker.items.updateStatus ────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.updateStatus',
  description:
    'Quick status transition for a tracker item (open → in_progress → in_review → closed / wont_fix). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID'),
    status: z.enum(['open', 'in_progress', 'in_review', 'closed', 'wont_fix']),
  }),
  async execute(args, req) {
    return trackerItemsUpdateStatus(args.itemId, args.status, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── tracker.items.delete ──────────────────────────────────────────────────────

registerTool({
  name: 'tracker.items.delete',
  description:
    'Permanently delete a tracker item. This also removes associated vote counts. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID to delete'),
  }),
  async execute(args, req) {
    return trackerItemsDelete(args.itemId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.votes.toggle ──────────────────────────────────────────────────────

registerTool({
  name: 'tracker.votes.toggle',
  description:
    'Toggle an upvote on a tracker item on behalf of the authenticated admin user. Returns new voteCount and voted state. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID to vote on'),
  }),
  async execute(args, req) {
    return trackerVotesToggle(args.itemId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.votes.list ────────────────────────────────────────────────────────

registerTool({
  name: 'tracker.votes.list',
  description: 'List voters for a tracker item (userId list + count). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID'),
  }),
  async execute(args, req) {
    return trackerVotesList(args.itemId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.comments.list ─────────────────────────────────────────────────────

registerTool({
  name: 'tracker.comments.list',
  description: 'List all comments for a tracker item in chronological order. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID'),
  }),
  async execute(args, req) {
    return trackerCommentsList(args.itemId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.comments.add ──────────────────────────────────────────────────────

registerTool({
  name: 'tracker.comments.add',
  description:
    'Add a comment to a tracker item. The comment body supports Markdown. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID'),
    body: z.string().min(1).describe('Comment body (Markdown supported)'),
  }),
  async execute(args, req) {
    return trackerCommentsAdd(args.itemId, args.body, { token: tokenOf(req), requestId: req.id });
  },
});

// ── tracker.comments.delete ───────────────────────────────────────────────────

registerTool({
  name: 'tracker.comments.delete',
  description: 'Delete a comment (admin can delete any comment). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    itemId: z.string().min(1).describe('Tracker item ID'),
    commentId: z.string().min(1).describe('Comment ID (cmt_…)'),
  }),
  async execute(args, req) {
    return trackerCommentsDelete(args.itemId, args.commentId, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── tracker.public.roadmap ────────────────────────────────────────────────────

registerTool({
  name: 'tracker.public.roadmap',
  description:
    'List public roadmap items (visibility=public, excludes closed/wont_fix) as seen by end-users. No auth required on the backend — useful for admin inspection of what is publicly visible. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
    type: z.enum(['bug', 'feature', 'task', 'improvement']).optional().describe('Filter by type'),
    status: z.enum(['open', 'in_progress', 'in_review']).optional().describe('Filter by status'),
    q: z.string().optional().describe('Free-text search'),
    sortBy: z.enum(['createdAt', 'updatedAt', 'voteCount']).optional().default('voteCount'),
    sortOrder: z.enum(['asc', 'desc']).optional().default('desc'),
    limit: z.coerce.number().min(1).max(config.QUERY_MAX_LIMIT).default(config.QUERY_DEFAULT_LIMIT),
    offset: z.coerce.number().min(0).default(0),
  }),
  async execute(args, req) {
    return trackerPublicRoadmap(args, {
      token: tokenOf(req),
      requestId: req.id,
      productId: args.productId,
    });
  },
});

// ── tracker.public.stats ──────────────────────────────────────────────────────

registerTool({
  name: 'tracker.public.stats',
  description:
    'Aggregate public roadmap stats: total public items, counts by status and type, total votes cast. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID'),
  }),
  async execute(args, req) {
    return trackerPublicStats({
      token: tokenOf(req),
      requestId: req.id,
      productId: args.productId,
    });
  },
});
