import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { readFile } from 'node:fs/promises'
import { z } from 'zod'
import { sh } from '../_shell'
import { appendSimulatorInspectionGuidance } from './simulator-guidance'

// Disable ANSI color codes from spawned tools so MCP text output stays readable
// (the host renders raw text; escape sequences leak into the result otherwise).
const noColorEnv = { FORCE_COLOR: '0', NO_COLOR: '1' }

export function register(server: McpServer, projectDir: string) {
  const { dirname } = import.meta

  server.tool('compile', {}, async () => {
    let log = 'Type checking & Compiling...\n'
    try {
      log += await sh`bun compile`.cwd(projectDir).env(noColorEnv).text()
    } catch (err: any) {
      const stdout = err.stdout?.toString() ?? ''
      const stderr = err.stderr?.toString() ?? ''
      log += [stdout, stderr].filter(Boolean).join('\n')
    }
    return {
      content: [{ type: 'text', text: log }],
    }
  })

  if (process.env.BRICKS_CTOR_MCP_DISABLE_PREVIEW === '1') return

  server.tool(
    'preview',
    {
      delay: z
        .number()
        .describe('Delay in milliseconds before taking screenshot')
        .optional()
        .default(3000),
      width: z.number().describe('Width of the screenshot').optional().default(600),
      height: z.number().optional().default(480),
      responseImage: z
        .boolean()
        .describe(
          'Whether to response image content (base64 encoded jpeg). If false, only saved path will be responded as text.',
        )
        .optional()
        .default(false),
      testId: z.string().describe('Automation test ID to trigger').optional(),
      testTitleLike: z
        .string()
        .describe('Find automation test by partial title match (case-insensitive)')
        .optional(),
    } as any,
    async ({ delay, width, height, responseImage, testId, testTitleLike }: any) => {
      let log = ''
      let error = false
      try {
        const toolsDir = `${dirname}/..`
        const args = [
          '--no-keep-open',
          '--take-screenshot',
          JSON.stringify({
            delay,
            width,
            height,
            path: `${toolsDir}/screenshot.jpg`,
            closeAfter: true,
            headless: true,
          }),
        ]
        if (testId) args.push('--test-id', testId)
        if (testTitleLike) args.push('--test-title-like', testTitleLike)
        log = await sh`bunx --bun electron ${toolsDir}/preview-main.mjs ${args}`
          .cwd(projectDir)
          .env(noColorEnv)
          .text()
      } catch (err: any) {
        const stdout = err.stdout?.toString() ?? ''
        const stderr = err.stderr?.toString() ?? ''
        log = [stdout, stderr].filter(Boolean).join('\n')
        error = true
      }
      if (!error) log = appendSimulatorInspectionGuidance(log, { testId, testTitleLike })
      let screenshotBase64: string | null = null
      if (!error && responseImage) {
        const toolsDir = `${dirname}/..`
        const screenshot = await readFile(`${toolsDir}/screenshot.jpg`)
        screenshotBase64 = screenshot.toString('base64')
      }
      const content: Array<
        { type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string }
      > = [{ type: 'text', text: log }]
      if (screenshotBase64) {
        content.push({
          type: 'image',
          data: screenshotBase64,
          mimeType: 'image/jpeg',
        })
      }
      return {
        content,
      }
    },
  )
}
