import {
  BadRequestException,
  Body,
  Controller,
  Get,
  Put,
  Query,
  Post,
  Req,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

import { Public } from '../../modules/auth/public.decorator';
import { ApiBody, ApiOperation, ApiTags } from '@nestjs/swagger';
import { MobileProfileService } from './mobile-profile.service';
import { EditMobileProfileDto } from './mobile-profile.request.dto';
import { Request } from 'express';
import { MobileSessionService } from '../common/mobile-session.service';

@ApiTags('mobile_profile')
@Controller('mobile/profile')
export class MobileProfileController {
  constructor(
    private readonly mobileProfileService: MobileProfileService,
    private readonly mobileSessionService: MobileSessionService,
  ) { }

  @Public()
  @Get('editable_profile')
  async getEditableProfile(@Query('userId') userIdRaw: string) {
    const userId = Number(userIdRaw);

    if (!Number.isFinite(userId) || userId <= 0) {
      throw new BadRequestException('userId must be a positive number');
    }

    return this.mobileProfileService.getEditableProfile(userId);
  }

  @Public()
  @Put('editable_profile')
  @ApiOperation({ summary: 'Edit mobile profile (seeker)' })
  @ApiBody({ type: EditMobileProfileDto })
  async editEditableProfile(
    @Body() body: EditMobileProfileDto,
    @Query('userId') userIdRaw?: string,
  ) {
    // Client calls: PUT /mobile/profile/editable_profile?userId=3679
    // Server-side DTO expects userId in the body; support both.
    if (userIdRaw && (!body?.userId || Number(body.userId) === 0)) {
      const parsed = Number(userIdRaw);
      if (Number.isFinite(parsed) && parsed > 0) body.userId = parsed;
    }

    return this.mobileProfileService.editProfile(body);
  }

  @Public()
  @Put('edit')
  @ApiOperation({ summary: 'Edit mobile profile (seeker) - legacy' })
  @ApiBody({ type: EditMobileProfileDto })
  async editProfile(@Body() body: EditMobileProfileDto) {
    return this.mobileProfileService.editProfile(body);
  }

  @Public()
  @Post('/logout')
  @ApiOperation({ summary: 'Logout user (mobile)' })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        userId: { type: 'number', example: 123 },
        userType: { type: 'string', example: 'seeker' },
      },
    },
  })
  async logout(
    @Req() req: Request,
    @Body() body: { userId?: number; userType?: string },
  ) {
    let userId = body.userId;
    let userType = body.userType;
    const sessionToken = this.mobileSessionService.extractSessionToken(req);

    if (sessionToken) {
      try {
        const user = await this.mobileSessionService.getUserFromSessionToken(sessionToken);
        if (user) {
          if (!userId) userId = user.id;
          if (!userType) userType = user.role;
        }
      } catch (err) {
        // Continue logout even if token is invalid or expired
      }
    }

    await this.mobileProfileService.logout(
      userId,
      userType,
      (req.headers['x-forwarded-for'] as any) || req.ip || ((req.connection as any) && (req.connection as any).remoteAddress) || null,
      (req.headers['user-agent'] as string) || '',
      sessionToken,
    );

    return new Promise((resolve, reject) => {
      req.session.destroy((err) => {
        if (err) {
          reject(
            new HttpException(
              'Logout failed',
              HttpStatus.INTERNAL_SERVER_ERROR,
            ),
          );
        } else {
          resolve({ message: 'Logged out successfully' });
        }
      });
    });
  }
}
