import { Controller, Put, Get, Param, Req, Res, Logger } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import type { Request, Response } from 'express';
import { Public } from '../../common/decorators/public.decorator';
import { LocalStorageProvider } from './local-storage.provider';
import * as fs from 'fs';
import * as path from 'path';

@ApiTags('storage')
@Controller('storage')
export class LocalStorageController {
  private readonly logger = new Logger(LocalStorageController.name);

  constructor(private readonly localProvider: LocalStorageProvider) {}

  /**
   * PUT upload — 接受原始二进制文件体
   */
  @Public()
  @Put('upload/:objectKey')
  async uploadFile(
    @Param('objectKey') objectKey: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const decodedKey = decodeURIComponent(objectKey);
    const chunks: Buffer[] = [];

    req.on('data', (chunk: Buffer) => chunks.push(chunk));
    req.on('end', () => {
      try {
        const buffer = Buffer.concat(chunks);
        this.localProvider.saveFile(decodedKey, buffer);
        res.status(200).json({ success: true, objectKey: decodedKey, size: buffer.length });
      } catch (err: any) {
        this.logger.error(`Upload failed: ${decodedKey}`, err.message);
        res.status(500).json({ success: false, error: err.message });
      }
    });
    req.on('error', (err: any) => {
      this.logger.error(`Upload stream error: ${decodedKey}`, err.message);
      res.status(500).json({ success: false, error: err.message });
    });
  }

  /**
   * GET download — 返回文件内容
   */
  @Public()
  @Get('download/:objectKey')
  async downloadFile(
    @Param('objectKey') objectKey: string,
    @Res() res: Response,
  ) {
    const decodedKey = decodeURIComponent(objectKey);
    const filePath = this.localProvider.getObjectPath(decodedKey);

    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ success: false, error: 'File not found' });
    }

    const stat = fs.statSync(filePath);
    res.setHeader('Content-Length', stat.size);
    res.setHeader('Content-Type', 'application/octet-stream');
    const stream = fs.createReadStream(filePath);
    stream.pipe(res);
  }
}
