/**
 * File Upload Routes
 * Handles image and document uploads
 */

import express, { Request, Response } from 'express';
import { uploadSingle, uploadImage, uploadVideo, uploadAudio } from '../middleware/upload';
import { authenticate } from '../middleware/auth';
import { validateRemoteImageUrl } from '../utils/imageUrlValidation';
import path from 'path';
import fs from 'fs';

const router = express.Router();

const MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5 MB for images
const ALLOWED_IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];

function getFileExtension(filename: string): string {
  const dotIndex = filename.lastIndexOf('.');
  return dotIndex === -1 ? '' : filename.substring(dotIndex).toLowerCase();
}

router.use(authenticate);

// Upload single file
router.post('/', uploadSingle.single('file'), (req: Request, res: Response) => {
  try {
    if (!req.file) {
      res.status(400).json({ error: 'No file uploaded' });
      return;
    }

    // Enforce 5 MB limit for image files
    const ext = getFileExtension(req.file.originalname);
    if (ALLOWED_IMAGE_EXTENSIONS.includes(ext) && req.file.size > MAX_IMAGE_SIZE) {
      const filePath = path.join('uploads', req.file.filename);
      if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
      res.status(413).json({ error: 'Image size must be 5 MB or less' });
      return;
    }

    const fileUrl = `/uploads/${req.file.filename}`;

    res.json({
      url: fileUrl,
      originalName: req.file.originalname,
      size: req.file.size,
      mimetype: req.file.mimetype,
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to upload file' });
  }
});

// Validate a remote image URL before it is added to a gallery (TC_097).
// Returns { valid: true } (200) for a reachable image, or 400 with a
// user-friendly message for broken/non-image/malformed URLs.
router.post('/validate-image-url', async (req: Request, res: Response) => {
  const result = await validateRemoteImageUrl(req.body?.url);
  if (result.valid) {
    // `url` is the direct image — the same value for a plain image link, or the
    // one extracted from a share/viewer page. Callers store this, not the input.
    res.json({ valid: true, url: result.url });
    return;
  }
  res.status(400).json({ valid: false, error: result.error });
});

// Upload multiple images (5 MB per image)
router.post('/images', uploadImage.array('images', 10), (req: Request, res: Response) => {
  try {
    const files = req.files as Express.Multer.File[];

    if (!files || files.length === 0) {
      res.status(400).json({ error: 'No images uploaded' });
      return;
    }

    const uploadedFiles = files.map((file) => ({
      url: `/uploads/${file.filename}`,
      originalName: file.originalname,
      size: file.size,
    }));

    res.json({ files: uploadedFiles });
  } catch (error) {
    res.status(500).json({ error: 'Failed to upload images' });
  }
});

// Upload video file (up to 256MB)
router.post('/video', uploadVideo.single('file'), (req: Request, res: Response) => {
  try {
    if (!req.file) {
      res.status(400).json({ error: 'No video uploaded' });
      return;
    }

    const fileUrl = `/uploads/${req.file.filename}`;

    res.json({
      url: fileUrl,
      originalName: req.file.originalname,
      size: req.file.size,
      mimetype: req.file.mimetype,
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to upload video' });
  }
});

// Upload audio file (MP3, WAV, M4A, OGG, AAC, FLAC — up to 256MB)
router.post('/audio', uploadAudio.single('file'), (req: Request, res: Response) => {
  try {
    if (!req.file) {
      res.status(400).json({ error: 'No audio file uploaded' });
      return;
    }

    const fileUrl = `/uploads/${req.file.filename}`;

    res.json({
      url: fileUrl,
      originalName: req.file.originalname,
      size: req.file.size,
      mimetype: req.file.mimetype,
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to upload audio file' });
  }
});

export default router;
