import { z } from 'zod';
import { registerTool } from '../tools/registry.js';
import {
  telemetryClusters,
  diagnosticsCreateSession,
  type TelemetryCluster,
} from '../../lib/platform-client.js';
import type { McpToolRequest } from '../tools/types.js';

const tokenOf = (req: McpToolRequest) => req.headers.authorization?.slice(7);

registerTool({
  name: 'support.createDebugPack',
  description: [
    'Compound tool: gathers telemetry clusters for a product + optionally creates a live diagnostics',
    'session targeting a specific user. Returns a structured debug pack artifact with cluster refs,',
    'optional session ID, and a markdown summary. Requires admin role.',
  ].join(' '),
  requiredRole: 'admin',
  inputSchema: z.object({
    productId: z.string().min(1).describe('Product ID to scope the debug pack'),
    targetUserId: z
      .string()
      .optional()
      .describe('User ID to target for a live diagnostics session (omit to skip session creation)'),
    targetAnonymousId: z
      .string()
      .optional()
      .describe('Anonymous install ID to target (alternative to targetUserId)'),
    from: z.string().optional().describe('ISO 8601 start time for cluster query'),
    to: z.string().optional().describe('ISO 8601 end time for cluster query'),
    collectionLevel: z
      .enum(['standard', 'debug', 'trace'])
      .optional()
      .describe('Diagnostics session collection level (default: debug)'),
    reason: z.string().optional().describe('Human-readable reason for creating this debug pack'),
  }),
  async execute(args, req) {
    const opts = {
      token: tokenOf(req),
      requestId: req.id,
      productId: args.productId,
    };

    const generatedAt = new Date().toISOString();

    // Step 1: collect error clusters
    let clusters: TelemetryCluster[] = [];
    let clusterError: string | undefined;
    try {
      const result = await telemetryClusters({ from: args.from, to: args.to }, opts);
      clusters = result.clusters;
    } catch (err) {
      clusterError = err instanceof Error ? err.message : String(err);
    }

    // Step 2: optionally create a diagnostics session
    let session: { id: string; status: string; expiresAt: string } | undefined;
    let sessionError: string | undefined;
    const wantsSession = !!(args.targetUserId || args.targetAnonymousId);
    if (wantsSession) {
      try {
        session = await diagnosticsCreateSession(
          {
            productId: args.productId,
            targetUserId: args.targetUserId,
            targetAnonymousId: args.targetAnonymousId,
            collectionLevel: args.collectionLevel ?? 'debug',
            captureLogs: true,
            captureNetwork: true,
            maxDurationMinutes: 60,
          },
          opts
        );
      } catch (err) {
        sessionError = err instanceof Error ? err.message : String(err);
      }
    }

    // Step 3: build markdown summary
    const lines: string[] = [
      `# Debug Pack — ${args.productId}`,
      `**Generated:** ${generatedAt}`,
      args.reason ? `**Reason:** ${args.reason}` : '',
      '',
      `## Error Clusters (${clusters.length})`,
    ];

    if (clusterError) {
      lines.push(`> ⚠️ Cluster fetch failed: ${clusterError}`);
    } else if (clusters.length === 0) {
      lines.push('No error clusters found in the requested time range.');
    } else {
      for (const c of clusters.slice(0, 10)) {
        lines.push(
          `- **[${c.severity.toUpperCase()}]** \`${c.id}\` — ${c.totalCount} events` +
            ` | platform: ${c.platform} | module: ${c.module}` +
            ` | last seen: ${c.lastSeenAt}` +
            (c.sampleMessage ? ` | "${c.sampleMessage}"` : '')
        );
      }
      if (clusters.length > 10) lines.push(`… and ${clusters.length - 10} more clusters`);
    }

    lines.push('');
    lines.push('## Diagnostics Session');
    if (!wantsSession) {
      lines.push('No target user specified — diagnostics session not created.');
    } else if (sessionError) {
      lines.push(`> ⚠️ Session creation failed: ${sessionError}`);
    } else if (session) {
      lines.push(`- **Session ID:** ${session.id}`);
      lines.push(`- **Status:** ${session.status}`);
      lines.push(`- **Expires:** ${session.expiresAt}`);
    }

    return {
      productId: args.productId,
      generatedAt,
      reason: args.reason,
      clusterCount: clusters.length,
      clusterError,
      clusters: clusters.slice(0, 10),
      session: session ?? null,
      sessionError,
      summary: lines.filter(l => l !== '').join('\n'),
    };
  },
});
