const express = require('express');
const router = express.Router();
const { requireAdminAuth } = require('../middleware/auth');
const { movieMediaUpload, imageUpload, videoUpload, pushToR2, handleMulterError } = require('../middleware/upload');
const { imageKey, videoKey, getPresignedUploadUrl } = require('../services/r2');
const { query } = require('../utils/db');

/**
 * POST /api/upload/movie-media/:movieId
 * Upload poster, banner, and/or video file to R2 for a movie.
 * Fields: poster (image), banner (image), video (video)
 * Admin only.
 */
router.post(
  '/movie-media/:movieId',
  requireAdminAuth,
  movieMediaUpload.fields([
    { name: 'poster', maxCount: 1 },
    { name: 'banner', maxCount: 1 },
    { name: 'video',  maxCount: 1 },
  ]),
  handleMulterError,
  async (req, res) => {
    const { movieId } = req.params;
    const files = req.files || {};

    // Verify movie exists
    const movieCheck = await query('SELECT id FROM movies WHERE id = $1', [movieId]);
    if (!movieCheck.rows.length) {
      return res.status(404).json({ success: false, message: 'Movie not found' });
    }

    const results = {};
    const dbUpdates = [];
    const dbParams = [];
    let p = 1;

    try {
      // Upload poster
      if (files.poster?.[0]) {
        const file = files.poster[0];
        const key = imageKey(movieId, 'poster', file.originalname);
        const { url } = await pushToR2(file, key);
        results.poster_url = url;
        dbUpdates.push(`poster_url = $${p++}`);
        dbParams.push(url);
      }

      // Upload banner
      if (files.banner?.[0]) {
        const file = files.banner[0];
        const key = imageKey(movieId, 'banner', file.originalname);
        const { url } = await pushToR2(file, key);
        results.banner_url = url;
        dbUpdates.push(`banner_url = $${p++}`);
        dbParams.push(url);
      }

      // Upload video
      if (files.video?.[0]) {
        const file = files.video[0];
        const key = videoKey(movieId, file.originalname);
        const { url } = await pushToR2(file, key);
        results.video_url = url;
        results.video_key = key;
        // Store key separately for later transcoding (Cloudflare Stream)
        dbUpdates.push(`video_url = $${p++}`, `video_r2_key = $${p++}`, `transcoding_status = 'pending'`);
        dbParams.push(url, key);
      }

      // Update movie record with new URLs
      if (dbUpdates.length) {
        dbUpdates.push(`updated_at = NOW()`);
        dbParams.push(movieId);
        await query(
          `UPDATE movies SET ${dbUpdates.join(', ')} WHERE id = $${p}`,
          dbParams
        );
      }

      res.json({
        success: true,
        message: 'Files uploaded to R2 successfully',
        uploaded: results,
      });
    } catch (err) {
      console.error('R2 upload error:', err);
      res.status(500).json({ success: false, message: 'Upload failed: ' + err.message });
    }
  }
);

/**
 * POST /api/upload/presigned-video-url
 * Returns a presigned R2 upload URL for direct browser → R2 upload.
 * Use this for large video files to avoid proxying through Node.js.
 * Body: { movieId, filename, contentType }
 * Admin only.
 */
router.post('/presigned-video-url', requireAdminAuth, async (req, res) => {
  try {
    const { movieId, filename, contentType } = req.body;

    if (!movieId || !filename || !contentType) {
      return res.status(400).json({ success: false, message: 'movieId, filename, and contentType required' });
    }

    const allowedTypes = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska', 'video/webm'];
    if (!allowedTypes.includes(contentType)) {
      return res.status(400).json({ success: false, message: 'Invalid video content type' });
    }

    const key = videoKey(movieId, filename);
    const { url, publicUrl } = await getPresignedUploadUrl(key, contentType, 3600); // 1 hour

    // After client uploads, they should call PATCH /api/movies/:id to set video_url
    res.json({
      success: true,
      uploadUrl: url,        // PUT this URL directly from the browser
      key,
      publicUrl,             // The final video_url to save to the movie
      expiresIn: 3600,
    });
  } catch (err) {
    console.error('Presigned URL error:', err);
    res.status(500).json({ success: false, message: 'Failed to generate upload URL' });
  }
});

/**
 * POST /api/upload/presigned-image-url
 * Returns a presigned URL for direct image upload.
 * Body: { movieId, type ('poster'|'banner'), filename, contentType }
 */
router.post('/presigned-image-url', requireAdminAuth, async (req, res) => {
  try {
    const { movieId, type, filename, contentType } = req.body;

    if (!['poster', 'banner', 'thumbnail'].includes(type)) {
      return res.status(400).json({ success: false, message: 'type must be poster, banner, or thumbnail' });
    }

    const key = imageKey(movieId, type, filename);
    const { url, publicUrl } = await getPresignedUploadUrl(key, contentType, 900); // 15 min

    res.json({ success: true, uploadUrl: url, key, publicUrl });
  } catch (err) {
    res.status(500).json({ success: false, message: 'Failed to generate upload URL' });
  }
});

module.exports = router;
