use chrono::{Duration, Utc};
use std::sync::Arc;

use crate::{
    domain::{pairing_session::PairingSession, record_id::RecordId},
    error::Result,
    ports::{id_generator::IdGeneratorPort, repository::PairingSessionRepositoryPort},
};

pub struct PairingSessionUseCase {
    pairing_repo: Arc<dyn PairingSessionRepositoryPort>,
    id_gen: Arc<dyn IdGeneratorPort>,
}

impl PairingSessionUseCase {
    pub fn new(
        pairing_repo: Arc<dyn PairingSessionRepositoryPort>,
        id_gen: impl IdGeneratorPort + 'static,
    ) -> Self {
        Self {
            pairing_repo,
            id_gen: Arc::new(id_gen),
        }
    }

    pub async fn init_pairing_session(&self) -> Result<PairingSession> {
        let id = self.id_gen.generate();
        
        // Session valid for 10 minutes
        let now = Utc::now();
        let expires_at = now + Duration::minutes(10);
        
        let session = PairingSession {
            id,
            share_id: None,
            created_at: now,
            expires_at,
        };
        
        self.pairing_repo.save(session).await
    }

    pub async fn get_session_status(&self, id: &RecordId) -> Result<Option<PairingSession>> {
        let session = self.pairing_repo.find_by_id(id).await?;
        
        // Check if expired
        if let Some(s) = &session {
            if Utc::now() > s.expires_at {
                return Ok(None);
            }
        }
        
        Ok(session)
    }

    pub async fn assign_share_to_session(&self, id: &RecordId, share_id: String) -> Result<()> {
        let session = self.pairing_repo.find_by_id(id).await?;
        
        if let Some(s) = session {
            if Utc::now() > s.expires_at {
                return Err(crate::error::JottamError::Conflict("Session expired".to_string()));
            }
            
            self.pairing_repo.update_share_id(id, share_id).await?;
            Ok(())
        } else {
            Err(crate::error::JottamError::NotFound("Pairing session not found".to_string()))
        }
    }
}
