import { Command } from 'commander';

export interface ConsoleCommandDeps {
  getProject: () => string | undefined;
  configLoader?: () => { mcplocalUrl: string };
  credentialsLoader?: () => { token: string } | null;
}

export function createConsoleCommand(deps: ConsoleCommandDeps): Command {
  const cmd = new Command('console')
    .description('Interactive MCP console — unified timeline with tools, provenance, and lab replay')
    .argument('[project]', 'Project name to connect to')
    .option('--stdin-mcp', 'Run inspector as MCP server over stdin/stdout (for Claude)')
    .option('--audit', 'Browse audit events from mcpd')
    .action(async (projectName: string | undefined, opts: { stdinMcp?: boolean; audit?: boolean }) => {
      let mcplocalUrl = 'http://localhost:3200';
      if (deps.configLoader) {
        mcplocalUrl = deps.configLoader().mcplocalUrl;
      } else {
        try {
          const { loadConfig } = await import('../../config/index.js');
          mcplocalUrl = loadConfig().mcplocalUrl;
        } catch {
          // Use default
        }
      }

      // --stdin-mcp: MCP server for Claude (unchanged)
      if (opts.stdinMcp) {
        const { runInspectMcp } = await import('./inspect-mcp.js');
        await runInspectMcp(mcplocalUrl);
        return;
      }

      let token: string | undefined;
      if (deps.credentialsLoader) {
        token = deps.credentialsLoader()?.token;
      } else {
        try {
          const { loadCredentials } = await import('../../auth/index.js');
          token = loadCredentials()?.token;
        } catch {
          // No credentials
        }
      }

      // --audit: browse audit events from mcpd
      if (opts.audit) {
        let mcpdUrl = 'http://localhost:3100';
        try {
          const { loadConfig } = await import('../../config/index.js');
          mcpdUrl = loadConfig().mcpdUrl;
        } catch {
          // Use default
        }
        const { renderAuditConsole } = await import('./audit-app.js');
        await renderAuditConsole({ mcpdUrl, token, projectFilter: projectName });
        return;
      }

      // Build endpoint URL only if project specified
      let endpointUrl: string | undefined;
      if (projectName) {
        endpointUrl = `${mcplocalUrl.replace(/\/$/, '')}/projects/${encodeURIComponent(projectName)}/mcp`;

        // Preflight check: verify the project exists before launching the TUI
        const { postJsonRpc, sendDelete } = await import('../mcp.js');
        try {
          const initResult = await postJsonRpc(
            endpointUrl,
            JSON.stringify({
              jsonrpc: '2.0',
              id: 0,
              method: 'initialize',
              params: {
                protocolVersion: '2024-11-05',
                capabilities: {},
                clientInfo: { name: 'mcpctl-preflight', version: '0.0.1' },
              },
            }),
            undefined,
            token,
          );

          if (initResult.status >= 400) {
            try {
              const body = JSON.parse(initResult.body) as { error?: string };
              console.error(`Error: ${body.error ?? `HTTP ${initResult.status}`}`);
            } catch {
              console.error(`Error: HTTP ${initResult.status} — ${initResult.body}`);
            }
            process.exit(1);
          }

          // Clean up the preflight session
          const sid = initResult.headers['mcp-session-id'];
          if (typeof sid === 'string') {
            await sendDelete(endpointUrl, sid, token);
          }
        } catch (err) {
          console.error(`Error: cannot connect to mcplocal at ${mcplocalUrl}`);
          console.error(err instanceof Error ? err.message : String(err));
          process.exit(1);
        }
      }

      // Launch unified console (observe-only if no project, interactive available if project given)
      const { renderUnifiedConsole } = await import('./unified-app.js');
      await renderUnifiedConsole({ projectName, endpointUrl, mcplocalUrl, token });
    });

  return cmd;
}
