import { Controller, Get, Patch, Body, BadRequestException } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { BaseController } from '../../common/base';
import { UsersService } from './users.service';
import { CreateUserDto, UpdateUserDto } from './dto/user.dto';
import { CurrentUser, Roles } from '../../common/decorators';
import {
  ApiResponse,
  createSuccessResponse,
} from '../../common/types/api-response.type';
import { User } from '@prisma/client';

import { plainToInstance } from 'class-transformer';
import { UserResponseDto } from './dto/user.dto';

interface AuthenticatedUser {
  id: string;
  email: string;
  roles: string[];
  permissions: string[];
}

@ApiTags('Users')
@ApiBearerAuth()
@Controller('users')
export class UsersController extends BaseController<
  User,
  CreateUserDto,
  UpdateUserDto
> {
  constructor(private readonly usersService: UsersService) {
    super(usersService, 'User');
  }

  @Get('me')
  async getMe(
    @CurrentUser() user: AuthenticatedUser,
  ): Promise<ApiResponse<UserResponseDto>> {
    const fullUser = await this.usersService.findOneWithRoles(user.id);
    return createSuccessResponse(
      plainToInstance(UserResponseDto, fullUser),
      'User profile retrieved successfully',
    );
  }

  @Patch('me')
  async updateProfile(
    @CurrentUser() user: AuthenticatedUser,
    @Body() body: { firstName?: string; lastName?: string },
  ): Promise<ApiResponse<UserResponseDto>> {
    const updated = await this.usersService.update(user.id, {
      firstName: body.firstName,
      lastName: body.lastName,
    });
    return createSuccessResponse(
      plainToInstance(UserResponseDto, updated),
      'Profil başarıyla güncellendi',
    );
  }

  @Patch('me/password')
  async changePassword(
    @CurrentUser() user: AuthenticatedUser,
    @Body() body: { currentPassword: string; newPassword: string },
  ): Promise<ApiResponse<{ success: boolean }>> {
    if (!body.currentPassword || !body.newPassword) {
      throw new BadRequestException('Mevcut ve yeni şifre gerekli');
    }
    if (body.newPassword.length < 8) {
      throw new BadRequestException('Yeni şifre en az 8 karakter olmalı');
    }
    const fullUser = await this.usersService.findOne(user.id);
    if (!fullUser) throw new BadRequestException('Kullanıcı bulunamadı');

    const bcrypt = await import('bcrypt');
    const isValid = await bcrypt.compare(body.currentPassword, fullUser.password);
    if (!isValid) {
      throw new BadRequestException('Mevcut şifre hatalı');
    }

    await this.usersService.update(user.id, { password: body.newPassword });
    return createSuccessResponse({ success: true }, 'Şifre başarıyla güncellendi');
  }

  // Override create to require admin role
  @Roles('admin')
  async create(
    ...args: Parameters<
      BaseController<User, CreateUserDto, UpdateUserDto>['create']
    >
  ) {
    return super.create(...args);
  }

  // Override delete to require admin role
  @Roles('admin')
  async delete(
    ...args: Parameters<
      BaseController<User, CreateUserDto, UpdateUserDto>['delete']
    >
  ) {
    return super.delete(...args);
  }
}
