import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  Patch,
  Post,
  Query,
  UploadedFile,
  UseGuards,
  UseInterceptors,
} from '@nestjs/common';
import { ApiBearerAuth, ApiConsumes, ApiTags } from '@nestjs/swagger';
import { MenuService } from './menu.service';
import { CreateMenuDto, GetMenuDto, QueryMenuDto, UpdateMenuDto, UploadCoverDto } from './dto';
import { JwtGuard } from '@/common/guards';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname, basename } from 'path';
import { OSSService } from '../oss/oss.service';
import { ConfigService } from '@nestjs/config';
import * as fs from 'fs';

@Controller('menu')
@ApiTags('menu')
@ApiBearerAuth('JWT')
@UseGuards(JwtGuard)
export class MenuController {
  constructor(
    private readonly menuService: MenuService,
    private readonly oSSService: OSSService,
    private readonly configService: ConfigService,
  ) {}

  @Post()
  create(@Body() createMenuDto: CreateMenuDto) {
    return this.menuService.create(createMenuDto);
  }

  @Get()
  getAll(@Param() getMenuDto: GetMenuDto) {
    return this.menuService.findAll(getMenuDto);
  }

  @Get('detail/:id')
  getMenuDetail(@Param('id') id: string) {
    return this.menuService.findWithChild(+id);
  }

  @Get('page')
  findPagination(@Query() queryDto: QueryMenuDto) {
    return this.menuService.findPagination(queryDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.menuService.remove(+id);
  }
  @Patch(':id')
  update(@Param('id') id: string, @Body() updateMenuDto: UpdateMenuDto) {
    return this.menuService.update(+id, updateMenuDto);
  }

  @Get('level/:id')
  getLevelMenu(@Param('id') id: string) {
    return this.menuService.findLevel(+id);
  }

  @Post('cover/upload')
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(FileInterceptor('file'))
  // @UseInterceptors(
  //   FileInterceptor('file', {
  //     storage: diskStorage({
  //       destination: './uploads',
  //       filename: (req, file, cb) => {
  //         // Generating a 32 random chars long string
  //         const randomName = Array(32)
  //           .fill(null)
  //           .map(() => Math.round(Math.random() * 16).toString(16))
  //           .join('');
  //         //Calling the callback passing the random name generated with the original extension name
  //         cb(null, `${randomName}${extname(file.originalname)}`);
  //       },
  //     }),
  //   }),
  // )
  async updateCover(@Body() data: UploadCoverDto, @UploadedFile() file) {
    const result = await this.oSSService.upload(file, {
      filepath: this.configService.get('OSS_FOLDER'),
    });
    if (result && result.length > 0 && result[0].uploaded && result[0].path) {
      return this.configService.get('OSS_DOMAIN') + '/' + result[0].path;
    } else {
      return false;
    }
  }

  @Post('package/upload')
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(
    FileInterceptor('file', {
      storage: diskStorage({
        destination: './uploads_temp',
        filename: (req, file, cb) => {
          const randomName = Array(32)
            .fill(null)
            .map(() => Math.round(Math.random() * 16).toString(16))
            .join('');
          cb(null, `${randomName}${extname(file.originalname)}`);
        },
      }),
    }),
  )
  async uploadPackage(@Body() body: { type: string }, @UploadedFile() file) {
    try {
      if (!file) {
        console.error('UploadPackage: No file received');
        return false;
      }
      console.log('UploadPackage: Starting upload for', file.originalname, 'size:', file.size, 'path:', file.path);

      let folder = 'OfflineVersion';
      if (body.type === 'ga') {
        folder = 'OfflineVersion_ga';
      } else {
        folder = 'OfflineVersion';
      }
      const result = await this.oSSService.upload(file, {
        filepath: `helperCenter/${folder}`,
        filename: basename(file.originalname, extname(file.originalname)),
        isInitDateDic: false,
      });

      console.log('UploadPackage: Upload result', JSON.stringify(result));

      if (file.path) {
        fs.unlink(file.path, (err) => {
          if (err) console.error('Error deleting temp file:', err);
        });
      }

      if (result && result.length > 0 && result[0].uploaded && result[0].path) {
        return this.configService.get('OSS_DOMAIN') + '/' + result[0].path;
      } else {
        console.error('UploadPackage: Upload failed or returned invalid result');
        return false;
      }
    } catch (error) {
      console.error('UploadPackage: Exception caught', error);
      if (file && file.path) {
        fs.unlink(file.path, (err) => {
           if (err) console.error('Error deleting temp file after exception:', err);
        });
      }
      return false; // Or throw HttpException
    }
  }
}
