import { PopulatedFlow } from '@activepieces/core-execution'
import { ApId, BaseModelSchema, Permission } from '@activepieces/core-utils'
import { z } from 'zod'

export type McpId = ApId

export const MCP_TRIGGER_PIECE_NAME = '@activepieces/piece-mcp'

export enum McpServerType {
    PLATFORM = 'PLATFORM',
    PROJECT = 'PROJECT',
}

export const McpServer = z.object({
    ...BaseModelSchema,
    platformId: z.nullable(ApId),
    projectId: z.nullable(ApId),
    type: z.enum([McpServerType.PLATFORM, McpServerType.PROJECT]),
    token: ApId,
    disabledTools: z.array(z.string()).nullable(),
})

export const PopulatedMcpServer = McpServer.extend({
    flows: z.array(PopulatedFlow),
})
export type PopulatedMcpServer = z.infer<typeof PopulatedMcpServer>

export type McpServer = z.infer<typeof McpServer>

export type ProjectScopedMcpServer = McpServer & { projectId: string }

export type McpToolContext = {
    mcp: ProjectScopedMcpServer
    userId?: string
}

export const UpdateMcpServerRequest = z.object({
    disabledTools: z.array(z.string()).optional(),
})

export type UpdateMcpServerRequest = z.infer<typeof UpdateMcpServerRequest>

/** Tool definition for MCP: inputSchema is a raw Zod shape (same as MCP expects). */
export type McpToolDefinition = {
    title: string
    description: string
    inputSchema: Record<string, z.ZodTypeAny>
    annotations?: {
        readOnlyHint?: boolean
        destructiveHint?: boolean
        idempotentHint?: boolean
        openWorldHint?: boolean
    }
    permission?: Permission
    execute: (args: Record<string, unknown>) => Promise<McpToolResult>
}

export type McpToolResult = {
    content: Array<{ type: 'text', text: string }>
    structuredContent?: Record<string, unknown>
    isError?: boolean
}
