<?php
namespace App\Controllers;

use App\Services\CommissionService;
use App\Services\AuthService;
use App\Repositories\UserRepository;
use App\Utils\Sanitizer;

class CommissionController extends ApiController
{
    private $commissionService;
    private $authService;
    private $userRepo;

    public function __construct(
        CommissionService $commissionService,
        AuthService $authService,
        UserRepository $userRepo
    ) {
        $this->commissionService = $commissionService;
        $this->authService = $authService;
        $this->userRepo = $userRepo;
    }

    public function getRules()
    {
        $selfOnly = (($_SESSION['role'] ?? '') === 'agent') && !$this->authService->isAdminOrCrmSpecialist();
        if (!$selfOnly) {
            $this->assertAdminOrCrm();
        }
        $rules = array_map(function ($rule) use ($selfOnly) {
            $payload = $rule->toArray();
            if ($selfOnly) {
                $payload['target_users'] = [];
            }
            return $payload;
        }, $this->commissionService->getRules());
        $this->successResponse(['rules' => $rules]);
    }

    public function getMyLedger()
    {
        if (!$this->authService->isAuthenticated()) {
            $this->errorResponse('دسترسی محدود', 403);
        }
        $userId = (int)($_SESSION['user_id'] ?? 0);
        if ($userId <= 0) {
            $this->errorResponse('کاربر معتبر نیست', 422);
        }
        $rows = array_map(static function ($row) {
            return $row->toArray();
        }, $this->commissionService->getUserLedger($userId));
        $this->successResponse(['ledger' => $rows]);
    }

    public function storeRule()
    {
        $this->assertAdminOrCrm();
        error_log('[store_commission_rule] payload=' . print_r($_POST, true));

        $targetUsers = $_POST['target_users'] ?? '[]';
        $salespersonRaw = $_POST['salesperson_user_id'] ?? null;
        $salespersonId = null;
        if ($salespersonRaw !== null && $salespersonRaw !== '') {
            $salespersonId = (int)$salespersonRaw;
            if ($salespersonId <= 0) {
                $salespersonId = null;
            }
        }
        $payload = [
            'id' => (int)($_POST['id'] ?? 0),
            'rule_type' => Sanitizer::sanitize($_POST['rule_type'] ?? 'TIERED_CASHFLOW'),
            'kpi_source' => Sanitizer::sanitize($_POST['kpi_source'] ?? ''),
            'target_users' => $targetUsers,
            'salesperson_user_id' => $salespersonId,
            'requested_services' => $_POST['requested_services'] ?? '[]',
            'kpi_min_threshold' => (float)($_POST['kpi_min_threshold'] ?? 0),
            'kpi_max_threshold' => (float)($_POST['kpi_max_threshold'] ?? 0),
            'base_amount' => (float)($_POST['base_amount'] ?? 0),
            'reward_percentage' => (float)($_POST['reward_percentage'] ?? 0),
            'status' => Sanitizer::sanitize($_POST['status'] ?? 'active'),
            'tiers' => $_POST['tiers'] ?? '[]',
        ];

        if ($payload['kpi_max_threshold'] <= $payload['kpi_min_threshold']) {
            $this->errorResponse('حداکثر آستانه باید از حداقل بزرگ‌تر باشد', 422);
        }
        if ($payload['reward_percentage'] < 0 || $payload['reward_percentage'] > 100) {
            $this->errorResponse('درصد پاداش باید بین 0 تا 100 باشد', 422);
        }

        if ($salespersonId !== null && !$this->userRepo->findById($salespersonId)) {
            $this->errorResponse('کاربر انتخاب شده نامعتبر است', 422);
        }

        $decodedTargets = json_decode((string)$targetUsers, true);
        $targetIds = is_array($decodedTargets) ? $decodedTargets : [];
        if ($salespersonId !== null) {
            $targetIds = [$salespersonId];
            $payload['target_users'] = json_encode([$salespersonId], JSON_UNESCAPED_UNICODE);
        }
        $numericTargets = array_values(array_filter(array_map('intval', $targetIds), static function ($id) {
            return $id > 0;
        }));
        foreach ($numericTargets as $targetId) {
            if (!$this->userRepo->findById($targetId)) {
                $this->errorResponse('کاربر انتخاب شده نامعتبر است', 422);
            }
        }

        try {
            $id = $this->commissionService->saveRule($payload);
            $this->successResponse(['id' => $id], 'قانون کمیسیون ذخیره شد');
        } catch (\PDOException $e) {
            $message = (string)$e->getMessage();
            error_log('[store_commission_rule][pdo_exception] ' . $message);
            $isFkViolation = strpos($message, 'Integrity constraint violation') !== false
                || strpos($message, 'SQLSTATE[23000]') !== false;
            $isSalespersonFk = strpos($message, 'commission_rules_ibfk_1') !== false
                || strpos($message, 'salesperson_user_id') !== false;
            if ($isFkViolation && $isSalespersonFk) {
                $this->errorResponse('کاربر انتخاب شده نامعتبر است', 422);
            }
            $this->errorResponse('خطای پایگاه داده در ذخیره قانون پورسانت', 500);
        } catch (\InvalidArgumentException $e) {
            $this->errorResponse($e->getMessage(), 422);
        } catch (\Throwable $e) {
            $this->errorResponse('خطا در ذخیره قانون پورسانت', 500);
        }
    }

    public function evaluate()
    {
        $this->assertAdminOrCrm();

        $userId = (int)($_POST['user_id'] ?? 0);
        $kpiScore = (float)($_POST['kpi_score'] ?? 0);
        $kpiSource = Sanitizer::sanitize($_POST['kpi_source'] ?? '');
        if ($userId <= 0 || $kpiSource === '') {
            $this->errorResponse('کاربر، منبع KPI و امتیاز الزامی هستند', 422);
        }

        $result = $this->commissionService->evaluateUserCommissions($userId, $kpiScore, $kpiSource);
        $this->successResponse(['results' => $result]);
    }

    public function getSetupData()
    {
        $selfOnly = (($_SESSION['role'] ?? '') === 'agent') && !$this->authService->isAdminOrCrmSpecialist();
        if (!$selfOnly) {
            $this->assertAdminOrCrm();
        }
        $allUsers = $this->userRepo->getAll();
        if ($selfOnly) {
            $currentId = (int)($_SESSION['user_id'] ?? 0);
            $allUsers = array_values(array_filter($allUsers, static function ($u) use ($currentId) {
                return (int)($u->id ?? 0) === $currentId;
            }));
        }
        $users = array_map(static function ($user) {
            return [
                'id' => (int)$user->id,
                'display_name' => trim((string)($user->display_name ?: ($user->first_name . ' ' . $user->last_name))),
                'is_active' => (int)$user->is_active,
                'role' => (string)$user->role,
            ];
        }, $allUsers);

        $this->successResponse([
            'users' => $users,
            'kpi_sources' => ['kpi_calls', 'kpi_meetings', 'kpi_sales_volume', 'kpi_followups'],
        ]);
    }

    private function assertAdminOrCrm(): void
    {
        if (!$this->authService->isAdminOrCrmSpecialist()) {
            $this->errorResponse('دسترسی محدود', 403);
        }
    }
}
