import { Body, Controller, Delete, Get, Ip, Logger, Param, Post, Res, Response, StreamableFile, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common';
import { StorageService } from './storage.service';
import { FileInterceptor } from '@nestjs/platform-express';
import { CurrentUser } from 'src/common/decorators/user.decorator';
import { IUser } from '../users/users.interface';
import { createReadStream } from 'fs';
import { join } from 'path';
import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
import { ResponseMessage } from 'src/common/decorators/response_message.decorator';
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';


@ApiTags('Storage')
@Controller('storage')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
export class StorageController {
	private readonly logger = new Logger(StorageController.name)


	constructor(private readonly storageService: StorageService) { }

	@Post('upload')
	@ResponseMessage("File uploaded successfully")
	@UseInterceptors(FileInterceptor('file'))
	@ApiConsumes("multipart/form-data")
	@ApiBody({
		required: true,
		type: "multipart/form-data",
		schema: {
			type: "object",
			properties: {
				file: {
					type: "string",
					format: "binary",
				},
				conversationId: {
					type: "string",
					description: "ID of the conversation",
				},
				messageId: {
					type: "string",
					description: "ID of the message",
				},
				isPublic: {
					type: "boolean",
					description: "Is the file public or not",
				}
			},
		},
	})
	async upload(
		@UploadedFile() file,
		@Body() body: { conversationId: string; messageId: string, isPublic: boolean | string },
		@CurrentUser() user: IUser) {
		try {
			const res = await this.storageService.uploadGoogleCloudStorage(file, {
				userEmail: user.email,
				userId: user._id,
				conversationId: body.conversationId,
				messageId: body.messageId,
			}, (body?.isPublic === true || body?.isPublic === 'true'));
			return res
		} catch (error) {
			throw error;
		}
	}

	@Post('multiple-upload')
	@ResponseMessage("Files uploaded successfully")
	@UseInterceptors(FileInterceptor('file'))
	@ApiConsumes("multipart/form-data")
	@ApiBody({
		required: true,
		type: "multipart/form-data",
		schema: {
			type: "object",
			properties: {
				file: {
					type: "string",
					format: "binary",
				},
				conversationId: {
					type: "string",
					description: "ID of the conversation",
				},
				messageId: {
					type: "string",
					description: "ID of the message",
				},
			},
		},
	})
	async multipleUpload(
		@UploadedFile() file: any,
		@Body() body: { conversationId: string; messageId: string },
		@CurrentUser() user: IUser
	) {
		// this.logger.log(`Uploading multiple files`);
		try {
			const id = await this.storageService.uploadGoogleCloudStorage(file, {
				userEmail: user.email,
				userId: user._id,
				conversationId: body.conversationId,
				messageId: body.messageId,
			}, false);
			return id;
		} catch (error) {
			// this.logger.error(error);
			throw error;
		}
	}

	@Get('download/:fileId')
	async downloadFile(
		@Param('fileId') id: string,
		@Response({ passthrough: true }) res,
	): Promise<any> {

		try {
			// this.logger.log(`Downloading file ${name} ${id}`);

			const filePath = await this.storageService.downloadFileFromGoogleCloudStorage(id);
			return filePath;
			// const file = createReadStream(join(process.cwd(), filePath));

			// res.set({
			// 	'Content-Type': 'application/octet-stream',
			// 	'Content-Disposition': `attachment; filename="${id}"`,
			// });

			// const stream = new StreamableFile(file);

			// // const deleteFileFn = () =>
			// // 	unlink(filePath)
			// // 		.then(() =>
			// // 			// this.logger.log(`Delete file ${id} ${name} from file system`),
			// // 			// console.log(`Delete file ${id} from file system`)
			// // 			this.logger.log(`Delete file ${id} from file system`)
			// // 		)
			// // 		.catch(() => null);

			// stream
			// 	.getStream()
			// 	// .addListener('end', deleteFileFn)
			// 	// .addListener('close', deleteFileFn)
			// 	// .addListener('error', deleteFileFn);

			// 	console.log(stream);

			// return stream;
		} catch (error) {
			// this.logger.error(
			// 	`Error downloading file ${name} ${id}, error: ${error.stack}`,
			// );
			throw error;
		}
	}

	@Delete('delete/:fileId')
	@ResponseMessage("File deleted successfully")
	async delete(
		@Param('fileId') fileId: string,
		@CurrentUser() user: IUser,
		@Ip() ip: string,
	) {
		// this.logger.log(
		// 	`Deleting file ${fileId}, admin is ${user.email}, ip is ${ip}`,
		// );
		try {
			// this.logger.log(`Deleting file ${fileId}`);
			await this.storageService.deleteFile(fileId, user);
		} catch (error) {
			// this.logger.error(`Error deleting file ${fileId}, error: ${error.stack}`);
			throw error;
		}
	}



	@Post('upload-from-drive')
	@ResponseMessage("File uploaded successfully")
	@ApiBody({
		required: true,
		type: "string",
		description: "File ID from Google Drive",
	})
	async uploadFromDrive(
		@Body() body: { fileId: string, fileName: string, mimeType: string },
		@CurrentUser() user: IUser
	) {
		try {
			const res = await this.storageService.uploadFromGoogleDrive(body.fileId, body.fileName, body.mimeType, user);
			return res;
		} catch (error) {
			throw error;
		}
	}
}
