/**
 * PeakPulse MCP tools — peakpulse.sessions.*, peakpulse.routes.*, peakpulse.stats
 *
 * Backed by: peakpulse-backend (port 4010).
 * All tools require admin role.
 */

import { z } from 'zod';
import { registerTool } from '../tools/registry.js';
import { config } from '../../lib/config.js';
import {
  peakpulseSessionsList,
  peakpulseSessionGet,
  peakpulseSessionExport,
  peakpulseGetStats,
  peakpulseRoutesList,
  peakpulseRouteGet,
  peakpulseSyncStatus,
} from '../../lib/peakpulse-client.js';
import type { McpToolRequest } from '../tools/types.js';

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

// ── peakpulse.sessions.list ───────────────────────────────────────────────

registerTool({
  name: 'peakpulse.sessions.list',
  description:
    'List adventure sessions for the authenticated user. Filter by activity type (hiking/skiing/cycling/running) or status. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    activityType: z
      .enum(['hiking', 'skiing', 'cycling', 'running'])
      .optional()
      .describe('Filter by activity type'),
    status: z
      .enum(['active', 'completed', 'paused'])
      .optional()
      .describe('Filter by session status'),
    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 peakpulseSessionsList(args, { token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.sessions.export ─────────────────────────────────────────────

registerTool({
  name: 'peakpulse.sessions.export',
  description:
    'Export a session as a portable JSON summary including GPS bounds, ski metrics, weather snapshot, and elevation data. Useful for sharing or route-review flows. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    sessionId: z.string().min(1).describe('Session ID to export'),
  }),
  async execute(args, req) {
    return peakpulseSessionExport(args.sessionId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.stats ───────────────────────────────────────────────────────

registerTool({
  name: 'peakpulse.stats',
  description:
    'Get aggregated activity stats for the authenticated user (total sessions, distance, elevation gain, per-activity breakdown). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({}),
  async execute(_args, req) {
    return peakpulseGetStats({ token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.sessions.get ──────────────────────────────────────────────────

registerTool({
  name: 'peakpulse.sessions.get',
  description:
    'Get a single adventure session by ID including activityType, GPS trackPoints summary, ski/hike metrics, weather snapshot, and haptic events. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    sessionId: z.string().min(1).describe('Session ID'),
  }),
  async execute(args, req) {
    return peakpulseSessionGet(args.sessionId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.routes.list ───────────────────────────────────────────────────

registerTool({
  name: 'peakpulse.routes.list',
  description:
    'List GPS route documents for the authenticated user. Each route contains track points, haptic milestone events, and a bounding box. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    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 peakpulseRoutesList(args, { token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.routes.get ────────────────────────────────────────────────────

registerTool({
  name: 'peakpulse.routes.get',
  description:
    'Retrieve GPS track points and haptic milestone events for a session. Returns bounding box coordinates plus full track point array. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    sessionId: z.string().min(1).describe('Session ID to get route data for'),
  }),
  async execute(args, req) {
    return peakpulseRouteGet(args.sessionId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.syncStatus ─────────────────────────────────────────────────────

registerTool({
  name: 'peakpulse.syncStatus',
  description:
    'Check the PeakPulse offline upload queue: pending session count, last successful sync timestamp, and oldest pending item age. Useful for diagnosing sync failures on iOS. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({}),
  async execute(_args, req) {
    return peakpulseSyncStatus({ token: tokenOf(req), requestId: req.id });
  },
});

// ── peakpulse.weather.getSnapshot ───────────────────────────────────────────────

registerTool({
  name: 'peakpulse.weather.getSnapshot',
  description:
    'Get the weather snapshot captured at the start of a session (temperature, wind speed, UV index, condition). Returns null if weather data was not captured. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    sessionId: z.string().min(1).describe('Session ID to retrieve weather snapshot for'),
  }),
  async execute(args, req) {
    const session = await peakpulseSessionGet(args.sessionId, {
      token: tokenOf(req),
      requestId: req.id,
    });
    return {
      sessionId: args.sessionId,
      weather: (session as unknown as Record<string, unknown>).weather ?? null,
    };
  },
});
