/**
 * ChronoMind MCP tools — chronomind.timers.*, chronomind.routines.*, chronomind.syncStatus
 *
 * Backed by: chronomind-backend (port 4011).
 * All tools require admin role.
 */

import { z } from 'zod';
import { registerTool } from '../tools/registry.js';
import { config } from '../../lib/config.js';
import {
  chronomindTimerCreate,
  chronomindTimersList,
  chronomindTimerDelete,
  chronomindRoutineGet,
  chronomindRoutinesList,
  chronomindSyncStatus,
  chronomindHouseholdsList,
  chronomindSharedTimerShare,
} from '../../lib/chronomind-client.js';
import type { McpToolRequest } from '../tools/types.js';

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

// ── chronomind.timers.create ───────────────────────────────────────────────

registerTool({
  name: 'chronomind.timers.create',
  description:
    'Create a new cloud-synced timer. The id and syncVersion must be provided by the caller (client-generated UUID and current version). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    id: z.string().min(1).describe('Client-generated timer UUID'),
    label: z.string().min(1).describe('Timer display name'),
    type: z.enum(['alarm', 'countdown', 'pomodoro', 'event']),
    urgency: z.enum(['critical', 'important', 'standard', 'gentle', 'passive']).default('standard'),
    duration: z.coerce.number().optional().describe('Duration in seconds (countdown/pomodoro)'),
    targetTime: z.string().optional().describe('ISO 8601 target time (alarm/event)'),
    category: z.string().optional().describe('Timer category label'),
    syncVersion: z.coerce.number().default(1),
    deviceId: z.string().optional().describe('Origin device ID for conflict detection'),
  }),
  async execute(args, req) {
    return chronomindTimerCreate(
      { ...args, state: 'idle' },
      { token: tokenOf(req), requestId: req.id }
    );
  },
});

// ── chronomind.timers.list ────────────────────────────────────────────────

registerTool({
  name: 'chronomind.timers.list',
  description:
    'List cloud-synced timers for the authenticated user. Filter by type (alarm/countdown/pomodoro/event) or state (idle/active/paused/warning/fired/completed). Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    type: z
      .enum(['alarm', 'countdown', 'pomodoro', 'event'])
      .optional()
      .describe('Filter by timer type'),
    state: z
      .enum(['idle', 'active', 'paused', 'warning', 'fired', 'completed'])
      .optional()
      .describe('Filter by timer state'),
    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 chronomindTimersList(args, { token: tokenOf(req), requestId: req.id });
  },
});

// ── chronomind.timers.delete ──────────────────────────────────────────────

registerTool({
  name: 'chronomind.timers.delete',
  description: 'Delete a timer by ID. Use with care — deletion is permanent. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    timerId: z.string().min(1).describe('Timer ID to delete'),
  }),
  async execute(args, req) {
    return chronomindTimerDelete(args.timerId, { token: tokenOf(req), requestId: req.id });
  },
});

// ── chronomind.routines.list ──────────────────────────────────────────────

registerTool({
  name: 'chronomind.routines.list',
  description:
    'List cloud-synced routines for the authenticated user. Optionally filter to template routines only. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    isTemplate: z
      .boolean()
      .optional()
      .describe('true = only templates, false = only user routines'),
    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 chronomindRoutinesList(args, { token: tokenOf(req), requestId: req.id });
  },
});

// ── chronomind.syncStatus ─────────────────────────────────────────────────

registerTool({
  name: 'chronomind.syncStatus',
  description:
    'Instant sync health check: total timers, active count, pending count, unsynced count, and last sync timestamp. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({}),
  async execute(_args, req) {
    return chronomindSyncStatus({ token: tokenOf(req), requestId: req.id });
  },
});

// ── chronomind.sharedTimers.share ──────────────────────────────────────────

registerTool({
  name: 'chronomind.sharedTimers.share',
  description:
    'Share a timer with one or more household members or specific user IDs. Creates a shared-timer record in the shared-timers module. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    timerId: z.string().min(1).describe('ID of the timer to share'),
    targets: z
      .array(
        z.object({
          userId: z.string().optional().describe('Target user ID'),
          householdId: z
            .string()
            .optional()
            .describe('Target household ID (shares with all members)'),
        })
      )
      .min(1)
      .describe('Recipients — provide userId or householdId for each target'),
  }),
  async execute(args, req) {
    return chronomindSharedTimerShare(args.timerId, args.targets, {
      token: tokenOf(req),
      requestId: req.id,
    });
  },
});

// ── chronomind.routines.validate ─────────────────────────────────────────

registerTool({
  name: 'chronomind.routines.validate',
  description:
    'Validate a routine for structural integrity: checks that total duration does not exceed the maximum, that all steps have non-zero duration, and that the routine has at least one step. Returns pass/fail with a list of issues. Requires admin role.',
  requiredRole: 'admin',
  inputSchema: z.object({
    routineId: z.string().min(1).describe('Routine ID to validate'),
    maxDurationMinutes: z.coerce
      .number()
      .min(1)
      .max(1440)
      .default(480)
      .describe('Maximum allowed total duration in minutes (default 480 = 8h)'),
  }),
  async execute(args, req) {
    let routine;
    try {
      routine = await chronomindRoutineGet(args.routineId, {
        token: tokenOf(req),
        requestId: req.id,
      });
    } catch {
      return { valid: false, routineId: args.routineId, issues: ['Routine not found'] };
    }
    const issues: string[] = [];
    if (!routine.steps || routine.steps.length === 0) issues.push('Routine has no steps');
    if (routine.totalDurationMinutes > args.maxDurationMinutes) {
      issues.push(
        `Total duration ${routine.totalDurationMinutes}min exceeds max ${args.maxDurationMinutes}min`
      );
    }
    return {
      valid: issues.length === 0,
      routineId: routine.id,
      routineName: routine.name,
      stepCount: routine.steps.length,
      totalDurationMinutes: routine.totalDurationMinutes,
      maxDurationMinutes: args.maxDurationMinutes,
      issues,
    };
  },
});

// ── chronomind.households.list ──────────────────────────────────────────────

registerTool({
  name: 'chronomind.households.list',
  description:
    'List ChronoMind Family-tier households the authenticated user belongs to, including member list and invite codes. 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 chronomindHouseholdsList(args, { token: tokenOf(req), requestId: req.id });
  },
});
