#!/bin/bash

echo "🎬 RedOne Vision Video Processing Pipeline Deployment"
echo "==================================================="
echo "Başlangıç: $(date)"

cd /var/www/redone.vision/backend

# 1. FFmpeg kontrolü
echo "1️⃣ FFmpeg kurulumu kontrol ediliyor..."
if command -v ffmpeg &> /dev/null; then
    ffmpeg_version=$(ffmpeg -version | head -n1)
    echo "✅ FFmpeg mevcut: $ffmpeg_version"
else
    echo "❌ FFmpeg bulunamadı, kuruluyor..."
    apt update
    apt install -y ffmpeg
    echo "✅ FFmpeg kuruldu"
fi

# 2. Backup mevcut dosyalar
echo "2️⃣ Mevcut dosyalar yedekleniyor..."
cp routes/upload.js routes/upload.js.backup.video.$(date +%Y%m%d_%H%M%S) 2>/dev/null || echo "upload.js bulunamadı"

# 3. VideoProcessor service oluştur
echo "3️⃣ VideoProcessor service oluşturuluyor..."
mkdir -p services

cat > services/videoProcessor.js << 'EOF'
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const EventEmitter = require('events');

class VideoProcessor extends EventEmitter {
    constructor() {
        super();
        this.queue = [];
        this.processing = false;
        this.currentJob = null;
        this.stats = {
            total: 0,
            completed: 0,
            failed: 0,
            inProgress: 0
        };
    }

    addToQueue(videoJob) {
        const job = {
            id: `job_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            inputPath: videoJob.inputPath,
            outputDir: videoJob.outputDir,
            filename: videoJob.filename,
            category: videoJob.category,
            subtype: videoJob.subtype,
            contentId: videoJob.contentId,
            addedAt: new Date(),
            status: 'queued',
            progress: 0,
            error: null
        };

        this.queue.push(job);
        this.stats.total++;

        console.log(`🎬 Video queued: ${job.id} - ${job.filename}`);

        if (!this.processing) {
            this.processQueue();
        }

        return job.id;
    }

    async processQueue() {
        if (this.processing || this.queue.length === 0) return;

        this.processing = true;
        console.log(`🚀 Processing ${this.queue.length} video(s)`);

        while (this.queue.length > 0) {
            const job = this.queue.shift();
            this.currentJob = job;
            this.stats.inProgress++;

            try {
                await this.processVideo(job);
                this.stats.completed++;
                console.log(`✅ Video completed: ${job.id}`);
            } catch (error) {
                this.stats.failed++;
                job.status = 'failed';
                job.error = error.message;
                console.error(`❌ Video failed: ${job.id} - ${error.message}`);
            }

            this.stats.inProgress--;
            this.currentJob = null;
        }

        this.processing = false;
    }

    async processVideo(job) {
        return new Promise((resolve, reject) => {
            console.log(`🎞️ Encoding: ${job.filename}`);
            
            job.status = 'processing';
            job.progress = 0;

            fs.mkdirSync(job.outputDir, { recursive: true });

            if (!fs.existsSync(job.inputPath)) {
                throw new Error(`Input not found: ${job.inputPath}`);
            }

            const outputName = path.parse(job.filename).name;
            const hlsPath = path.join(job.outputDir, `${outputName}.m3u8`);
            const segmentPath = path.join(job.outputDir, `${outputName}_%03d.ts`);

            // FFmpeg 9:16 HLS encoding
            const ffmpegArgs = [
                '-i', job.inputPath,
                '-vf', 'scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,format=yuv420p',
                '-c:v', 'libx264',
                '-preset', 'medium',
                '-crf', '23',
                '-maxrate', '2M',
                '-bufsize', '4M',
                '-c:a', 'aac',
                '-b:a', '128k',
                '-ac', '2',
                '-f', 'hls',
                '-hls_time', '6',
                '-hls_playlist_type', 'vod',
                '-hls_segment_filename', segmentPath,
                hlsPath
            ];

            const ffmpeg = spawn('ffmpeg', ffmpegArgs);
            let duration = 0;

            ffmpeg.stderr.on('data', (data) => {
                const output = data.toString();
                
                // Parse duration
                const durationMatch = output.match(/Duration: (\d{2}):(\d{2}):(\d{2})/);
                if (durationMatch && duration === 0) {
                    const [, hours, minutes, seconds] = durationMatch;
                    duration = parseInt(hours) * 3600 + parseInt(minutes) * 60 + parseInt(seconds);
                }

                // Parse progress
                const timeMatch = output.match(/time=(\d{2}):(\d{2}):(\d{2})/);
                if (timeMatch && duration > 0) {
                    const [, hours, minutes, seconds] = timeMatch;
                    const currentTime = parseInt(hours) * 3600 + parseInt(minutes) * 60 + parseInt(seconds);
                    job.progress = Math.min(Math.round((currentTime / duration) * 100), 95);
                }
            });

            ffmpeg.on('close', (code) => {
                if (code === 0 && fs.existsSync(hlsPath)) {
                    job.status = 'completed';
                    job.progress = 100;
                    
                    try {
                        fs.unlinkSync(job.inputPath);
                        console.log(`🗑️ Temp cleaned: ${job.inputPath}`);
                    } catch (e) {
                        console.warn(`⚠️ Cleanup warning: ${e.message}`);
                    }
                    
                    resolve(job);
                } else {
                    reject(new Error(`FFmpeg failed with code ${code}`));
                }
            });

            ffmpeg.on('error', (error) => {
                reject(new Error(`FFmpeg error: ${error.message}`));
            });
        });
    }

    getStatus() {
        return {
            processing: this.processing,
            currentJob: this.currentJob ? {
                id: this.currentJob.id,
                filename: this.currentJob.filename,
                status: this.currentJob.status,
                progress: this.currentJob.progress
            } : null,
            queue: this.queue.length,
            stats: this.stats,
            timestamp: new Date().toISOString()
        };
    }

    getJobStatus(jobId) {
        if (this.currentJob && this.currentJob.id === jobId) {
            return this.currentJob;
        }
        return this.queue.find(job => job.id === jobId) || null;
    }
}

module.exports = new VideoProcessor();
EOF

echo "✅ VideoProcessor service oluşturuldu"

# 4. Updated upload.js oluştur
echo "4️⃣ Updated upload.js oluşturuluyor..."
cat > routes/upload.js << 'EOF'
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const videoProcessor = require('../services/videoProcessor');

const router = express.Router();

const verifyToken = (req, res, next) => {
    try {
        const authHeader = req.headers.authorization;
        if (authHeader && authHeader.startsWith('Bearer ')) {
            req.admin = { username: 'admin', role: 'admin' };
        }
        next();
    } catch (error) {
        next();
    }
};

function generateContentId(title, category) {
    const sanitizedTitle = (title || 'untitled')
        .toLowerCase()
        .replace(/[^a-z0-9]/g, '-')
        .replace(/-+/g, '-')
        .replace(/^-|-$/g, '');
    const timestamp = Date.now().toString().slice(-6);
    return `${(category || 'general').toLowerCase()}-${sanitizedTitle}-${timestamp}`;
}

function getMediaPath(category, subtype, isVideo) {
    const baseType = isVideo ? 'Video' : 'Poster';
    return `/var/www/redone.vision/media/${category}/${baseType}/${subtype}/`;
}

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        const isVideo = file.mimetype.startsWith("video/");
        
        if (isVideo) {
            // Videos → temp for processing
            const tempPath = '/var/www/redone.vision/uploads/temp';
            fs.mkdirSync(tempPath, { recursive: true });
            console.log(`📹 Video → temp: ${tempPath}`);
            cb(null, tempPath);
        } else {
            // Images → direct to final
            const { category, subtype } = req.body;
            const finalPath = `/var/www/redone.vision/uploads/${category}/Poster/${subtype}`;
            fs.mkdirSync(finalPath, { recursive: true });
            console.log(`🖼️ Image → final: ${finalPath}`);
            cb(null, finalPath);
        }
    },
    filename: (req, file, cb) => {
        const title = req.body.title || req.body.contentTitle || '';
        const timestamp = Date.now();
        const ext = path.extname(file.originalname);
        
        let filename;
        if (title && title.trim()) {
            const cleanTitle = title.trim().replace(/[^a-z0-9]/gi, '-').toLowerCase();
            filename = `${cleanTitle}-${timestamp}${ext}`;
        } else {
            filename = `upload-${timestamp}${ext}`;
        }
        
        cb(null, filename);
    }
});

const upload = multer({
    storage: storage,
    limits: { fileSize: 10 * 1024 * 1024 * 1024 },
    fileFilter: (req, file, cb) => {
        const allowedTypes = /jpeg|jpg|png|gif|webp|svg|mp4|webm|ogg|avi|mov|wmv|flv|mkv/;
        const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
        const mimetype = allowedTypes.test(file.mimetype);
        
        if (extname && mimetype) {
            return cb(null, true);
        } else {
            cb(new Error('Sadece video ve görüntü dosyaları yüklenebilir!'));
        }
    }
});

router.post('/file', verifyToken, upload.single('file'), async (req, res) => {
    console.log('🚀 UPLOAD WITH VIDEO PIPELINE');
    
    try {
        if (!req.file) {
            return res.status(400).json({
                success: false,
                message: 'Dosya yüklenmedi'
            });
        }

        const title = req.body.title || req.body.contentTitle || 'Untitled';
        const category = req.body.category || req.body.contentCategory || 'Movies';
        const subtype = req.body.subtype || req.body.destination || 'Content';
        
        const isVideo = req.file.mimetype.startsWith('video/');
        const finalContentId = generateContentId(title, category);
        
        let processingJobId = null;
        let finalStatus = 'uploaded';
        let finalMessage = 'Dosya başarıyla yüklendi';

        if (isVideo) {
            const outputDir = getMediaPath(category, subtype, true);
            
            const videoJob = {
                inputPath: req.file.path,
                outputDir: outputDir,
                filename: req.file.filename,
                category: category,
                subtype: subtype,
                contentId: finalContentId
            };

            processingJobId = videoProcessor.addToQueue(videoJob);
            finalStatus = 'processing';
            finalMessage = `🎬 Video yüklendi! Encoding başlatıldı (Job: ${processingJobId})`;
            
            console.log(`🎬 Video queued: ${processingJobId}`);
        }

        const responseData = {
            success: true,
            message: finalMessage,
            data: {
                contentId: finalContentId,
                filename: req.file.filename,
                originalName: req.file.originalname,
                size: req.file.size,
                uploadPath: req.file.path,
                category: category,
                subtype: subtype,
                isVideo: isVideo,
                status: finalStatus,
                uploadedAt: new Date().toISOString(),
                processing: isVideo ? {
                    jobId: processingJobId,
                    status: 'queued',
                    message: '9:16 HLS encoding will begin shortly',
                    expectedOutput: getMediaPath(category, subtype, true)
                } : null
            }
        };
        
        console.log(`✅ ${isVideo ? 'Video' : 'Image'} uploaded: ${req.file.filename}`);
        res.json(responseData);
        
    } catch (error) {
        console.error('❌ Upload error:', error);
        res.status(500).json({
            success: false,
            message: 'Upload hatası: ' + error.message
        });
    }
});

router.get('/processing/status', verifyToken, (req, res) => {
    res.json({
        success: true,
        message: 'Video processing status',
        data: videoProcessor.getStatus()
    });
});

router.get('/processing/job/:jobId', verifyToken, (req, res) => {
    const job = videoProcessor.getJobStatus(req.params.jobId);
    
    if (job) {
        res.json({ success: true, data: job });
    } else {
        res.status(404).json({ success: false, message: 'Job bulunamadı' });
    }
});

router.get('/temp-files', verifyToken, (req, res) => {
    try {
        const tempPath = '/var/www/redone.vision/uploads/temp';
        
        if (!fs.existsSync(tempPath)) {
            return res.json({
                success: true,
                data: { files: [], message: 'Temp klasörü bulunamadı' }
            });
        }
        
        const files = fs.readdirSync(tempPath)
            .filter(file => file !== '.gitkeep')
            .map(file => {
                const filePath = path.join(tempPath, file);
                const stats = fs.statSync(filePath);
                return {
                    filename: file,
                    path: filePath,
                    size: stats.size,
                    created: stats.birthtime,
                    isVideo: /\.(mp4|avi|mov|mkv|webm)$/i.test(file)
                };
            });
        
        res.json({
            success: true,
            data: {
                tempPath: tempPath,
                fileCount: files.length,
                videoCount: files.filter(f => f.isVideo).length,
                files: files
            }
        });
        
    } catch (error) {
        res.status(500).json({
            success: false,
            message: 'Temp files error: ' + error.message
        });
    }
});

router.get('/status', (req, res) => {
    const processingStatus = videoProcessor.getStatus();
    
    res.json({
        success: true,
        message: '🎬 Video Processing Pipeline Active',
        data: {
            uploadService: 'Active',
            videoProcessing: processingStatus.processing,
            queueLength: processingStatus.queue,
            stats: processingStatus.stats,
            workflow: 'upload → temp → 9:16 HLS encode → media → cleanup',
            encoding: 'FFmpeg HLS 1080x1920',
            timestamp: new Date().toISOString()
        }
    });
});

module.exports = router;
EOF

echo "✅ Updated upload.js oluşturuldu"

# 5. Media klasörleri oluştur
echo "5️⃣ Media klasörleri oluşturuluyor..."
mkdir -p /var/www/redone.vision/media/{Movies/{Video/{Teaser,Riyad,Content},Poster/{Riyad,Content}},Series/{Video/{Teaser,Riyad,Content},Poster/{Riyad,Content}},Lifestyle/{Video/{Teaser,Content},Poster/Content},RedPulse/{Video/{Teaser,Content},Poster/Content}}

# 6. İzinleri ayarla
echo "6️⃣ İzinler ayarlanıyor..."
chown -R www-data:www-data /var/www/redone.vision/uploads/
chown -R www-data:www-data /var/www/redone.vision/media/
chmod -R 755 /var/www/redone.vision/uploads/
chmod -R 755 /var/www/redone.vision/media/

# 7. Syntax kontrol
echo "7️⃣ Syntax kontrol..."
node -c services/videoProcessor.js && echo "✅ VideoProcessor OK" || echo "❌ VideoProcessor syntax error"
node -c routes/upload.js && echo "✅ Upload routes OK" || echo "❌ Upload routes syntax error"

# 8. PM2 restart
echo "8️⃣ Backend restart..."
pm2 restart redone-backend
sleep 5

# 9. Test endpoints
echo "9️⃣ Pipeline endpoints test..."

# Processing status
status_response=$(curl -s https://redone.vision/api/upload/processing/status)
echo "Processing status: $status_response"

# Upload status
upload_status=$(curl -s https://redone.vision/api/upload/status)
echo "Upload status: $upload_status"

# Temp files
temp_files=$(curl -s https://redone.vision/api/upload/temp-files)
echo "Temp files: $temp_files"

echo ""
echo "🎉 VIDEO PROCESSING PIPELINE DEPLOYED!"
echo "======================================"
echo "✅ FFmpeg HLS encoding ready"
echo "✅ 9:16 vertical video processing"
echo "✅ Temp → Media transfer pipeline"
echo "✅ Background processing queue"
echo "✅ Progress tracking"
echo "✅ Automatic cleanup"
echo ""
echo "🎬 Workflow:"
echo "   1. Upload video → /uploads/temp/"
echo "   2. FFmpeg 9:16 HLS encoding"
echo "   3. Transfer → /media/category/Video/subtype/"
echo "   4. Cleanup temp files"
echo ""
echo "📋 Test endpoints:"
echo "   - https://redone.vision/api/upload/status"
echo "   - https://redone.vision/api/upload/processing/status"
echo "   - https://redone.vision/api/upload/temp-files"
echo ""
echo "🎬 Admin panel video upload test:"
echo "   1. https://redone.vision/admin.html"
echo "   2. Upload bir video dosyası"
echo "   3. PM2 logs'ta encoding progress izleyin:"
echo "      pm2 logs redone-backend --lines 0 -f"
echo ""
echo "🔍 Debug komutları:"
echo "   - ls -la /var/www/redone.vision/uploads/temp/"
echo "   - ls -la /var/www/redone.vision/media/Movies/Video/Content/"
echo "   - curl https://redone.vision/api/upload/processing/status"
echo ""
echo "Bitiş: $(date)"
