import { BadRequestException, Controller, Get, Param, Post, Req, Res, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { FileInterceptor } from '@nestjs/platform-express';
import { existsSync, mkdirSync } from 'fs';
import { diskStorage } from 'multer';
import { extname } from 'path';
import { GetUser } from 'src/auth/dto/get-user.decorator';
import { FileUploadService } from './file-upload.service';
import * as fs from 'fs';
import * as archiver from 'archiver';
import * as path from 'path';

export function createFolders(filePath: string) {


    const splitPath = filePath.split('/');
    splitPath.reduce((path, subPath) => {
        let currentPath;
        if (subPath != '.') {
            currentPath = path + '/' + subPath;

            if (!existsSync(currentPath)) {
                mkdirSync(currentPath);
            }
        }
        else {
            currentPath = subPath;
        }
        return currentPath

    }, '')
}


@Controller('file-upload')

export class FileUploadController {
    constructor(
        private iservice: FileUploadService
    ) {
    }

    @Post('user-documents/:id')
    @UseInterceptors(FileInterceptor('file', {
        storage: diskStorage({
            destination: (req, res, cb) => {
                const filePath: string = './uploads/userDocuments/'+req.params.id;
                createFolders(filePath);
                return cb(null, filePath);
            },
            filename: (req, file, cb) => {
                console.log('===here===file upload==');
                const randomName = Array(32).fill(null).map(() => (Math.round(Math.random() * 16)).toString(16)).join('');
                return cb(null, `${randomName}${extname(file.originalname)}`);
            }
        })
    }))
    userDoc(@UploadedFile() file) {
        return { fileName: file.filename, filePath: file.path };
    }
   
    
    @Post('Bank-documents/:id')
    @UseInterceptors(FileInterceptor('file', {
        storage: diskStorage({
            // destination: './uploads/cars',
            destination: (req, res, cb) => {
                // console.log(req);
                
                const filePath: string = './uploads/BankDocuments/'+req.params.id;
                createFolders(filePath);
                return cb(null, filePath);
            },
            filename: (req, file, cb) => {
                console.log('===here===file upload==');
                const randomName = Array(32).fill(null).map(() => (Math.round(Math.random() * 16)).toString(16)).join('');
                return cb(null, `${randomName}${extname(file.originalname)}`);
            }
        })
    }))
    bankDoc(@UploadedFile() file) {
        if (!file) {
            return { error: 'No file uploaded.' };
        }
        //To return the size of the document in kb
        const fileSizeKB = Math.ceil(file.size / 1024);
        return { fileName: file.filename, filePath: file.path, fileSizeKB };
    }

    
    @Get('Bank-Documents/:id/:imgpath')
    getBankDocuments(
        @Param('imgpath') image: string,
        @Param('id') id: string,
        @Res() res,
        @Req() req,

    ) {
        return res.sendFile(image, { root: './uploads/BankDocuments/'+id}, function (err) {
            if (err) {
                console.log(err.status);
                res.status(err.status).end();
            }
        })
    }

    @Get('user-Documents/:id/:imgpath')
    getUserDocuments(
        @Param('imgpath') image: string,
        @Param('id') id: string,
        @Res() res,
        @Req() req,

    ) {
        return res.sendFile(image, { root: './uploads/userDocuments/'+id}, function (err) {
            if (err) {
                console.log(err.status);
                res.status(err.status).end();
            }
        })
    }

    

    @Get('Bank-Documents-Arc/:id')
    async getBankDocumentsAsZip(
        @Param('id') id: string,
        @Res() res,
        @Req() req,
      ) {
        const folderPath = path.join('./uploads/BankDocuments', id);
        if (!fs.existsSync(folderPath)) {
          res.status(404).send({ error: 'File not found' });
          return;
        }
      
        const zipFileName = id + '.zip';
        const zipPath = path.join('./uploads/BankDocuments', zipFileName);
      
        // Create a new archive
        const archive = archiver('zip', {
          zlib: { level: 9 } // Set compression level (optional)
        });
      
        // Create a write stream to the zip file
        const output = fs.createWriteStream(zipPath);
      
        // Pipe the archive to the write stream
        archive.pipe(output);
      
        // Add the entire folder to the archive
        archive.directory(folderPath, id);
      
        // Finalize the archive
        await archive.finalize();
      
        // Set the appropriate headers for downloading the zip file
        res.attachment(zipFileName);
        res.setHeader('Content-Type', 'application/zip');
      
        // Stream the zip file to the response
        const readStream = fs.createReadStream(zipPath);
        readStream.pipe(res);
      
        // Remove the temporary zip file once it's streamed
        readStream.on('end', () => {
          fs.unlinkSync(zipPath);
        });
      
        // Handle any errors that occur during the archiving process
        archive.on('error', function (err) {
          console.log(err);
          res.status(500).send({ error: 'Failed to create the zip file' });
        });


}
}