<?php
namespace App\Controllers;

use App\Services\AuthService;
use App\Services\PayrollIntegrationService;
use App\Utils\DateNormalizer;
use App\Utils\Sanitizer;

class PayrollController extends ApiController
{
    private $payrollService;
    private $authService;

    public function __construct(
        PayrollIntegrationService $payrollService,
        AuthService $authService
    ) {
        $this->payrollService = $payrollService;
        $this->authService = $authService;
    }

    public function aggregateMonthlyPayouts()
    {
        $this->assertManagerAccess(['commissions.ledger.calculate']);
        $billingMonth = Sanitizer::sanitize($_POST['billing_month'] ?? DateNormalizer::currentJalaliMonth());
        $payrollDay = (int)($_POST['payroll_day'] ?? 30);
        $managerId = (int)($_SESSION['user_id'] ?? 0);
        try {
            $rows = $this->payrollService->aggregateMonthlySettledCommissions($billingMonth, $managerId, $payrollDay);
            $this->successResponse(['cycles' => $rows], 'چرخه‌های پورسانت ایجاد/به‌روزرسانی شد');
        } catch (\InvalidArgumentException $e) {
            $this->errorResponse($e->getMessage(), 422);
        }
    }

    public function getPayoutQueue()
    {
        $this->assertManagerAccess(['commissions.view']);
        $filters = [
            'billing_month' => Sanitizer::sanitize($_POST['billing_month'] ?? $_GET['billing_month'] ?? ''),
            'status' => Sanitizer::sanitize($_POST['status'] ?? $_GET['status'] ?? ''),
            'salesperson_name' => Sanitizer::sanitize($_POST['salesperson_name'] ?? $_GET['salesperson_name'] ?? ''),
            'amount_min' => $_POST['amount_min'] ?? $_GET['amount_min'] ?? '',
            'amount_max' => $_POST['amount_max'] ?? $_GET['amount_max'] ?? '',
        ];
        $applySlaRaw = $_POST['apply_sla'] ?? $_GET['apply_sla'] ?? '1';
        $applySla = !in_array(strtolower(trim((string)$applySlaRaw)), ['0', 'false', 'no', 'off'], true);
        $includeLinesRaw = $_POST['include_lines'] ?? $_GET['include_lines'] ?? '0';
        $includeLines = in_array(strtolower(trim((string)$includeLinesRaw)), ['1', 'true', 'yes', 'on'], true);
        $rows = $this->payrollService->getManagerQueueAdvanced($filters, $applySla, $includeLines);
        $this->successResponse(['cycles' => $rows]);
    }

    public function getCommissionDrilldown()
    {
        $this->assertManagerAccess(['commissions.view']);
        $filters = [
            'cycle_id' => (int)($_POST['cycle_id'] ?? $_GET['cycle_id'] ?? 0),
            'metric' => Sanitizer::sanitize($_POST['metric'] ?? $_GET['metric'] ?? 'all'),
            'line_status' => Sanitizer::sanitize($_POST['line_status'] ?? $_GET['line_status'] ?? ''),
            'beneficiary_type' => Sanitizer::sanitize($_POST['beneficiary_type'] ?? $_GET['beneficiary_type'] ?? ''),
            'payment_kind' => Sanitizer::sanitize($_POST['payment_kind'] ?? $_GET['payment_kind'] ?? ''),
            'rule_id' => (int)($_POST['rule_id'] ?? $_GET['rule_id'] ?? 0),
        ];

        try {
            $drilldown = $this->payrollService->getCommissionDrilldown($filters);
            $this->successResponse(['drilldown' => $drilldown], 'جزئیات محاسبه پورسانت آماده شد');
        } catch (\InvalidArgumentException $e) {
            $this->errorResponse($e->getMessage(), 422);
        } catch (\Throwable $e) {
            $this->errorResponse('خطا در دریافت جزئیات پورسانت', 500);
        }
    }

    public function decidePayout()
    {
        $this->assertManagerAccess(['commissions.status.manage']);
        $cycleId = (int)($_POST['cycle_id'] ?? 0);
        $action = Sanitizer::sanitize($_POST['action'] ?? '');
        $reason = trim((string)($_POST['override_reason'] ?? $_POST['reason'] ?? ''));
        $overrideAmountRaw = $_POST['override_amount'] ?? null;
        $overrideAmount = ($overrideAmountRaw === null || $overrideAmountRaw === '') ? null : (float)$overrideAmountRaw;
        $managerId = (int)($_SESSION['user_id'] ?? 0);

        $normalizedAction = strtoupper(trim($action));
        if (in_array($normalizedAction, ['APPROVE', 'OVERRIDE', 'REJECT'], true)) {
            $cycle = $this->payrollService->decidePayoutCycle($cycleId, $normalizedAction, $managerId, $overrideAmount, $reason);
        } else {
            $cycle = $this->payrollService->advancePayoutCycle($cycleId, $normalizedAction, $managerId, $reason);
        }
        $this->successResponse(['cycle' => $cycle->toArray()], 'وضعیت چرخه با موفقیت ثبت شد');
    }

    private function assertManagerAccess(array $alternateCapabilities = []): void
    {
        $role = trim((string)($_SESSION['role'] ?? ''));
        if (in_array($role, ['admin', 'system'], true) || $this->hasDelegatedCapability('payroll.admin.manage')) {
            return;
        }
        foreach ($alternateCapabilities as $capabilityKey) {
            if ($this->hasDelegatedCapability((string)$capabilityKey)) {
                return;
            }
        }
        $this->errorResponse('دسترسی محدود', 403);
    }
}
