/**
 * MCP tools for rMinders (cron jobs, reminders, workflows).
 *
 * Tools: rminders_list_jobs, rminders_list_reminders,
 *        rminders_list_workflows, rminders_create_reminder
 */

import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import type { SyncServer } from "../local-first/sync-server";
import { mindersDocId } from "../../modules/rminders/schemas";
import type { MindersDoc } from "../../modules/rminders/schemas";
import { resolveAccess, accessDeniedResponse } from "./_auth";

export function registerMindersTools(server: McpServer, syncServer: SyncServer) {
	server.tool(
		"rminders_list_jobs",
		"List cron/scheduled jobs in a space",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token"),
			enabled_only: z.boolean().optional().describe("Only show enabled jobs (default false)"),
		},
		async ({ space, token, enabled_only }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const doc = syncServer.getDoc<MindersDoc>(mindersDocId(space));
			if (!doc) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "No schedule data found" }) }] };
			}

			let jobs = Object.values(doc.jobs || {});
			if (enabled_only) jobs = jobs.filter(j => j.enabled);

			const summary = jobs.map(j => ({
				id: j.id,
				name: j.name,
				description: j.description,
				enabled: j.enabled,
				cronExpression: j.cronExpression,
				timezone: j.timezone,
				actionType: j.actionType,
				lastRunAt: j.lastRunAt,
				lastRunStatus: j.lastRunStatus,
				nextRunAt: j.nextRunAt,
				runCount: j.runCount,
			}));

			return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
		},
	);

	server.tool(
		"rminders_list_reminders",
		"List reminders in a space",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token"),
			completed: z.boolean().optional().describe("Filter by completed status"),
			upcoming_days: z.number().optional().describe("Only show reminders firing in next N days"),
			limit: z.number().optional().describe("Max results (default 50)"),
		},
		async ({ space, token, completed, upcoming_days, limit }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const doc = syncServer.getDoc<MindersDoc>(mindersDocId(space));
			if (!doc) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "No schedule data found" }) }] };
			}

			let reminders = Object.values(doc.reminders || {});

			if (completed !== undefined) {
				reminders = reminders.filter(r => r.completed === completed);
			}

			if (upcoming_days) {
				const now = Date.now();
				const cutoff = now + upcoming_days * 86400000;
				reminders = reminders.filter(r => r.remindAt >= now && r.remindAt <= cutoff);
			}

			reminders.sort((a, b) => a.remindAt - b.remindAt);
			reminders = reminders.slice(0, limit || 50);

			const summary = reminders.map(r => ({
				id: r.id,
				title: r.title,
				description: r.description,
				remindAt: r.remindAt,
				allDay: r.allDay,
				completed: r.completed,
				notified: r.notified,
				sourceModule: r.sourceModule,
				sourceLabel: r.sourceLabel,
			}));

			return { content: [{ type: "text", text: JSON.stringify(summary, null, 2) }] };
		},
	);

	server.tool(
		"rminders_list_workflows",
		"List automation workflows in a space (summaries only, omits node/edge graph)",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token"),
		},
		async ({ space, token }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const doc = syncServer.getDoc<MindersDoc>(mindersDocId(space));
			if (!doc) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "No schedule data found" }) }] };
			}

			const workflows = Object.values(doc.workflows || {}).map(w => ({
				id: w.id,
				name: w.name,
				enabled: w.enabled,
				nodeCount: w.nodes?.length ?? 0,
				edgeCount: w.edges?.length ?? 0,
				lastRunAt: w.lastRunAt,
				lastRunStatus: w.lastRunStatus,
				runCount: w.runCount,
				createdAt: w.createdAt,
				updatedAt: w.updatedAt,
			}));

			return { content: [{ type: "text", text: JSON.stringify(workflows, null, 2) }] };
		},
	);

	server.tool(
		"rminders_create_reminder",
		"Create a new reminder (requires auth token + space membership)",
		{
			space: z.string().describe("Space slug"),
			token: z.string().describe("JWT auth token"),
			title: z.string().describe("Reminder title"),
			remind_at: z.number().describe("When to fire (epoch ms)"),
			description: z.string().optional().describe("Reminder description"),
			all_day: z.boolean().optional().describe("All-day reminder"),
			source_module: z.string().optional().describe("Originating module (e.g. 'rtasks')"),
			source_label: z.string().optional().describe("Source display label"),
		},
		async ({ space, token, title, remind_at, description, all_day, source_module, source_label }) => {
			const access = await resolveAccess(token, space, true);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const docId = mindersDocId(space);
			const doc = syncServer.getDoc<MindersDoc>(docId);
			if (!doc) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "No schedule data found" }) }], isError: true };
			}

			const reminderId = `rem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;

			const now = Date.now();
			syncServer.changeDoc<MindersDoc>(docId, `Create reminder ${title}`, (d) => {
				if (!d.reminders) (d as any).reminders = {};
				d.reminders[reminderId] = {
					id: reminderId,
					title,
					description: description || "",
					remindAt: remind_at,
					allDay: all_day || false,
					timezone: "UTC",
					notifyEmail: null,
					notified: false,
					completed: false,
					sourceModule: source_module || null,
					sourceEntityId: null,
					sourceLabel: source_label || null,
					sourceColor: null,
					cronExpression: null,
					calendarEventId: null,
					createdBy: access.claims?.did ?? "",
					createdAt: now,
					updatedAt: now,
				} as any;
			});

			return { content: [{ type: "text", text: JSON.stringify({ id: reminderId, created: true }) }] };
		},
	);
}
