import {
  BadRequestException,
  Body,
  Controller,
  Logger,
  Post,
  Req,
} from '@nestjs/common';
import { CommonService } from './common.service';
import { RoleEnum } from 'api/utils/constants';
import { Roles, SkipAuth } from '../utils/decorator';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import * as fs from 'fs';
import * as path from 'path';
import { resolve } from 'path';
import { generateQiniuTempToken, generateTempToken } from 'api/utils/oss';
import { Request } from 'express';
import { UploadToken } from './dtos/upload-token.dto';
import { getUid } from 'api/utils/utils';
import { AssetsDto } from './dtos/assets.dto';
import { DownloadScreenDto } from './dtos/download-screenshot.dto';
import { ScreenshotService } from './screenshot.service';

@Controller('common')
export class CommonController {
  private readonly logger = new Logger(CommonController.name);

  constructor(
    private commonService: CommonService,
    private screenshotService: ScreenshotService,
    @InjectDataSource() private readonly dataSource: DataSource,
  ) {}

  @Post('role/list')
  @Roles(RoleEnum.Admin)
  findRoleMap() {
    return RoleEnum;
  }

  @Post('execute/sqlfile')
  @SkipAuth()
  async executeSqlfile() {
    const dir = resolve(__dirname, '../../sql');
    fs.readdir(dir, (err, fileOrDirs) => {
      if (!fileOrDirs) {
        return;
      }
      fileOrDirs.forEach((fileOrDir) => {
        const filePath = `${dir}/${fileOrDir}`;
        fs.readFile(filePath, async (err, data) => {
          data.toString();
          await this.dataSource.manager.query(data.toString());
          fs.rmSync(filePath);
        });
      });
    });
  }

  @Post('/update/assets')
  @Roles(RoleEnum.SuperAdmin)
  async updateAssets(@Body() assertsDto: AssetsDto) {
    const { name, content } = assertsDto;
    const asset = await this.commonService.findAssets(name);
    if (asset) {
      return this.commonService.update(asset.id, {
        content: JSON.stringify(content),
      });
    }
    return this.commonService.save({
      ...assertsDto,
      content: JSON.stringify(assertsDto.content),
    });
  }

  @Post('/upload/token')
  @Roles(RoleEnum.SuperAdmin)
  async uploadToken() {
    try {
      return await generateTempToken();
    } catch {
      throw new BadRequestException('临时授权失败');
    }
  }

  @Post('/upload/qiniu/token')
  async uploadQiniuToken(
    @Req() req: Request,
    @Body() uploadToken: UploadToken,
  ) {
    const uid = getUid(req);
    const key = uploadToken.key;
    try {
      return generateQiniuTempToken(`user/${uid}/${key}`);
    } catch {
      throw new BadRequestException('临时授权错误,文件上传失败');
    }
  }

  @Post('/download/screenshot')
  async downloadScreenShot(
    @Req() req: Request,
    @Body() downloadScreenDto: DownloadScreenDto,
  ) {
    const { imgBase64, name } = downloadScreenDto;
    const uid = getUid(req);
    const base64Data = imgBase64.replace(/^data:image\/\w+;base64,/, '');
    const buffer = Buffer.from(base64Data, 'base64');
    const filename = `${name}${uid}.png`;
    fs.writeFileSync(
      path.join(__dirname, '../../screenshot', filename),
      buffer,
    );
    const filePath = `${filename}`;
    const result = await this.screenshotService.find({
      name: filePath,
    });
    if (result) {
      await this.screenshotService.update(result.id, {});
    } else {
      await this.screenshotService.save({
        name: filePath,
      });
    }
    return filePath;
  }
}
