import {
  Controller,
  Post,
  UseGuards,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
import { extname, join } from 'path';
import { existsSync, mkdirSync } from 'fs';
import { ClsService } from 'nestjs-cls';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { TenantEntity } from '../../entities/tenant.entity';
import { CLS_TENANT_ID } from '../../common/cls/cls.constants';
import { successResponse } from '../../common/responses/api-response';

const UPLOAD_ROOT = join(process.cwd(), 'uploads');

@Controller('uploads')
export class UploadController {
  constructor(
    private readonly cls: ClsService,
    @InjectRepository(TenantEntity)
    private readonly tenantRepo: Repository<TenantEntity>,
  ) {}

  @Post()
  @UseGuards(JwtAuthGuard)
  @UseInterceptors(
    FileInterceptor('file', {
      limits: { fileSize: 50 * 1024 * 1024 }, // 50MB (images + videos)
      fileFilter: (_req, file, cb) => {
        const allowed = /\.(jpg|jpeg|png|gif|svg|webp|ico|mp4|mov|webm|avi)$/i;
        if (!allowed.test(extname(file.originalname))) {
          cb(new BadRequestException('Only image and video files are allowed'), false);
          return;
        }
        cb(null, true);
      },
      storage: diskStorage({
        destination: (_req, _file, cb) => {
          // Temp store in uploads root — we'll move based on tenant after
          if (!existsSync(UPLOAD_ROOT)) {
            mkdirSync(UPLOAD_ROOT, { recursive: true });
          }
          cb(null, UPLOAD_ROOT);
        },
        filename: (_req, file, cb) => {
          const uniqueName = `${Date.now()}-${Math.random().toString(36).substring(2, 8)}${extname(file.originalname)}`;
          cb(null, uniqueName);
        },
      }),
    }),
  )
  async uploadFile(@UploadedFile() file: Express.Multer.File) {
    if (!file) {
      throw new BadRequestException('No file uploaded');
    }

    const tenantId = this.cls.get<string>(CLS_TENANT_ID);
    const tenant = await this.tenantRepo.findOne({
      where: { id: tenantId },
      select: ['subdomain'],
    });
    const subdomain = tenant?.subdomain || 'default';

    // Move file to tenant folder
    const tenantDir = join(UPLOAD_ROOT, subdomain);
    if (!existsSync(tenantDir)) {
      mkdirSync(tenantDir, { recursive: true });
    }

    const { renameSync } = require('fs');
    const newPath = join(tenantDir, file.filename);
    renameSync(file.path, newPath);

    const fileUrl = `/api/uploads/${subdomain}/${file.filename}`;

    const videoExts = /\.(mp4|mov|webm|avi)$/i;
    const fileType = videoExts.test(extname(file.originalname)) ? 'video' : 'image';

    const result = {
      url: fileUrl,
      filename: file.filename,
      size: file.size,
      type: fileType,
    };

    return successResponse(result, 'File uploaded successfully');
  }
}
