/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Performance Profile Routes — Remote Diagnostics
 * Ingest and query performance profiling data.
 */

import type { FastifyInstance } from 'fastify';
import { randomUUID } from 'node:crypto';
import { requireRole } from '../../lib/auth.js';
import { IngestProfileSchema, QueryProfilesSchema } from './performance-profile-types.js';
import {
  ingestProfile,
  getProfile,
  queryProfiles,
  listProfilesForProduct,
} from './performance-profile-repository.js';
import { getRequestProductId } from '../../lib/request-context.js';
import { NotFoundError, BadRequestError } from '../../lib/errors.js';
import type { PerformanceProfileDoc } from './performance-profile-types.js';

export async function performanceProfileRoutes(app: FastifyInstance): Promise<void> {
  // Ingest performance profile (client endpoint)
  app.post('/diagnostics/sessions/:id/profiles', async (req, reply) => {
    const { id: sessionId } = req.params as { id: string };
    const productId = getRequestProductId(req);

    // Require authentication
    if (!req.jwtPayload?.sub) {
      return reply.status(401).send({ error: 'Authentication required' });
    }

    // Validate request body
    const result = IngestProfileSchema.safeParse(req.body);
    if (!result.success) {
      return reply.status(400).send({
        error: 'Invalid profile data',
        details: result.error.issues,
      });
    }

    const { profileType, platform, deviceInfo, profile } = result.data;

    // Validate session ID matches
    if (result.data.sessionId !== sessionId) {
      throw new BadRequestError('Session ID mismatch');
    }

    // Create profile document
    const now = new Date().toISOString();
    const profileId = `prof_${randomUUID().replace(/-/g, '')}`;

    const doc: PerformanceProfileDoc = {
      id: `pp_${randomUUID().replace(/-/g, '')}`,
      pk: `${productId}:${sessionId}`,
      sessionId,
      productId,
      profileId,
      profileType,
      platform,
      deviceInfo,
      profile: profile as unknown as PerformanceProfileDoc['profile'],
      startedAt: now,
      endedAt: now,
      createdAt: now,
      ttl: 7 * 86400, // 7 days
    };

    const { id } = await ingestProfile(doc);

    app.log.info(`Ingested ${profileType} profile ${profileId} for session ${sessionId}`);

    reply.status(201);
    return {
      id,
      profileId,
      sessionId,
      profileType,
    };
  });

  // Get specific profile (admin only)
  app.get('/diagnostics/sessions/:id/profiles/:profileId', async (req, reply) => {
    await requireRole(req, 'admin');

    const { id: sessionId, profileId } = req.params as { id: string; profileId: string };
    const productId = getRequestProductId(req);

    const profile = await getProfile(productId, sessionId, profileId);
    if (!profile) {
      throw new NotFoundError('Performance profile not found');
    }

    return {
      id: profile.id,
      profileId: profile.profileId,
      profileType: profile.profileType,
      platform: profile.platform,
      deviceInfo: profile.deviceInfo,
      profile: profile.profile,
      startedAt: profile.startedAt,
      endedAt: profile.endedAt,
    };
  });

  // Query profiles for a session (admin only)
  app.get('/diagnostics/sessions/:id/profiles', async (req, reply) => {
    await requireRole(req, 'admin');

    const { id: sessionId } = req.params as { id: string };
    const productId = getRequestProductId(req);
    const query = QueryProfilesSchema.parse(req.query);

    const result = await queryProfiles(productId, sessionId, query);

    return {
      profiles: result.profiles.map(p => ({
        id: p.id,
        profileId: p.profileId,
        profileType: p.profileType,
        platform: p.platform,
        deviceInfo: p.deviceInfo,
        startedAt: p.startedAt,
        endedAt: p.endedAt,
      })),
      total: result.total,
    };
  });

  // List all profiles for product (admin only)
  app.get('/diagnostics/profiles', async (req, reply) => {
    await requireRole(req, 'admin');

    const productId = getRequestProductId(req);
    const query = req.query as { limit?: string };
    const limit = Math.min(parseInt(query?.limit || '50', 10), 100);

    const profiles = await listProfilesForProduct(productId, limit);

    return {
      profiles: profiles.map(p => ({
        id: p.id,
        profileId: p.profileId,
        sessionId: p.sessionId,
        profileType: p.profileType,
        platform: p.platform,
        deviceInfo: p.deviceInfo,
        startedAt: p.startedAt,
      })),
    };
  });
}
