<?php
/**
 * Vendor Permissions Helper
 *
 * Centralizes vendor permission checks based on admin settings
 *
 * @package Wahra_Rentals_Bookings
 */

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class WAHRB_Vendor_Permissions
 *
 * Helper class to check vendor permissions as configured by admin
 */
class WAHRB_Vendor_Permissions {

    /**
     * Cached permissions
     *
     * @var array|null
     */
    private static $permissions = null;

    /**
     * Default permissions
     *
     * @var array
     */
    private static $defaults = [
        // ========== PRICING PERMISSIONS ==========
        'can_set_own_prices'        => true,
        'can_set_cancellation_policy' => true,
        'can_set_deposit_amount'    => true,
        'can_set_security_deposit'  => true,
        'min_price_allowed'         => 0,
        'max_price_allowed'         => 0,
        'require_approval'          => false,
        
        // ========== SLOT MODE CUSTOMIZATION ==========
        'can_customize_slot_duration' => true,
        'can_customize_business_hours' => true,
        'allowed_slot_durations'    => [30, 60, 90, 120, 180, 240],
        
        // ========== SERVICE MODE CUSTOMIZATION ==========
        'can_customize_service_duration' => true,
        'can_customize_capacity'    => true,
        'allowed_service_durations' => [15, 30, 45, 60, 90, 120],
        'max_capacity_allowed'      => 50,
        
        // ========== DEFAULT VALUES (cascade to vendor) ==========
        'use_admin_defaults'        => true,

        // ========== PER-CATEGORY OVERRIDES ==========
        // Each key is a category slug => array of permission overrides
        'categories' => [],
    ];

    /**
     * Get all permissions
     *
     * @return array
     */
    public static function get_all() {
        if (self::$permissions === null) {
            self::$permissions = get_option('wahrb_settings_vendor_permissions', self::$defaults);
            self::$permissions = wp_parse_args(self::$permissions, self::$defaults);
        }
        return self::$permissions;
    }

    /**
     * Check if vendor can perform a specific action
     *
     * @param string $permission Permission key
     * @return bool
     */
    public static function can($permission) {
        $permissions = self::get_all();
        return !empty($permissions[$permission]);
    }

    /**
     * Check if vendor can set their own prices
     *
     * @return bool
     */
    public static function can_set_prices() {
        return self::can('can_set_own_prices');
    }

    /**
     * Check if vendor can set cancellation policy
     *
     * @return bool
     */
    public static function can_set_cancellation_policy() {
        return self::can('can_set_cancellation_policy');
    }

    /**
     * Check if vendor can set deposit amount
     *
     * @return bool
     */
    public static function can_set_deposit() {
        return self::can('can_set_deposit_amount');
    }

    /**
     * Check if vendor can set security deposit
     *
     * @return bool
     */
    public static function can_set_security_deposit() {
        return self::can('can_set_security_deposit');
    }

    /**
     * Get minimum price allowed for vendors
     *
     * @return float
     */
    public static function get_min_price() {
        $permissions = self::get_all();
        return (float) ($permissions['min_price_allowed'] ?? 0);
    }

    /**
     * Get maximum price allowed for vendors (0 = no limit)
     *
     * @return float
     */
    public static function get_max_price() {
        $permissions = self::get_all();
        return (float) ($permissions['max_price_allowed'] ?? 0);
    }

    /**
     * Check if bookings require admin approval
     *
     * @return bool
     */
    public static function require_approval() {
        return self::can('require_approval');
    }

    /**
     * Validate a price against min/max constraints
     *
     * @param float $price Price to validate
     * @return float Validated price (clamped if necessary)
     */
    public static function validate_price($price) {
        $price = (float) $price;
        $min = self::get_min_price();
        $max = self::get_max_price();

        if ($min > 0 && $price < $min) {
            $price = $min;
        }

        if ($max > 0 && $price > $max) {
            $price = $max;
        }

        return $price;
    }

    /**
     * Get allowed booking modes (union of all enabled platform categories)
     *
     * @return array
     */
    public static function get_allowed_modes() {
        $modes = [];
        foreach (WAHRB_Platform_Categories::get_enabled() as $slug => $cat) {
            $cat_modes = WAHRB_Platform_Categories::get_booking_modes($slug);
            $modes = array_merge($modes, $cat_modes);
        }
        return array_unique($modes);
    }

    /**
     * Check if a specific booking mode is allowed
     *
     * @param string $mode Mode to check (day, slot, service)
     * @return bool
     */
    public static function is_mode_allowed($mode) {
        return in_array($mode, self::get_allowed_modes(), true);
    }

    /**
     * Check if slot mode is enabled (derived from platform categories)
     *
     * @return bool
     */
    public static function is_slot_mode_enabled() {
        return in_array('slot', self::get_allowed_modes(), true);
    }

    /**
     * Check if service mode is enabled (derived from platform categories)
     *
     * @return bool
     */
    public static function is_service_mode_enabled() {
        return in_array('service', self::get_allowed_modes(), true);
    }

    /**
     * Get per-category permissions
     *
     * @param string $category_slug Platform category slug
     * @return array Merged permissions (base + category overrides)
     */
    public static function get_for_category($category_slug) {
        $base = self::get_all();
        $cat_overrides = $base['categories'][$category_slug] ?? [];
        
        // Merge: category overrides take precedence over base
        $merged = $base;
        unset($merged['categories']);
        
        foreach ($cat_overrides as $key => $value) {
            $merged[$key] = $value;
        }
        
        return $merged;
    }

    /**
     * Check a permission for a specific category
     *
     * @param string $permission Permission key
     * @param string $category_slug Platform category slug
     * @return bool
     */
    public static function can_for_category($permission, $category_slug) {
        $perms = self::get_for_category($category_slug);
        return !empty($perms[$permission]);
    }

    /**
     * Get price limits for a specific category
     *
     * @param string $category_slug Platform category slug
     * @return array ['min' => float, 'max' => float]
     */
    public static function get_price_limits_for_category($category_slug) {
        $perms = self::get_for_category($category_slug);
        return [
            'min' => (float) ($perms['min_price_allowed'] ?? 0),
            'max' => (float) ($perms['max_price_allowed'] ?? 0),
        ];
    }

    /**
     * Check if vendor can customize slot duration
     *
     * @return bool
     */
    public static function can_customize_slot_duration() {
        return self::can('can_customize_slot_duration');
    }

    /**
     * Check if vendor can customize business hours
     *
     * @return bool
     */
    public static function can_customize_business_hours() {
        return self::can('can_customize_business_hours');
    }

    /**
     * Get allowed slot durations (in minutes)
     *
     * @return array
     */
    public static function get_allowed_slot_durations() {
        $permissions = self::get_all();
        return $permissions['allowed_slot_durations'] ?? [30, 60, 90, 120, 180, 240];
    }

    /**
     * Check if vendor can customize service duration
     *
     * @return bool
     */
    public static function can_customize_service_duration() {
        return self::can('can_customize_service_duration');
    }

    /**
     * Check if vendor can customize capacity
     *
     * @return bool
     */
    public static function can_customize_capacity() {
        return self::can('can_customize_capacity');
    }

    /**
     * Get allowed service durations (in minutes)
     *
     * @return array
     */
    public static function get_allowed_service_durations() {
        $permissions = self::get_all();
        return $permissions['allowed_service_durations'] ?? [15, 30, 45, 60, 90, 120];
    }

    /**
     * Get maximum capacity allowed
     *
     * @return int
     */
    public static function get_max_capacity() {
        $permissions = self::get_all();
        return (int) ($permissions['max_capacity_allowed'] ?? 50);
    }

    /**
     * Check if admin defaults should be used for new products
     *
     * @return bool
     */
    public static function use_admin_defaults() {
        return self::can('use_admin_defaults');
    }

    /**
     * Get admin default values for new product initialization
     *
     * @return array
     */
    public static function get_admin_defaults() {
        $booking_settings = get_option('wahrb_settings_booking', []);
        
        return [
            // Slot mode defaults
            'slot_duration_minutes'     => $booking_settings['default_slot_duration_minutes'] ?? 60,
            'min_duration_hours'        => $booking_settings['default_min_duration_hours'] ?? 1,
            'max_duration_hours'        => $booking_settings['default_max_duration_hours'] ?? 8,
            'business_hours_start'      => $booking_settings['default_business_hours_start'] ?? '09:00',
            'business_hours_end'        => $booking_settings['default_business_hours_end'] ?? '18:00',
            // Service mode defaults
            'service_duration_minutes'  => $booking_settings['default_service_duration_minutes'] ?? 60,
            'capacity_per_slot'         => $booking_settings['default_capacity_per_slot'] ?? 1,
            // Day mode defaults
            'min_duration_days'         => $booking_settings['default_min_stay_days'] ?? 1,
            'max_duration_days'         => $booking_settings['default_max_stay_days'] ?? 90,
        ];
    }

    /**
     * Get permissions for JavaScript (wizard)
     *
     * @return array
     */
    public static function get_js_config() {
        $base = [
            // Pricing permissions
            'can_set_prices'            => self::can_set_prices(),
            'can_set_cancellation'      => self::can_set_cancellation_policy(),
            'can_set_deposit'           => self::can_set_deposit(),
            'can_set_security_deposit'  => self::can_set_security_deposit(),
            'min_price'                 => self::get_min_price(),
            'max_price'                 => self::get_max_price(),
            'require_approval'          => self::require_approval(),
            // Mode permissions (derived from platform categories)
            'allowed_modes'             => self::get_allowed_modes(),
            'slot_mode_enabled'         => self::is_slot_mode_enabled(),
            'service_mode_enabled'      => self::is_service_mode_enabled(),
            // Slot customization
            'can_customize_slot_duration' => self::can_customize_slot_duration(),
            'can_customize_business_hours' => self::can_customize_business_hours(),
            'allowed_slot_durations'    => self::get_allowed_slot_durations(),
            // Service customization
            'can_customize_service_duration' => self::can_customize_service_duration(),
            'can_customize_capacity'    => self::can_customize_capacity(),
            'allowed_service_durations' => self::get_allowed_service_durations(),
            'max_capacity'              => self::get_max_capacity(),
            // Defaults
            'use_admin_defaults'        => self::use_admin_defaults(),
            'admin_defaults'            => self::get_admin_defaults(),
        ];

        // Add per-category permissions for enabled categories
        $enabled = WAHRB_Platform_Categories::get_enabled();
        $per_category = [];
        foreach ($enabled as $slug => $cat) {
            $cat_perms = self::get_for_category($slug);
            $per_category[$slug] = [
                'can_set_prices'           => !empty($cat_perms['can_set_own_prices']),
                'can_set_deposit'          => !empty($cat_perms['can_set_deposit_amount']),
                'can_set_security_deposit' => !empty($cat_perms['can_set_security_deposit']),
                'min_price'                => (float) ($cat_perms['min_price_allowed'] ?? 0),
                'max_price'                => (float) ($cat_perms['max_price_allowed'] ?? 0),
                'require_approval'         => !empty($cat_perms['require_approval']),
            ];
        }
        $base['categories'] = $per_category;

        return $base;
    }

    /**
     * Clear cached permissions (useful after settings update)
     */
    public static function clear_cache() {
        self::$permissions = null;
    }
}
