/**
 * MCP tools for rSocials (campaigns & social threads).
 *
 * Tools: rsocials_list_campaigns, rsocials_get_campaign,
 *        rsocials_list_threads, rsocials_create_thread
 */

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

export function registerSocialsTools(server: McpServer, syncServer: SyncServer) {
	server.tool(
		"rsocials_list_campaigns",
		"List social media campaigns in a space",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token (required for private/permissioned spaces)"),
		},
		async ({ space, token }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const doc = syncServer.getDoc<SocialsDoc>(socialsDocId(space));
			if (!doc) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "No socials data found for this space" }) }] };
			}

			const campaigns = Object.values(doc.campaigns || {}).map(c => ({
				id: c.id,
				title: c.title,
				description: c.description,
				platforms: c.platforms,
				postCount: c.posts?.length ?? 0,
				createdAt: c.createdAt,
				updatedAt: c.updatedAt,
			}));

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

	server.tool(
		"rsocials_get_campaign",
		"Get full details of a specific campaign including posts",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token"),
			campaign_id: z.string().describe("Campaign ID"),
		},
		async ({ space, token, campaign_id }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

			const doc = syncServer.getDoc<SocialsDoc>(socialsDocId(space));
			const campaign = doc?.campaigns?.[campaign_id];
			if (!campaign) {
				return { content: [{ type: "text", text: JSON.stringify({ error: "Campaign not found" }) }] };
			}

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

	server.tool(
		"rsocials_list_threads",
		"List social threads in a space",
		{
			space: z.string().describe("Space slug"),
			token: z.string().optional().describe("JWT auth token"),
			limit: z.number().optional().describe("Max results (default 50)"),
		},
		async ({ space, token, limit }) => {
			const access = await resolveAccess(token, space, false);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

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

			const threads = Object.values(doc.threads || {})
				.sort((a, b) => b.updatedAt - a.updatedAt)
				.slice(0, limit || 50)
				.map(t => ({
					id: t.id,
					name: t.name,
					handle: t.handle,
					title: t.title,
					tweetCount: t.tweets?.length ?? 0,
					createdAt: t.createdAt,
					updatedAt: t.updatedAt,
				}));

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

	server.tool(
		"rsocials_create_thread",
		"Create a new social thread (requires auth token + space membership)",
		{
			space: z.string().describe("Space slug"),
			token: z.string().describe("JWT auth token"),
			name: z.string().describe("Author display name"),
			handle: z.string().describe("Author handle"),
			title: z.string().describe("Thread title"),
			tweets: z.array(z.string()).describe("Tweet texts in order"),
		},
		async ({ space, token, name, handle, title, tweets }) => {
			const access = await resolveAccess(token, space, true);
			if (!access.allowed) return accessDeniedResponse(access.reason!);

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

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

			syncServer.changeDoc<SocialsDoc>(docId, `Create thread ${title}`, (d) => {
				if (!d.threads) (d as any).threads = {};
				d.threads[threadId] = {
					id: threadId,
					name,
					handle,
					title,
					tweets,
					imageUrl: null,
					tweetImages: null,
					createdAt: now,
					updatedAt: now,
				};
			});

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