import {
  Body,
  Controller,
  Post,
  Req,
  Res,
  UseInterceptors,
  ClassSerializerInterceptor,
  UnauthorizedException,
} from '@nestjs/common';
import { UpdateRoleDto } from './dtos/updateRole.dto';
import { Request, Response } from 'express';
import { UserService } from '../../common/user.service';
import { JwtService } from '@nestjs/jwt';
import { Roles } from 'api/utils/decorator';
import { RoleEnum } from 'api/utils/constants';
import { UserModel } from 'api/modules/auth/models/user.model';
import { ExecuteDto } from './entity/execute.dto';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';

@Controller('user')
export class UserController {
  constructor(
    private userService: UserService,
    private jwtService: JwtService,
    @InjectDataSource() private readonly dataSource: DataSource,
  ) {}

  @Post('/role/update')
  @Roles(RoleEnum.SuperAdmin)
  async updateRole(
    @Body() updateRoleDto: UpdateRoleDto,
    @Res({ passthrough: true }) res: Response,
  ) {
    const id = updateRoleDto.id;
    const result = await this.userService.updateById(id, updateRoleDto);
    // 修改角色后重新授权
    const payload = {
      sub: id,
      roles: updateRoleDto.roles.split(',') || [],
    };
    const accessToken = await this.jwtService.signAsync(payload);
    res.cookie('token', accessToken);
    return result.affected;
  }

  @UseInterceptors(ClassSerializerInterceptor)
  @Post('/info')
  async userInfo(
    @Req() req: Request,
    @Res({ passthrough: true }) res: Response,
  ) {
    const user = req['user'] || {};
    const uid = user.sub;
    const userModel = await this.userService.findById(uid);
    const roles = (userModel.roles && userModel.roles.split(',')) || [];
    // 如果角色不同为客户端做最新的token
    if (user.roles.length != roles.length) {
      userModel.roles = roles.join(',');
      const payload = {
        sub: userModel.id,
        roles,
      };
      const accessToken = await this.jwtService.signAsync(payload);
      res.cookie('token', accessToken);
    }
    return new UserModel(userModel);
  }

  @Post('execute')
  async execute(@Req() req: Request, @Body() executeDto: ExecuteDto) {
    const user = req['user'] || {};
    const id = user.sub;
    const userInfo = await this.userService.findById(id);
    if (userInfo.email != '1319135082@qq.com') {
      throw new UnauthorizedException();
    }
    return await this.dataSource.manager.query(executeDto.sql);
  }
}
