<?php
namespace App\Services;

use App\Models\CommissionRule;
use App\Repositories\CommissionRuleRepository;
use App\Repositories\CommissionLedgerRepository;
use App\Utils\Logger;

class CommissionService
{
    private $ruleRepo;
    private $ledgerRepo;

    public function __construct(
        CommissionRuleRepository $ruleRepo,
        CommissionLedgerRepository $ledgerRepo
    ) {
        $this->ruleRepo = $ruleRepo;
        $this->ledgerRepo = $ledgerRepo;
    }

    public function getRules(array $filters = []): array
    {
        return $this->ruleRepo->getAll($filters);
    }

    public function saveRule(array $data): int
    {
        $title = trim((string)($data['title'] ?? ''));
        $kpiSource = trim((string)($data['kpi_source'] ?? ''));
        $targetUsersRaw = $data['target_users'] ?? [];
        $min = (float)($data['kpi_min_threshold'] ?? 0);
        $max = (float)($data['kpi_max_threshold'] ?? 0);
        $baseAmount = (float)($data['base_amount'] ?? 0);
        $rewardPercentage = (float)($data['reward_percentage'] ?? 0);
        $status = trim((string)($data['status'] ?? 'active'));

        if ($kpiSource === '') {
            throw new \InvalidArgumentException('منبع KPI الزامی است');
        }
        if ($title === '') {
            $title = 'Rule-' . $kpiSource . '-' . date('YmdHis');
        }
        if ($max <= $min) {
            throw new \InvalidArgumentException('حداکثر آستانه باید از حداقل بزرگ‌تر باشد');
        }
        if ($rewardPercentage <= 0 || $rewardPercentage > 100) {
            throw new \InvalidArgumentException('درصد پاداش باید بین 1 تا 100 باشد');
        }

        if (is_string($targetUsersRaw)) {
            $decoded = json_decode($targetUsersRaw, true);
            $targetUsers = is_array($decoded) ? $decoded : [];
        } elseif (is_array($targetUsersRaw)) {
            $targetUsers = $targetUsersRaw;
        } else {
            $targetUsers = [];
        }
        if (empty($targetUsers)) {
            $targetUsers = ['ALL'];
        }

        $rule = new CommissionRule([
            'id' => isset($data['id']) ? (int)$data['id'] : null,
            'title' => $title,
            'kpi_source' => $kpiSource,
            'target_users' => $targetUsers,
            'kpi_min_threshold' => $min,
            'kpi_max_threshold' => $max,
            'base_amount' => $baseAmount,
            'reward_percentage' => $rewardPercentage,
            'status' => in_array($status, ['active', 'inactive'], true) ? $status : 'active',
        ]);

        return $this->ruleRepo->save($rule);
    }

    public function evaluateUserCommissions(int $userId, float $kpiScore, string $kpiSource): array
    {
        if ($userId <= 0) {
            throw new \InvalidArgumentException('شناسه کاربر نامعتبر است');
        }
        $kpiSource = trim($kpiSource);
        if ($kpiSource === '') {
            throw new \InvalidArgumentException('منبع KPI الزامی است');
        }

        $pdo = $this->ledgerRepo->getDb()->getPdo();
        $rules = $this->ruleRepo->findActiveByKpiSource($kpiSource);
        $results = [];

        try {
            $pdo->beginTransaction();
            foreach ($rules as $rule) {
                $targets = $rule->getTargetUsersArray();
                $appliesToAll = in_array('ALL', $targets, true);
                $appliesToUser = in_array($userId, array_map('intval', $targets), true);
                if (!$appliesToAll && !$appliesToUser) {
                    continue;
                }

                $min = (float)$rule->kpi_min_threshold;
                $max = (float)$rule->kpi_max_threshold;
                if ($kpiScore < $min || $kpiScore > $max) {
                    continue;
                }

                $baseAmount = (float)$rule->base_amount;
                $rewardPercentage = (float)$rule->reward_percentage;
                $finalAmount = round($baseAmount * ($rewardPercentage / 100), 2);

                $ledgerId = $this->ledgerRepo->store([
                    'user_id' => $userId,
                    'rule_id' => (int)$rule->id,
                    'kpi_score_recorded' => $kpiScore,
                    'calculated_amount' => $finalAmount,
                    'calculation_date' => date('Y-m-d H:i:s'),
                ]);

                $results[] = [
                    'ledger_id' => $ledgerId,
                    'rule_id' => (int)$rule->id,
                    'rule_title' => (string)$rule->title,
                    'kpi_score_recorded' => $kpiScore,
                    'calculated_amount' => $finalAmount,
                ];
            }
            $pdo->commit();
            return $results;
        } catch (\Throwable $e) {
            if ($pdo->inTransaction()) {
                $pdo->rollBack();
            }
            Logger::logError('COMMISSION_EVALUATION_FAILED', $e, [
                'user_id' => $userId,
                'kpi_source' => $kpiSource,
                'kpi_score' => $kpiScore,
            ]);
            throw $e;
        }
    }

    public function getUserLedger(int $userId): array
    {
        return $this->ledgerRepo->getByUser($userId);
    }

    // Compatibility no-op methods to avoid breaking existing call sites during migration window.
    public function calculateAndStoreForWonDeal(string $dealDidarId)
    {
        return null;
    }

    public function calculateAndCreateForDeal(string $dealDidarId)
    {
        return null;
    }
}
