/**
 * @ai-summary Fastify route handlers for onboarding API
 * @ai-context HTTP request/response handling for onboarding workflow
 */

import { FastifyRequest, FastifyReply } from 'fastify';
import { OnboardingService } from '../domain/onboarding.service';
import { UserPreferencesRepository } from '../../../core/user-preferences/data/user-preferences.repository';
import { UserProfileRepository } from '../../user-profile/data/user-profile.repository';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';
import { SavePreferencesInput } from './onboarding.validation';

interface AuthenticatedRequest extends FastifyRequest {
  user: {
    sub: string;
    [key: string]: unknown;
  };
}

export class OnboardingController {
  private onboardingService: OnboardingService;

  constructor() {
    const userPreferencesRepo = new UserPreferencesRepository(pool);
    const userProfileRepo = new UserProfileRepository(pool);
    this.onboardingService = new OnboardingService(userPreferencesRepo, userProfileRepo);
  }

  /**
   * POST /api/onboarding/preferences
   * Save user preferences during onboarding
   */
  async savePreferences(
    request: FastifyRequest<{ Body: SavePreferencesInput }>,
    reply: FastifyReply
  ) {
    try {
      const auth0Sub = (request as AuthenticatedRequest).user.sub;

      const preferences = await this.onboardingService.savePreferences(
        auth0Sub,
        request.body
      );

      return reply.code(200).send({
        success: true,
        preferences,
      });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('Error in savePreferences controller', {
        error,
        userId: (request as AuthenticatedRequest).user?.sub,
      });

      if (errorMessage === 'User profile not found') {
        return reply.code(404).send({
          error: 'Not Found',
          message: 'User profile not found',
        });
      }

      return reply.code(500).send({
        error: 'Internal server error',
        message: 'Failed to save preferences',
      });
    }
  }

  /**
   * POST /api/onboarding/complete
   * Mark onboarding as complete
   */
  async completeOnboarding(request: FastifyRequest, reply: FastifyReply) {
    try {
      const auth0Sub = (request as AuthenticatedRequest).user.sub;

      const completedAt = await this.onboardingService.completeOnboarding(auth0Sub);

      return reply.code(200).send({
        success: true,
        completedAt: completedAt.toISOString(),
      });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('Error in completeOnboarding controller', {
        error,
        userId: (request as AuthenticatedRequest).user?.sub,
      });

      if (errorMessage === 'User profile not found') {
        return reply.code(404).send({
          error: 'Not Found',
          message: 'User profile not found',
        });
      }

      return reply.code(500).send({
        error: 'Internal server error',
        message: 'Failed to complete onboarding',
      });
    }
  }

  /**
   * GET /api/onboarding/status
   * Get current onboarding status
   */
  async getStatus(request: FastifyRequest, reply: FastifyReply) {
    try {
      const auth0Sub = (request as AuthenticatedRequest).user.sub;

      const status = await this.onboardingService.getOnboardingStatus(auth0Sub);

      return reply.code(200).send({
        preferencesSet: status.preferencesSet,
        onboardingCompleted: status.onboardingCompleted,
        onboardingCompletedAt: status.onboardingCompletedAt
          ? status.onboardingCompletedAt.toISOString()
          : null,
      });
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Unknown error';
      logger.error('Error in getStatus controller', {
        error,
        userId: (request as AuthenticatedRequest).user?.sub,
      });

      if (errorMessage === 'User profile not found') {
        return reply.code(404).send({
          error: 'Not Found',
          message: 'User profile not found',
        });
      }

      return reply.code(500).send({
        error: 'Internal server error',
        message: 'Failed to get onboarding status',
      });
    }
  }
}
