/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Crash-Triggered Auto Sessions — Remote Diagnostics Phase 4
 * Automatically start debug sessions when crashes are detected.
 */

import type { FastifyInstance } from 'fastify';
import type { DebugSessionDoc } from './types.js';
import { createSession } from './repository.js';
import { bus } from '../../lib/event-bus.js';
import { randomUUID } from 'node:crypto';

export interface CrashReport {
  productId: string;
  userId?: string;
  anonymousId?: string;
  deviceId: string;
  sessionId: string;
  timestamp: string;
  errorType: string;
  errorMessage: string;
  stackTrace?: string;
  breadcrumbs: Array<{
    timestamp: string;
    category: string;
    message: string;
  }>;
  deviceState: {
    memoryUsage: number;
    batteryLevel?: number;
    osVersion: string;
    appVersion: string;
  };
}

export interface AutoSessionConfig {
  enabled: boolean;
  preCrashContextSeconds: number; // How much history to capture (default: 60)
  collectionLevel: 'standard' | 'debug' | 'trace';
  captureScreenshots: boolean;
  maxDurationMinutes: number;
  cooldownMinutes: number; // Prevent spam
}

const CRASH_COOLDOWN_MS = 5 * 60 * 1000; // 5 minutes between auto-sessions per device
const recentCrashes = new Map<string, number>(); // deviceId -> lastCrashTimestamp

/**
 * Handle incoming crash report and auto-start debug session if configured.
 */
export async function handleCrashReport(
  crash: CrashReport,
  config: AutoSessionConfig,
  adminUserId: string
): Promise<{ session?: DebugSessionDoc; created: boolean; reason?: string }> {
  if (!config.enabled) {
    return { created: false, reason: 'Auto-sessions disabled' };
  }

  // Check cooldown
  const lastCrash = recentCrashes.get(crash.deviceId);
  if (lastCrash && Date.now() - lastCrash < config.cooldownMinutes * 60 * 1000) {
    return { created: false, reason: 'Cooldown active' };
  }

  // Record this crash
  recentCrashes.set(crash.deviceId, Date.now());

  // Clean up old entries (devices not seen in 1 hour)
  const oneHourAgo = Date.now() - 60 * 60 * 1000;
  for (const [deviceId, timestamp] of recentCrashes) {
    if (timestamp < oneHourAgo) {
      recentCrashes.delete(deviceId);
    }
  }

  // Create auto-session
  const now = new Date().toISOString();
  const expiresAt = new Date(Date.now() + config.maxDurationMinutes * 60 * 1000).toISOString();

  const session: DebugSessionDoc = {
    id: `ds_${randomUUID().replace(/-/g, '')}`,
    productId: crash.productId,
    targetUserId: crash.userId,
    targetAnonymousId: crash.anonymousId,
    targetDeviceId: crash.deviceId,
    targetSessionId: crash.sessionId,
    status: 'active',
    collectionLevel: config.collectionLevel,
    captureLogs: true,
    captureNetwork: true,
    captureScreenshots: config.captureScreenshots,
    screenshotOnError: true,
    maxDurationMinutes: config.maxDurationMinutes,
    createdAt: now,
    updatedAt: now,
    startedAt: now,
    expiresAt,
    logCount: 0,
    traceCount: 0,
    screenshotCount: 0,
    createdBy: adminUserId,
  };

  await createSession(session);

  // Emit event for notifications
  bus.emit('diagnostics.session.created', {
    sessionId: session.id,
    productId: crash.productId,
    targetUserId: crash.userId,
    targetAnonymousId: crash.anonymousId,
    targetDeviceId: crash.deviceId,
    createdBy: adminUserId,
  });

  return { session, created: true };
}

/**
 * Fastify route handler for crash report ingestion.
 */
export async function crashTriggerRoutes(app: FastifyInstance): Promise<void> {
  // Client crash reporting endpoint
  app.post('/diagnostics/crash-report', async (req, reply) => {
    // Require authentication
    if (!req.jwtPayload?.sub) {
      return reply.status(401).send({ error: 'Authentication required' });
    }

    const crash = req.body as CrashReport;

    // Validate required fields
    if (!crash.productId || !crash.deviceId || !crash.errorType) {
      return reply.status(400).send({
        error: 'Missing required fields: productId, deviceId, errorType',
      });
    }

    // Default auto-session config
    const config: AutoSessionConfig = {
      enabled: true,
      preCrashContextSeconds: 60,
      collectionLevel: 'debug',
      captureScreenshots: true,
      maxDurationMinutes: 30,
      cooldownMinutes: 5,
    };

    const result = await handleCrashReport(crash, config, req.jwtPayload.sub);

    if (result.created && result.session) {
      reply.status(201);
      return {
        accepted: true,
        sessionId: result.session.id,
        message: 'Crash report accepted, debug session started',
      };
    } else {
      reply.status(202);
      return {
        accepted: true,
        sessionId: null,
        reason: result.reason,
        message: 'Crash report accepted, but no session created',
      };
    }
  });

  // Get crash-triggered sessions for a product (admin only)
  app.get('/diagnostics/crash-sessions', async req => {
    // Import requireRole inline to avoid circular dependency
    const { requireRole } = await import('../../lib/auth.js');
    await requireRole(req, 'admin');

    const { productId } = req.query as { productId?: string };
    if (!productId) {
      return { sessions: [] };
    }

    // Query for sessions that were created from crash triggers
    // These are identified by the event bus events
    return { sessions: [] }; // Placeholder - would query by trigger metadata
  });
}
