use crate::transcoding::codecs::profiles::QualityProfile;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::SystemTime;
use uuid::Uuid;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum JobPriority {
    Background = 0,
    Normal = 1,
    Urgent = 2,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum JobStatus {
    Pending,
    Processing,
    Completed,
    Failed(String),
    Cancelled,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TranscodingJob {
    pub id: Uuid,
    pub track_id: String,
    pub input_path: PathBuf,
    pub output_dir: PathBuf,
    pub target_profile: QualityProfile,
    pub priority: JobPriority,
    pub status: JobStatus,
    pub created_at: SystemTime,
    pub started_at: Option<SystemTime>,
    pub completed_at: Option<SystemTime>,
    pub retry_count: u32,
    pub progress_percent: f32,
}

impl TranscodingJob {
    pub fn new(
        track_id: String,
        input_path: PathBuf,
        output_dir: PathBuf,
        target_profile: QualityProfile,
        priority: JobPriority,
    ) -> Self {
        Self {
            id: Uuid::new_v4(),
            track_id,
            input_path,
            output_dir,
            target_profile,
            priority,
            status: JobStatus::Pending,
            created_at: SystemTime::now(),
            started_at: None,
            completed_at: None,
            retry_count: 0,
            progress_percent: 0.0,
        }
    }

    pub fn mark_started(&mut self) {
        self.status = JobStatus::Processing;
        self.started_at = Some(SystemTime::now());
    }

    pub fn mark_completed(&mut self) {
        self.status = JobStatus::Completed;
        self.completed_at = Some(SystemTime::now());
        self.progress_percent = 100.0;
    }

    pub fn mark_failed(&mut self, reason: String) {
        self.status = JobStatus::Failed(reason);
        self.completed_at = Some(SystemTime::now());
    }
    
    pub fn can_retry(&self, max_retries: u32) -> bool {
        self.retry_count < max_retries
    }
}
