<?php
/**
 * PENALTY SETTINGS MODEL - DAY-BASED VERSION
 * File: app/Models/PenaltySettings.php
 * 
 * UPDATED: Day-based penalty calculation (1-7+ days)
 */

class PenaltySettings {
    private $db;
    
    public function __construct() {
        $this->db = Database::getInstance();
    }
    
    /**
     * Get current penalty settings
     * @return array|null
     */
    public function getSettings() {
        return $this->db->fetch("SELECT * FROM penalty_settings ORDER BY id DESC LIMIT 1");
    }
    
    /**
     * Update penalty settings
     * @param array $data
     * @return bool
     */
    public function updateSettings($data) {
        // Check if settings exist
        $existing = $this->getSettings();
        
        if ($existing) {
            // Update existing settings
            return $this->db->execute("
                UPDATE penalty_settings 
                SET penalty_source = ?,
                    penalty_7plus_days = ?,
                    penalty_6_days = ?,
                    penalty_5_days = ?,
                    penalty_4_days = ?,
                    penalty_3_days = ?,
                    penalty_2_days = ?,
                    penalty_1_day = ?,
                    penalty_same_day = ?,
                    admin_commission_from_penalty = ?,
                    updated_by = ?,
                    updated_at = NOW()
                WHERE id = ?
            ", [
                $data['penalty_source'],
                $data['penalty_7plus_days'] ?? 0.00,
                $data['penalty_6_days'] ?? 0.00,
                $data['penalty_5_days'] ?? 0.00,
                $data['penalty_4_days'] ?? 0.00,
                $data['penalty_3_days'] ?? 0.00,
                $data['penalty_2_days'] ?? 20.00,
                $data['penalty_1_day'] ?? 50.00,
                $data['penalty_same_day'] ?? 100.00,
                $data['admin_commission_from_penalty'],
                $data['updated_by'],
                $existing['id']
            ]);
        } else {
            // Create new settings
            return $this->db->execute("
                INSERT INTO penalty_settings 
                (penalty_source, penalty_7plus_days, penalty_6_days, penalty_5_days, penalty_4_days,
                 penalty_3_days, penalty_2_days, penalty_1_day, penalty_same_day,
                 admin_commission_from_penalty, updated_by)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ", [
                $data['penalty_source'],
                $data['penalty_7plus_days'] ?? 0.00,
                $data['penalty_6_days'] ?? 0.00,
                $data['penalty_5_days'] ?? 0.00,
                $data['penalty_4_days'] ?? 0.00,
                $data['penalty_3_days'] ?? 0.00,
                $data['penalty_2_days'] ?? 20.00,
                $data['penalty_1_day'] ?? 50.00,
                $data['penalty_same_day'] ?? 100.00,
                $data['admin_commission_from_penalty'],
                $data['updated_by']
            ]);
        }
    }
    
    /**
     * Calculate penalty based on DAYS until start date
     * @param float $rental_amount (excluding security deposit)
     * @param string $start_date Order start date
     * @param int|null $vendor_id For Phase 2 - get vendor-specific penalty
     * @return array ['penalty_percentage', 'penalty_amount', 'vendor_share', 'admin_share', 'days_until_start']
     */
    public function calculatePenalty($rental_amount, $start_date, $vendor_id = null) {
        $settings = $this->getSettings();
        
        if (!$settings) {
            // No settings found - return no penalty
            return [
                'penalty_percentage' => 0,
                'penalty_amount' => 0,
                'vendor_share' => 0,
                'admin_share' => 0,
                'timing' => 'no_settings',
                'days_until_start' => 0
            ];
        }
        
        // Calculate DAYS until start date (not hours)
        $now = new DateTime();
        $start = new DateTime($start_date);
        
        // Set time to midnight for accurate day calculation
        $now->setTime(0, 0, 0);
        $start->setTime(0, 0, 0);
        
        $interval = $now->diff($start);
        $days_until_start = (int)$interval->days;
        
        // If start date is in the past, it's a no-show
        if ($start < $now) {
            $days_until_start = 0;
        }
        
        // Determine penalty percentage based on days
        $penalty_percentage = 0;
        $timing = '';
        
        if ($days_until_start >= 7) {
            // 7+ days before
            $penalty_percentage = $settings['penalty_7plus_days'];
            $timing = '7plus_days';
        } elseif ($days_until_start == 6) {
            $penalty_percentage = $settings['penalty_6_days'];
            $timing = '6_days';
        } elseif ($days_until_start == 5) {
            $penalty_percentage = $settings['penalty_5_days'];
            $timing = '5_days';
        } elseif ($days_until_start == 4) {
            $penalty_percentage = $settings['penalty_4_days'];
            $timing = '4_days';
        } elseif ($days_until_start == 3) {
            $penalty_percentage = $settings['penalty_3_days'];
            $timing = '3_days';
        } elseif ($days_until_start == 2) {
            $penalty_percentage = $settings['penalty_2_days'];
            $timing = '2_days';
        } elseif ($days_until_start == 1) {
            $penalty_percentage = $settings['penalty_1_day'];
            $timing = '1_day';
        } else {
            // Same day or past (0 days)
            $penalty_percentage = $settings['penalty_same_day'];
            $timing = 'same_day';
        }
        
        // If using vendor-set penalties (Phase 2)
        if ($settings['penalty_source'] === 'vendor' && $vendor_id) {
            $vendor_penalty = $this->db->fetch("
                SELECT vendor_penalty_percentage 
                FROM items 
                WHERE vendor_id = ? AND vendor_penalty_percentage IS NOT NULL
                LIMIT 1
            ", [$vendor_id]);
            
            if ($vendor_penalty && $vendor_penalty['vendor_penalty_percentage'] !== null) {
                $penalty_percentage = $vendor_penalty['vendor_penalty_percentage'];
                $timing = 'vendor_set';
            }
        }
        
        // Calculate penalty amount
        $penalty_amount = ($rental_amount * $penalty_percentage) / 100;
        
        // Calculate admin commission from penalty
        $admin_commission_percentage = $settings['admin_commission_from_penalty'];
        $admin_share = ($penalty_amount * $admin_commission_percentage) / 100;
        $vendor_share = $penalty_amount - $admin_share;
        
        return [
            'penalty_percentage' => $penalty_percentage,
            'penalty_amount' => $penalty_amount,
            'vendor_share' => $vendor_share,
            'admin_share' => $admin_share,
            'timing' => $timing,
            'days_until_start' => $days_until_start
        ];
    }
    
    /**
     * Get penalty settings as JSON for JavaScript
     * @return string JSON
     */
    public function getSettingsJSON() {
        $settings = $this->getSettings();
        
        if (!$settings) {
            return json_encode([
                'penalty_7plus_days' => 0,
                'penalty_6_days' => 0,
                'penalty_5_days' => 0,
                'penalty_4_days' => 0,
                'penalty_3_days' => 0,
                'penalty_2_days' => 20,
                'penalty_1_day' => 50,
                'penalty_same_day' => 100
            ]);
        }
        
        return json_encode([
            'penalty_7plus_days' => floatval($settings['penalty_7plus_days']),
            'penalty_6_days' => floatval($settings['penalty_6_days']),
            'penalty_5_days' => floatval($settings['penalty_5_days']),
            'penalty_4_days' => floatval($settings['penalty_4_days']),
            'penalty_3_days' => floatval($settings['penalty_3_days']),
            'penalty_2_days' => floatval($settings['penalty_2_days']),
            'penalty_1_day' => floatval($settings['penalty_1_day']),
            'penalty_same_day' => floatval($settings['penalty_same_day'])
        ]);
    }
    
    /**
     * Get penalty policy text for display
     * @return string
     */
    public function getPolicyText() {
        $settings = $this->getSettings();
        
        if (!$settings) {
            return "No cancellation policy set.";
        }
        
        return "
        <strong>Cancellation Policy:</strong>
        <ul>
            <li>7+ days before rental: <strong>" . number_format($settings['penalty_7plus_days']) . "%</strong> penalty</li>
            <li>6 days before: <strong>" . number_format($settings['penalty_6_days']) . "%</strong> penalty</li>
            <li>5 days before: <strong>" . number_format($settings['penalty_5_days']) . "%</strong> penalty</li>
            <li>4 days before: <strong>" . number_format($settings['penalty_4_days']) . "%</strong> penalty</li>
            <li>3 days before: <strong>" . number_format($settings['penalty_3_days']) . "%</strong> penalty</li>
            <li>2 days before: <strong>" . number_format($settings['penalty_2_days']) . "%</strong> penalty</li>
            <li>1 day before: <strong>" . number_format($settings['penalty_1_day']) . "%</strong> penalty</li>
            <li>Same day: <strong>" . number_format($settings['penalty_same_day']) . "%</strong> penalty</li>
        </ul>
        <small class='text-muted'>Penalty applies to rental amount only, not security deposit.</small>
        ";
    }
}