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

// ── Handoff schemas ────────────────────────────────────────────────
export const RegressionWatchInputSchema = z.object({
  productId: z.string().min(1).describe('Product ID to monitor'),
  severityThreshold: z
    .enum(['error', 'warning', 'info'])
    .optional()
    .default('error')
    .describe('Minimum severity to trigger diagnostics'),
  clusterAgeMinutes: z
    .number()
    .int()
    .min(5)
    .max(1440)
    .optional()
    .default(60)
    .describe('Only consider clusters newer than this many minutes'),
  maxSessionsToCreate: z
    .number()
    .int()
    .min(1)
    .max(10)
    .optional()
    .default(3)
    .describe('Maximum diagnostics sessions to create'),
  dryRun: z
    .boolean()
    .optional()
    .default(false)
    .describe('If true, only report what would be done without creating sessions'),
});

export const RegressionWatchResultSchema = z.object({
  runId: z.string(),
  productId: z.string(),
  clustersFound: z.number(),
  clustersAboveThreshold: z.number(),
  sessionsCreated: z.number(),
  sessionIds: z.array(z.string()),
  dryRun: z.boolean(),
  summary: z.string(),
});

export type RegressionWatchInput = z.infer<typeof RegressionWatchInputSchema>;
export type RegressionWatchResult = z.infer<typeof RegressionWatchResultSchema>;

// ── Pipeline implementation ───────────────────────────────────────────
export async function runRegressionWatchPipeline(
  input: RegressionWatchInput,
  req: McpToolRequest
): Promise<RegressionWatchResult> {
  const runId = `regression-watch-${Date.now()}`;
  const { productId, severityThreshold, clusterAgeMinutes, maxSessionsToCreate, dryRun } = input;

  req.log.info(
    { runId, productId, severityThreshold, clusterAgeMinutes, dryRun },
    'Starting regression watch pipeline'
  );

  try {
    // Step 1: Find recent clusters above severity threshold
    const clustersResponse = await telemetryClusters(
      {
        platform: productId,
        from: new Date(Date.now() - clusterAgeMinutes * 60 * 1000).toISOString(),
        to: new Date().toISOString(),
      },
      { token: req.headers.authorization?.replace('Bearer ', '') || '', requestId: req.id }
    );

    const clusters = clustersResponse.clusters || [];
    const clustersAboveThreshold = clusters.filter(
      (c: { severity: string }) => c.severity === severityThreshold
    );

    req.log.info(
      { runId, totalClusters: clusters.length, aboveThreshold: clustersAboveThreshold.length },
      'Cluster analysis complete'
    );

    if (clustersAboveThreshold.length === 0) {
      return {
        runId,
        productId,
        clustersFound: clusters.length,
        clustersAboveThreshold: 0,
        sessionsCreated: 0,
        sessionIds: [],
        dryRun,
        summary: `No clusters found at or above ${severityThreshold} severity in the last ${clusterAgeMinutes} minutes.`,
      };
    }

    // Step 2: Create diagnostics sessions for representative clusters
    const sessionsToCreate = Math.min(clustersAboveThreshold.length, maxSessionsToCreate);
    const sessionIds: string[] = [];
    let sessionsCreated = 0;

    for (let i = 0; i < sessionsToCreate; i++) {
      const cluster = clustersAboveThreshold[i];

      if (dryRun) {
        req.log.info(
          { runId, clusterId: cluster.id, pk: cluster.pk },
          '[DRY RUN] Would create diagnostics session'
        );
        sessionIds.push(`dry-run-session-${i + 1}`);
        sessionsCreated++;
        continue;
      }

      try {
        // Extract target from cluster - use fingerprint as identifier
        const sessionResponse = await diagnosticsCreateSession(
          {
            productId,
            targetUserId: 'system', // Use system user for cluster-based diagnostics
            collectionLevel: 'trace',
            captureLogs: true,
            captureNetwork: true,
            maxDurationMinutes: 30,
          },
          { token: req.headers.authorization?.replace('Bearer ', '') || '', requestId: req.id }
        );

        sessionIds.push(sessionResponse.id);
        sessionsCreated++;

        req.log.info(
          { runId, clusterId: cluster.id, sessionId: sessionResponse.id },
          'Created diagnostics session for cluster'
        );
      } catch (sessionError) {
        req.log.warn(
          {
            runId,
            clusterId: cluster.id,
            pk: cluster.pk,
            error: sessionError instanceof Error ? sessionError.message : String(sessionError),
          },
          'Failed to create diagnostics session for cluster (continuing)'
        );
        // Continue with next cluster instead of failing entire pipeline
      }
    }

    const summary = dryRun
      ? `[DRY RUN] Would create ${sessionsToCreate} diagnostics sessions for ${clustersAboveThreshold.length} clusters at ${severityThreshold} severity.`
      : `Created ${sessionsCreated} diagnostics sessions for ${clustersAboveThreshold.length} clusters at ${severityThreshold} severity.`;

    return {
      runId,
      productId,
      clustersFound: clusters.length,
      clustersAboveThreshold: clustersAboveThreshold.length,
      sessionsCreated: dryRun ? 0 : sessionsCreated,
      sessionIds,
      dryRun,
      summary,
    };
  } catch (error) {
    req.log.error(
      { runId, productId, error: error instanceof Error ? error.message : String(error) },
      'Regression watch pipeline failed'
    );

    return {
      runId,
      productId,
      clustersFound: 0,
      clustersAboveThreshold: 0,
      sessionsCreated: 0,
      sessionIds: [],
      dryRun,
      summary: `Pipeline failed: ${error instanceof Error ? error.message : String(error)}`,
    };
  }
}
