<?php
/**
 * Discount Codes Management
 * سیستم کدهای تخفیف
 */

namespace GemAcc;

use PDO;

class DiscountCode
{
    private PDO $pdo;
    
    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }
    
    /**
     * ایجاد کد تخفیف جدید
     */
    public function create(array $data): int
    {
        $stmt = $this->pdo->prepare("
            INSERT INTO discount_codes 
            (code, type, value, min_purchase, max_discount, max_uses, max_uses_per_user, valid_from, valid_until, payment_scope, created_by)
            VALUES (:code, :type, :value, :min, :max_disc, :max_uses, :max_per_user, :valid_from, :valid_until, :payment_scope, :created_by)
        ");
        
        $stmt->execute([
            ':code'         => strtoupper(trim($data['code'])),
            ':type'         => $data['type'] ?? 'PERCENT',
            ':value'        => (int)($data['value'] ?? 0),
            ':min'          => (int)($data['min_purchase'] ?? 0),
            ':max_disc'     => $data['max_discount'] ?? null,
            ':max_uses'     => $data['max_uses'] ?? null,
            ':max_per_user' => (int)($data['max_uses_per_user'] ?? 1),
            ':valid_from'   => $data['valid_from'] ?? null,
            ':valid_until'  => $data['valid_until'] ?? null,
            ':payment_scope' => in_array(($data['payment_scope'] ?? 'all'), ['all','card','crypto'], true) ? $data['payment_scope'] : 'all',
            ':created_by'   => $data['created_by'] ?? null,
        ]);
        
        return (int)$this->pdo->lastInsertId();
    }
    
    /**
     * گرفتن کد تخفیف با کد
     */
    public function getByCode(string $code): ?array
    {
        $stmt = $this->pdo->prepare("SELECT * FROM discount_codes WHERE code = ?");
        $stmt->execute([strtoupper(trim($code))]);
        return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    }
    
    /**
     * گرفتن کد تخفیف با آیدی
     */
    public function getById(int $id): ?array
    {
        $stmt = $this->pdo->prepare("SELECT * FROM discount_codes WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    }
    
    /**
     * گرفتن همه کدهای تخفیف
     */
    public function getAll(): array
    {
        $stmt = $this->pdo->query("SELECT * FROM discount_codes ORDER BY created_at DESC");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * گرفتن کدهای فعال
     */
    public function getActive(): array
    {
        $stmt = $this->pdo->query("
            SELECT * FROM discount_codes 
            WHERE is_active = 1 
            AND (valid_from IS NULL OR valid_from <= NOW())
            AND (valid_until IS NULL OR valid_until >= NOW())
            AND (max_uses IS NULL OR used_count < max_uses)
            ORDER BY created_at DESC
        ");
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }
    
    /**
     * بررسی اعتبار کد تخفیف برای کاربر
     * @return array ['valid' => bool, 'message' => string, 'discount' => ?array]
     */
    public function validate(string $code, int $userId, int $purchaseAmount): array
    {
        $discount = $this->getByCode($code);
        
        if (!$discount) {
            return ['valid' => false, 'message' => 'کد تخفیف یافت نشد', 'discount' => null];
        }
        
        if (!$discount['is_active']) {
            return ['valid' => false, 'message' => 'کد تخفیف غیرفعال است', 'discount' => null];
        }
        
        // بررسی تاریخ شروع
        if ($discount['valid_from'] && strtotime($discount['valid_from']) > time()) {
            return ['valid' => false, 'message' => 'کد تخفیف هنوز فعال نشده', 'discount' => null];
        }
        
        // بررسی تاریخ پایان
        if ($discount['valid_until'] && strtotime($discount['valid_until']) < time()) {
            return ['valid' => false, 'message' => 'کد تخفیف منقضی شده', 'discount' => null];
        }
        
        // بررسی حداکثر استفاده کل
        if ($discount['max_uses'] !== null && $discount['used_count'] >= $discount['max_uses']) {
            return ['valid' => false, 'message' => 'ظرفیت استفاده از این کد تمام شده', 'discount' => null];
        }
        
        // بررسی حداقل مبلغ خرید
        if ($discount['min_purchase'] > 0 && $purchaseAmount < $discount['min_purchase']) {
            return [
                'valid' => false, 
                'message' => 'حداقل مبلغ خرید برای این کد ' . number_format($discount['min_purchase']) . ' تومان است', 
                'discount' => null
            ];
        }
        
        // بررسی حداکثر استفاده توسط این کاربر
        $userUsage = $this->getUserUsageCount($discount['id'], $userId);
        if ($userUsage >= $discount['max_uses_per_user']) {
            return ['valid' => false, 'message' => 'شما قبلاً از این کد استفاده کرده‌اید', 'discount' => null];
        }
        
        // محاسبه مبلغ تخفیف
        $discountAmount = $this->calculateDiscount($discount, $purchaseAmount);
        
        return [
            'valid'           => true, 
            'message'         => 'کد تخفیف معتبر است',
            'discount'        => $discount,
            'discount_amount' => $discountAmount,
            'final_price'     => $purchaseAmount - $discountAmount,
        ];
    }
    
    /**
     * محاسبه مبلغ تخفیف
     */
    public function calculateDiscount(array $discount, int $purchaseAmount): int
    {
        if ($discount['type'] === 'PERCENT') {
            $discountAmount = (int)floor($purchaseAmount * $discount['value'] / 100);
            
            // اعمال حداکثر تخفیف
            if ($discount['max_discount'] !== null && $discountAmount > $discount['max_discount']) {
                $discountAmount = $discount['max_discount'];
            }
        } else {
            // مبلغ ثابت
            $discountAmount = min($discount['value'], $purchaseAmount);
        }
        
        return $discountAmount;
    }
    
    /**
     * تعداد استفاده کاربر از یک کد
     */
    public function getUserUsageCount(int $discountId, int $userId): int
    {
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) FROM discount_usages 
            WHERE discount_id = ? AND user_id = ?
        ");
        $stmt->execute([$discountId, $userId]);
        return (int)$stmt->fetchColumn();
    }
    
    /**
     * ثبت استفاده از کد تخفیف
     */
    public function recordUsage(int $discountId, int $userId, int $orderId, int $discountAmount): bool
    {
        $this->pdo->beginTransaction();
        
        try {
            // ثبت استفاده
            $stmt = $this->pdo->prepare("
                INSERT INTO discount_usages (discount_id, user_id, order_id, discount_amount)
                VALUES (?, ?, ?, ?)
            ");
            $stmt->execute([$discountId, $userId, $orderId, $discountAmount]);
            
            // افزایش شمارنده
            $stmt = $this->pdo->prepare("
                UPDATE discount_codes SET used_count = used_count + 1 WHERE id = ?
            ");
            $stmt->execute([$discountId]);
            
            $this->pdo->commit();
            return true;
        } catch (\Exception $e) {
            $this->pdo->rollBack();
            return false;
        }
    }
    
    /**
     * فعال/غیرفعال کردن کد
     */
    public function toggle(int $id, bool $active): bool
    {
        $stmt = $this->pdo->prepare("UPDATE discount_codes SET is_active = ? WHERE id = ?");
        return $stmt->execute([$active ? 1 : 0, $id]);
    }
    
    /**
     * حذف کد تخفیف
     */
    public function delete(int $id): bool
    {
        $stmt = $this->pdo->prepare("DELETE FROM discount_codes WHERE id = ?");
        return $stmt->execute([$id]);
    }
    
    /**
     * فرمت نمایش کد تخفیف
     */
    public function formatDiscount(array $discount): string
    {
        if ($discount['type'] === 'PERCENT') {
            $text = $discount['value'] . '٪';
            if ($discount['max_discount']) {
                $text .= ' (حداکثر ' . number_format($discount['max_discount']) . ' تومان)';
            }
        } else {
            $text = number_format($discount['value']) . ' تومان';
        }
        return $text;
    }
}

