//! Virtual garage service layer providing business logic for garage management operations.
//!
//! Implements the service layer of the virtual garage system, handling business logic,
//! validation, and orchestration.

use forge_models::{VGarage, VehicleCategory};
use forge_repositories::VGarageRepository;

/// Service layer implementation for virtual garage business logic and operations.
///
/// Orchestrates virtual garage management operations, handling business logic, validation,
/// and data transformation. Manages equipment storage across four categories: items,
/// weapons, magazines, and backpacks.
///
/// # Thread Safety
/// Thread-safe when used with a thread-safe repository.
pub struct VGarageService<R: VGarageRepository> {
    /// The repository instance used for all data persistence operations.
    ///
    /// This repository handles the actual storage and retrieval of garage data,
    /// abstracting away the specific database implementation details.
    repository: R,
}

impl<R: VGarageRepository> VGarageService<R> {
    /// Creates a new garage service with the provided repository.
    ///
    /// The repository must be initialized and ready for use.
    pub fn new(repository: R) -> Self {
        Self { repository }
    }

    /// Creates a new empty virtual garage for a player.
    ///
    /// Handles duplicate checking and persistence.
    pub fn create_garage(&self, uid: &str) -> Result<VGarage, String> {
        // Business rule: Check if garage already exists
        if self.repository.exists(uid)? {
            return Err(format!("Garage for '{}' already exists", uid));
        }

        // Create empty garage (no items)
        let garage = VGarage::new();
        self.repository.create(uid, &garage)?;

        Ok(garage)
    }

    /// Retrieves a player's virtual garage.
    pub fn fetch_garage(&self, uid: &str) -> Result<VGarage, String> {
        match self.repository.fetch(uid)? {
            Some(garage) => Ok(garage),
            None => Err(format!("No garage found for player '{}'", uid)),
        }
    }

    /// Retrieves a specific field from a player's virtual garage.
    ///
    /// Fields: "cars", "armor", "heli", "planes", "naval", "other"
    pub fn get_garage(&self, uid: &str, field: &str) -> Result<Vec<String>, String> {
        self.repository.get(uid, field)
    }

    /// Adds classnames to a player's virtual garage.
    pub fn add_garage(
        &self,
        uid: &str,
        category: VehicleCategory,
        classnames: Vec<String>,
    ) -> Result<VGarage, String> {
        let mut garage = match self.repository.fetch(uid)? {
            Some(g) => g,
            None => VGarage::new(),
        };

        garage.add(category, classnames);
        self.repository.update(uid, &garage)?;

        Ok(garage)
    }

    /// Removes a classname from a player's virtual garage.
    pub fn remove_garage(
        &self,
        uid: &str,
        category: VehicleCategory,
        classname: &str,
    ) -> Result<VGarage, String> {
        let mut garage = match self.repository.fetch(uid)? {
            Some(g) => g,
            None => return Err(format!("No garage found for player '{}'", uid)),
        };

        if garage.remove(category, classname).is_none() {
            return Err(format!("Item '{}' not found in garage", classname));
        }

        self.repository.update(uid, &garage)?;

        Ok(garage)
    }

    /// Permanently deletes a player's virtual garage.
    ///
    /// Irreversible operation. Delegates to repository.
    pub fn delete_garage(&self, uid: &str) -> Result<(), String> {
        // Business rule: Check if garage exists
        if !self.repository.exists(uid)? {
            return Err(format!("No garage found for player '{}'", uid));
        }

        // Delete garage
        self.repository.delete(uid)?;

        Ok(())
    }

    /// Checks if a player has a virtual garage.
    ///
    /// Lightweight check without data retrieval.
    pub fn garage_exists(&self, uid: &str) -> Result<bool, String> {
        self.repository.exists(uid)
    }
}
