import { Request, Response } from "express";
import multer from "multer";
import path from "path";
import fs from "fs";

// Configure multer for video uploads
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = './uploads/videos';
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir, { recursive: true });
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
  }
});

const fileFilter = (req: any, file: any, cb: any) => {
  // Accept video files only
  if (file.mimetype.startsWith('video/')) {
    cb(null, true);
  } else {
    cb(new Error('Only video files are allowed!'), false);
  }
};

export const videoUpload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: {
    fileSize: 1024 * 1024 * 1024 // 1GB limit
  }
});

interface HighlightClip {
  id: string;
  type: 'goal' | 'assist' | 'save' | 'tackle' | 'run' | 'pass' | 'skill';
  startTime: number;
  endTime: number;
  confidence: number;
  description: string;
  playerName?: string;
}

interface VideoAnalysis {
  videoId: string;
  status: 'processing' | 'completed' | 'failed';
  progress: number;
  highlights: HighlightClip[];
  processingTime: number;
}

// In-memory storage for demo (in production, use database)
const videoAnalyses = new Map<string, VideoAnalysis>();

// Mock AI analysis engine
class AIVideoAnalyzer {
  static async analyzeVideo(videoPath: string, videoId: string, settings: any): Promise<HighlightClip[]> {
    // Simulate AI processing time
    await new Promise(resolve => setTimeout(resolve, 2000));

    // Mock detected highlights based on video analysis
    const mockHighlights: HighlightClip[] = [
      {
        id: `${videoId}_1`,
        type: 'goal',
        startTime: Math.floor(Math.random() * 1800) + 120,
        endTime: Math.floor(Math.random() * 1800) + 135,
        confidence: Math.floor(Math.random() * 20) + 80,
        description: 'Goal scored from penalty area',
        playerName: 'Player ' + Math.floor(Math.random() * 11 + 1)
      },
      {
        id: `${videoId}_2`,
        type: 'assist',
        startTime: Math.floor(Math.random() * 1800) + 300,
        endTime: Math.floor(Math.random() * 1800) + 315,
        confidence: Math.floor(Math.random() * 15) + 75,
        description: 'Assist leading to goal',
        playerName: 'Player ' + Math.floor(Math.random() * 11 + 1)
      },
      {
        id: `${videoId}_3`,
        type: 'save',
        startTime: Math.floor(Math.random() * 1800) + 600,
        endTime: Math.floor(Math.random() * 1800) + 612,
        confidence: Math.floor(Math.random() * 25) + 70,
        description: 'Goalkeeper save',
        playerName: 'Goalkeeper'
      },
      {
        id: `${videoId}_4`,
        type: 'tackle',
        startTime: Math.floor(Math.random() * 1800) + 800,
        endTime: Math.floor(Math.random() * 1800) + 810,
        confidence: Math.floor(Math.random() * 20) + 65,
        description: 'Defensive tackle',
        playerName: 'Player ' + Math.floor(Math.random() * 11 + 1)
      },
      {
        id: `${videoId}_5`,
        type: 'skill',
        startTime: Math.floor(Math.random() * 1800) + 1000,
        endTime: Math.floor(Math.random() * 1800) + 1015,
        confidence: Math.floor(Math.random() * 30) + 60,
        description: 'Skill move past defender',
        playerName: 'Player ' + Math.floor(Math.random() * 11 + 1)
      }
    ];

    // Filter highlights based on settings
    return mockHighlights.filter(highlight => 
      settings.highlightTypes?.includes(highlight.type) && 
      highlight.confidence >= (settings.minConfidence || 50)
    );
  }

  static async generateHighlightReel(clips: HighlightClip[], settings: any): Promise<string> {
    // Simulate video compilation time
    await new Promise(resolve => setTimeout(resolve, 3000));
    
    // Return mock output file path
    return `./uploads/highlights/highlight_reel_${Date.now()}.mp4`;
  }
}

// API endpoints
export async function uploadVideo(req: Request, res: Response) {
  try {
    if (!req.file) {
      return res.status(400).json({ error: 'No video file uploaded' });
    }

    const videoData = {
      id: Date.now().toString(),
      name: req.file.originalname,
      filename: req.file.filename,
      size: req.file.size,
      path: req.file.path,
      uploadedAt: new Date().toISOString(),
      status: 'ready'
    };

    res.json({
      success: true,
      video: videoData
    });
  } catch (error: any) {
    console.error('Video upload error:', error);
    res.status(500).json({ error: error.message });
  }
}

export async function analyzeVideo(req: Request, res: Response) {
  try {
    const { videoId, settings } = req.body;

    if (!videoId) {
      return res.status(400).json({ error: 'Video ID is required' });
    }

    // Initialize analysis
    const analysis: VideoAnalysis = {
      videoId,
      status: 'processing',
      progress: 0,
      highlights: [],
      processingTime: Date.now()
    };

    videoAnalyses.set(videoId, analysis);

    // Start background analysis
    (async () => {
      try {
        const highlights = await AIVideoAnalyzer.analyzeVideo(
          `./uploads/videos/${videoId}`, 
          videoId, 
          settings
        );

        const completedAnalysis: VideoAnalysis = {
          videoId,
          status: 'completed',
          progress: 100,
          highlights,
          processingTime: Date.now() - analysis.processingTime
        };

        videoAnalyses.set(videoId, completedAnalysis);
      } catch (error) {
        const failedAnalysis: VideoAnalysis = {
          videoId,
          status: 'failed',
          progress: 0,
          highlights: [],
          processingTime: Date.now() - analysis.processingTime
        };

        videoAnalyses.set(videoId, failedAnalysis);
      }
    })();

    res.json({
      success: true,
      analysisId: videoId,
      status: 'processing'
    });
  } catch (error: any) {
    console.error('Video analysis error:', error);
    res.status(500).json({ error: error.message });
  }
}

export async function getAnalysisStatus(req: Request, res: Response) {
  try {
    const { videoId } = req.params;
    const analysis = videoAnalyses.get(videoId);

    if (!analysis) {
      return res.status(404).json({ error: 'Analysis not found' });
    }

    res.json(analysis);
  } catch (error: any) {
    console.error('Get analysis status error:', error);
    res.status(500).json({ error: error.message });
  }
}

export async function generateHighlights(req: Request, res: Response) {
  try {
    const { videoId, selectedClips, settings } = req.body;

    if (!videoId || !selectedClips || selectedClips.length === 0) {
      return res.status(400).json({ error: 'Video ID and selected clips are required' });
    }

    // Generate highlight reel
    const outputPath = await AIVideoAnalyzer.generateHighlightReel(selectedClips, settings);

    res.json({
      success: true,
      outputPath,
      clipCount: selectedClips.length,
      duration: selectedClips.reduce((total: number, clip: any) => total + (clip.endTime - clip.startTime), 0)
    });
  } catch (error: any) {
    console.error('Generate highlights error:', error);
    res.status(500).json({ error: error.message });
  }
}

export async function getVideoLibrary(req: Request, res: Response) {
  try {
    const uploadsDir = './uploads/videos';
    
    if (!fs.existsSync(uploadsDir)) {
      return res.json({ videos: [] });
    }

    const files = fs.readdirSync(uploadsDir);
    const videos = files
      .filter(file => file.match(/\.(mp4|mov|avi|mkv)$/i))
      .map(file => {
        const filePath = path.join(uploadsDir, file);
        const stats = fs.statSync(filePath);
        
        return {
          id: file.replace(/\.[^/.]+$/, ""), // Remove extension for ID
          name: file,
          size: stats.size,
          uploadedAt: stats.birthtime.toISOString(),
          status: 'ready'
        };
      });

    res.json({ videos });
  } catch (error: any) {
    console.error('Get video library error:', error);
    res.status(500).json({ error: error.message });
  }
}

export async function deleteVideo(req: Request, res: Response) {
  try {
    const { videoId } = req.params;
    const videoPath = `./uploads/videos/${videoId}`;

    if (fs.existsSync(videoPath)) {
      fs.unlinkSync(videoPath);
    }

    // Remove analysis data
    videoAnalyses.delete(videoId);

    res.json({ success: true });
  } catch (error: any) {
    console.error('Delete video error:', error);
    res.status(500).json({ error: error.message });
  }
}