/**
 * @ai-summary Fastify route handlers for user profile API
 * @ai-context HTTP request/response handling with user authentication
 */

import { FastifyRequest, FastifyReply } from 'fastify';
import { UserProfileService } from '../domain/user-profile.service';
import { UserProfileRepository } from '../data/user-profile.repository';
import { AdminRepository } from '../../admin/data/admin.repository';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';
import {
  UpdateProfileInput,
  updateProfileSchema,
  RequestDeletionInput,
  requestDeletionSchema,
} from './user-profile.validation';

export class UserProfileController {
  private userProfileService: UserProfileService;

  constructor() {
    const repository = new UserProfileRepository(pool);
    const adminRepository = new AdminRepository(pool);
    this.userProfileService = new UserProfileService(repository);
    this.userProfileService.setAdminRepository(adminRepository);
  }

  /**
   * GET /api/user/profile - Get current user's profile
   */
  async getProfile(request: FastifyRequest, reply: FastifyReply) {
    try {
      const auth0Sub = request.userContext?.userId;

      if (!auth0Sub) {
        return reply.code(401).send({
          error: 'Unauthorized',
          message: 'User context missing',
        });
      }

      // Get user data from Auth0 token
      const auth0User = {
        sub: auth0Sub,
        email: (request as any).user?.email || request.userContext?.email || '',
        name: (request as any).user?.name,
      };

      // Get or create profile
      const profile = await this.userProfileService.getOrCreateProfile(
        auth0Sub,
        auth0User
      );

      return reply.code(200).send(profile);
    } catch (error: any) {
      logger.error('Error getting user profile', {
        error: error.message,
        userId: request.userContext?.userId,
      });

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

  /**
   * PUT /api/user/profile - Update user profile
   */
  async updateProfile(
    request: FastifyRequest<{ Body: UpdateProfileInput }>,
    reply: FastifyReply
  ) {
    try {
      const auth0Sub = request.userContext?.userId;

      if (!auth0Sub) {
        return reply.code(401).send({
          error: 'Unauthorized',
          message: 'User context missing',
        });
      }

      // Validate request body
      const validation = updateProfileSchema.safeParse(request.body);
      if (!validation.success) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: 'Invalid request body',
          details: validation.error.errors,
        });
      }

      const updates = validation.data;

      // Update profile
      const profile = await this.userProfileService.updateProfile(
        auth0Sub,
        updates
      );

      return reply.code(200).send(profile);
    } catch (error: any) {
      logger.error('Error updating user profile', {
        error: error.message,
        userId: request.userContext?.userId,
      });

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

      if (error.message.includes('At least one field')) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: error.message,
        });
      }

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

  /**
   * POST /api/user/delete - Request account deletion
   */
  async requestDeletion(
    request: FastifyRequest<{ Body: RequestDeletionInput }>,
    reply: FastifyReply
  ) {
    try {
      const auth0Sub = request.userContext?.userId;

      if (!auth0Sub) {
        return reply.code(401).send({
          error: 'Unauthorized',
          message: 'User context missing',
        });
      }

      // Validate request body
      const validation = requestDeletionSchema.safeParse(request.body);
      if (!validation.success) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: 'Invalid request body',
          details: validation.error.errors,
        });
      }

      const { confirmationText } = validation.data;

      // Request deletion (user is already authenticated via JWT)
      const profile = await this.userProfileService.requestDeletion(
        auth0Sub,
        confirmationText
      );

      const deletionStatus = this.userProfileService.getDeletionStatus(profile);

      return reply.code(200).send({
        message: 'Account deletion requested successfully',
        deletionStatus,
      });
    } catch (error: any) {
      logger.error('Error requesting account deletion', {
        error: error.message,
        userId: request.userContext?.userId,
      });

      if (error.message.includes('Invalid confirmation')) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: 'Confirmation text must be exactly "DELETE"',
        });
      }

      if (error.message.includes('already requested')) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: 'Account deletion already requested',
        });
      }

      if (error.message.includes('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 request account deletion',
      });
    }
  }

  /**
   * POST /api/user/cancel-deletion - Cancel account deletion
   */
  async cancelDeletion(request: FastifyRequest, reply: FastifyReply) {
    try {
      const auth0Sub = request.userContext?.userId;

      if (!auth0Sub) {
        return reply.code(401).send({
          error: 'Unauthorized',
          message: 'User context missing',
        });
      }

      // Cancel deletion
      const profile = await this.userProfileService.cancelDeletion(auth0Sub);

      return reply.code(200).send({
        message: 'Account deletion canceled successfully',
        profile,
      });
    } catch (error: any) {
      logger.error('Error canceling account deletion', {
        error: error.message,
        userId: request.userContext?.userId,
      });

      if (error.message.includes('no deletion request')) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: 'No deletion request pending',
        });
      }

      if (error.message.includes('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 cancel account deletion',
      });
    }
  }

  /**
   * GET /api/user/deletion-status - Get deletion status
   */
  async getDeletionStatus(request: FastifyRequest, reply: FastifyReply) {
    try {
      const auth0Sub = request.userContext?.userId;

      if (!auth0Sub) {
        return reply.code(401).send({
          error: 'Unauthorized',
          message: 'User context missing',
        });
      }

      // Get user data from Auth0 token
      const auth0User = {
        sub: auth0Sub,
        email: (request as any).user?.email || request.userContext?.email || '',
        name: (request as any).user?.name,
      };

      // Get or create profile
      const profile = await this.userProfileService.getOrCreateProfile(
        auth0Sub,
        auth0User
      );

      const deletionStatus = this.userProfileService.getDeletionStatus(profile);

      return reply.code(200).send(deletionStatus);
    } catch (error: any) {
      logger.error('Error getting deletion status', {
        error: error.message,
        userId: request.userContext?.userId,
      });

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