import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { registerUserTools } from './tools/user.js';
import { registerPaymentTools } from './tools/payment.js';
import { registerProofTools } from './tools/proofs.js';
import { registerSystemTools } from './tools/system.js';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { getToolSecuritySchemes } from './lib/tool-security.js';
import { UI_TEMPLATE_URI } from './lib/ui.js';
import { config } from './config.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

export const createServer = () => {
  const server = new McpServer({
    name: "ProovIT MCP",
    version: "1.0.0"
  });

  // Register UI Resource
  const widgetMeta = {
    "openai/widgetPrefersBorder": true,
    "openai/widgetDomain": config.widgetDomain,
    "openai/widgetCSP": {
      connect_domains: [config.widgetDomain],
      resource_domains: [config.widgetDomain]
    }
  };

  server.registerResource(
    "ui",
    UI_TEMPLATE_URI,
    {
      title: "ProovIT UI",
      _meta: widgetMeta
    },
    async (uri) => {
      const uiPath = path.join(process.cwd(), 'dist', 'client', 'index.html');
      try {
        const content = await fs.promises.readFile(uiPath, 'utf-8');
        return {
          contents: [{
            uri: uri.href,
            mimeType: "text/html+skybridge",
            text: content,
            _meta: widgetMeta
          }]
        };
      } catch (err) {
        return {
          contents: [{
            uri: uri.href,
            mimeType: "text/plain",
            text: "UI bundle not found. Please run 'npm run build:client'."
          }]
        };
      }
    }
  );

  // Register all tool modules
  registerSystemTools(server); // Public
  registerUserTools(server);   // Protected
  registerPaymentTools(server); // Protected
  registerProofTools(server);   // Protected

  // Inject securitySchemes into the tools/list response until the SDK supports it natively.
  const protocolServer = (server as any).server;
  const requestHandlers = protocolServer?._requestHandlers;
  const originalListTools = requestHandlers?.get('tools/list');
  if (protocolServer?.setRequestHandler && originalListTools) {
    protocolServer.setRequestHandler(ListToolsRequestSchema, async (request: any, extra: any) => {
      const result = await originalListTools(request, extra);
      if (!result || !Array.isArray(result.tools)) {
        return result;
      }
      const schemesByTool = getToolSecuritySchemes();
      return {
        ...result,
        tools: result.tools.map((tool: any) => {
          const schemes = schemesByTool.get(tool.name);
          return schemes ? { ...tool, securitySchemes: schemes } : tool;
        })
      };
    });
  }

  return server;
};
