<?php
namespace App\Controllers;

use App\Services\KpiService;
use App\Services\AuthService;
use App\Services\CommissionService;
use App\Utils\Logger;

class KpiController extends ApiController
{
    private $kpiService;
    private $authService;
    private $commissionService;

    public function __construct(
        KpiService $kpiService,
        AuthService $authService,
        ?CommissionService $commissionService = null
    ) {
        $this->kpiService = $kpiService;
        $this->authService = $authService;
        $this->commissionService = $commissionService;
    }

    private function canRbac(string $capabilityKey): bool
    {
        global $app;
        if (isset($app->services->rbac) && $app->services->rbac) {
            return (bool)$app->services->rbac->can($capabilityKey);
        }
        return false;
    }

    private function requireRbac(string $capabilityKey, string $message = 'دسترسی محدود'): void
    {
        if (!$this->canRbac($capabilityKey)) {
            $this->errorResponse($message, 403);
        }
    }

    private function getRbacScopeForResource(string $resourceKey): ?array
    {
        global $app;
        if (!isset($app->services->rbac) || !$app->services->rbac) {
            return null;
        }
        return (array)$app->services->rbac->getDataScope($resourceKey);
    }

    private function mapSelectedUserIdsToDidarIds(array $selectedUserIds): array
    {
        global $app;
        if (!isset($app->repositories->user) || !$app->repositories->user) {
            return [];
        }
        $didarIds = [];
        foreach ($selectedUserIds as $uid) {
            $userId = (int)$uid;
            if ($userId <= 0) {
                continue;
            }
            try {
                $user = $app->repositories->user->findById($userId);
                $didar = trim((string)($user->didar_user_id ?? ''));
                if ($didar !== '') {
                    $didarIds[$didar] = true;
                }
            } catch (\Throwable $e) {
                // Ignore invalid user ids in selected_users scope.
            }
        }
        return array_keys($didarIds);
    }

    private function applyOwnerDidarScope(array $requestedOwnerDidarIds, string $resourceKey, string $selfDidarId): array
    {
        $requested = array_values(array_unique(array_filter(array_map(static function ($v) {
            return trim((string)$v);
        }, $requestedOwnerDidarIds), static function ($v) {
            return $v !== '' && strtolower($v) !== 'all';
        })));

        global $app;
        $scope = $this->getRbacScopeForResource($resourceKey);
        if (!$scope) {
            return $requested;
        }

        $scopeType = trim((string)($scope['scope_type'] ?? ''));
        if ($scopeType === '' || $scopeType === 'all') {
            return $requested;
        }

        if ($scopeType === 'self') {
            return $selfDidarId !== '' ? [$selfDidarId] : ['__rbac_scope_none__'];
        }

        if ($scopeType === 'selected_users') {
            $allowed = (isset($app->services->rbac) && $app->services->rbac)
                ? $app->services->rbac->allowedDidarIdsForScope($resourceKey)
                : $this->mapSelectedUserIdsToDidarIds((array)($scope['selected_user_ids'] ?? []));
            if (empty($allowed)) {
                return ['__rbac_scope_none__'];
            }
            if (empty($requested)) {
                return $allowed;
            }
            $intersect = array_values(array_intersect($requested, $allowed));
            return !empty($intersect) ? $intersect : ['__rbac_scope_none__'];
        }

        return $requested;
    }

    /**
     * دریافت شاخص‌های KPI
     * Admin: می‌تواند همه را ببیند + اهداف را تعریف کند
     * CRM Specialist: **دسترسی ندارد** (403)
     * Agent: فقط KPI خودش را می‌بیند
     */
    public function getKPI()
    {
        $this->requireRbac('kpi.view', 'دسترسی محدود - دسترسی به داشبورد KPI مجاز نیست');
        $role = $_SESSION['role'] ?? '';
        $didarId = $_SESSION['didar_id'] ?? '';

        // CRM Specialist کاملاً محروم است
        if ($role === 'crm_specialist') {
            $this->errorResponse('دسترسی محدود - کارشناسان CRM به داشبورد KPI دسترسی ندارند', 403);
            return;
        }

        // دریافت فیلترها
        $dateFrom = $_POST['date_from'] ?? date('Y-m-01'); // اول ماه جاری
        $dateTo = $_POST['date_to'] ?? date('Y-m-t'); // آخر ماه جاری
        $ownerDidarId = $_POST['owner_didar_id'] ?? '';
        $productId = $_POST['product_id'] ?? '';
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $dealStatuses = $this->parseMultiSelectInput($_POST['deal_statuses'] ?? null);
        $dealLeadTypes = $this->parseMultiSelectInput($_POST['deal_lead_types'] ?? null);
        $debug = ($_POST['debug'] ?? $_GET['debug'] ?? '0') === '1';

        // Backward compatibility with old single-select filters
        if (empty($ownerDidarIds) && !empty($ownerDidarId)) {
            $ownerDidarIds = [$ownerDidarId];
        }
        if (empty($productIds) && !empty($productId)) {
            $productIds = [$productId];
        }

        // اگر Agent بود، فورس فقط خودش را ببیند
        $isAdmin = $this->authService->isAdmin();
        $isSystemRole = method_exists($this->authService, 'isSystemRole') && $this->authService->isSystemRole();
        $isAdminLike = $isAdmin || $isSystemRole;

        // RBAC data-scope can narrow or widen owner visibility for custom roles.
        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, 'kpi', (string)$didarId);

        // ساخت فیلترها
        $ownerCsv = implode(',', $ownerDidarIds);
        $productCsv = implode(',', $productIds);
        $dealStatusCsv = implode(',', $dealStatuses);
        $dealLeadTypeCsv = implode(',', $dealLeadTypes);
        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => $ownerCsv,
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => $productCsv,
            'deal_statuses' => $dealStatuses,
            'deal_statuses_csv' => $dealStatusCsv,
            'deal_lead_types' => $dealLeadTypes,
            'deal_lead_types_csv' => $dealLeadTypeCsv,
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());

        // محاسبه KPI
        try {
            $kpi = $this->kpiService->calculateKPI($filters);
            $payload = [
                'kpi' => $kpi,
                'filters' => [
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'owner_didar_id' => $filters['owner_didar_id'],
                    'owner_didar_ids' => $ownerDidarIds,
                    'product_id' => $filters['product_id'],
                    'product_ids' => $productIds,
                    'deal_statuses' => $dealStatuses,
                    'deal_lead_types' => $dealLeadTypes,
                    'criteria' => $this->extractCriteriaFilters($filters)
                ],
                'can_manage_targets' => $isAdminLike // فقط مدیر/نقش سیستمیِ admin-like می‌تواند اهداف را تعریف کند
            ];

            // Debug فقط برای ادمین فعال می‌شود تا جزئیات خام KPI قابل بررسی باشد
            if ($debug && $isAdminLike) {
                $payload['debug'] = $this->kpiService->buildDebugSnapshot($filters);
            }

            $this->successResponse($payload);

        } catch (\Exception $e) {
            Logger::logError('Failed to calculate KPI', $e, ['filters' => $filters]);
            $this->errorResponse('خطا در محاسبه KPI: ' . $e->getMessage(), 500);
        }
    }

    /**
     * ثبت هدف KPI (فقط Admin)
     */
    public function setKpiTarget()
    {
        $this->requireRbac('kpi.targets.manage', 'دسترسی محدود - مدیریت تارگت KPI مجاز نیست');
        $role = $_SESSION['role'] ?? '';
        $didarId = $_SESSION['didar_id'] ?? '';

        if ($role === 'crm_specialist') {
            $this->errorResponse('دسترسی محدود - کارشناسان CRM به داشبورد KPI دسترسی ندارند', 403);
            return;
        }

        $userId = intval($_POST['user_id'] ?? 0);
        $year = intval($_POST['year'] ?? date('Y'));
        $month = intval($_POST['month'] ?? date('m'));
        $targetAmount = floatval($_POST['target_amount'] ?? 0);
        $targetDealCount = intval($_POST['target_deal_count'] ?? 0);

        if ($userId <= 0 || $targetAmount < 0) {
            $this->errorResponse('پارامترهای نامعتبر');
            return;
        }

        try {
            $result = $this->kpiService->setKpiTarget($userId, $year, $month, $targetAmount, $targetDealCount);

            $this->successResponse([
                'message' => 'هدف KPI با موفقیت ثبت شد',
                'user_id' => $userId,
                'year' => $year,
                'month' => $month,
                'target_amount' => $targetAmount,
                'target_deal_count' => $targetDealCount
            ]);
        } catch (\Exception $e) {
            Logger::logError('Failed to set KPI target', $e, [
                'user_id' => $userId,
                'year' => $year,
                'month' => $month
            ]);
            $this->errorResponse('خطا در ثبت هدف KPI: ' . $e->getMessage(), 500);
        }
    }

    /**
     * دریافت لیست اهداف KPI (فقط Admin)
     */
    public function getKpiTargets()
    {
        $this->requireRbac('kpi.targets.manage', 'دسترسی محدود - مشاهده تارگت KPI مجاز نیست');
        $isAdminLike = $this->authService->isAdmin() || (method_exists($this->authService, 'isSystemRole') && $this->authService->isSystemRole());
        if (!$isAdminLike) {
            $this->errorResponse('دسترسی محدود - فقط مدیر سیستم', 403);
            return;
        }

        try {
            $targets = $this->kpiService->getAllKpiTargets();

            $this->successResponse(['targets' => $targets]);
        } catch (\Exception $e) {
            Logger::logError('Failed to get KPI targets', $e);
            $this->errorResponse('خطا در دریافت لیست اهداف KPI: ' . $e->getMessage(), 500);
        }
    }

    /**
     * دریافت جزئیات معاملات KPI (فقط Admin)
     */
    public function getKpiDealDetails()
    {
        $this->requireRbac('kpi.deals.details', 'دسترسی محدود - مشاهده جزئیات KPI مجاز نیست');
        $isAdminLike = $this->authService->isAdmin() || (method_exists($this->authService, 'isSystemRole') && $this->authService->isSystemRole());
        if (!$isAdminLike) {
            $this->errorResponse('دسترسی محدود - فقط مدیر سیستم', 403);
            return;
        }

        // دریافت فیلترها
        $dateFrom = $_POST['date_from'] ?? date('Y-m-01');
        $dateTo = $_POST['date_to'] ?? date('Y-m-t');
        $ownerDidarId = $_POST['owner_didar_id'] ?? '';
        $productId = $_POST['product_id'] ?? '';
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $dealStatuses = $this->parseMultiSelectInput($_POST['deal_statuses'] ?? null);
        $dealLeadTypes = $this->parseMultiSelectInput($_POST['deal_lead_types'] ?? null);

        if (empty($ownerDidarIds) && !empty($ownerDidarId)) {
            $ownerDidarIds = [$ownerDidarId];
        }
        if (empty($productIds) && !empty($productId)) {
            $productIds = [$productId];
        }

        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, 'kpi', (string)($_SESSION['didar_id'] ?? ''));

        // ساخت فیلترها
        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => implode(',', $ownerDidarIds),
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => implode(',', $productIds),
            'deal_statuses' => $dealStatuses,
            'deal_statuses_csv' => implode(',', $dealStatuses),
            'deal_lead_types' => $dealLeadTypes,
            'deal_lead_types_csv' => implode(',', $dealLeadTypes),
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());

        try {
            $deals = $this->kpiService->getKpiDealDetails($filters);

            $this->successResponse([
                'deals' => $deals,
                'filters' => [
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'owner_didar_id' => $filters['owner_didar_id'],
                    'owner_didar_ids' => $ownerDidarIds,
                    'product_id' => $filters['product_id'],
                    'product_ids' => $productIds,
                    'deal_statuses' => $dealStatuses,
                    'deal_lead_types' => $dealLeadTypes,
                    'criteria' => $this->extractCriteriaFilters($filters)
                ]
            ]);

        } catch (\Exception $e) {
            Logger::logError('Failed to get KPI deal details', $e, ['filters' => $filters]);
            $this->errorResponse('خطا در دریافت جزئیات معاملات: ' . $e->getMessage(), 500);
        }
    }

    public function getKPISection()
    {
        $this->requireRbac('kpi.view', 'دسترسی محدود - دسترسی به داشبورد KPI مجاز نیست');
        $role = $_SESSION['role'] ?? '';
        if ($role === 'crm_specialist') {
            $this->errorResponse('دسترسی محدود - کارشناسان CRM به داشبورد KPI دسترسی ندارند', 403);
            return;
        }
        $section = trim((string)($_POST['section'] ?? 'summary'));
        $dateFrom = $_POST['date_from'] ?? date('Y-m-01');
        $dateTo = $_POST['date_to'] ?? date('Y-m-t');
        $ownerDidarId = $_POST['owner_didar_id'] ?? '';
        $productId = $_POST['product_id'] ?? '';
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $dealStatuses = $this->parseMultiSelectInput($_POST['deal_statuses'] ?? null);
        $dealLeadTypes = $this->parseMultiSelectInput($_POST['deal_lead_types'] ?? null);
        if (empty($ownerDidarIds) && !empty($ownerDidarId)) $ownerDidarIds = [$ownerDidarId];
        if (empty($productIds) && !empty($productId)) $productIds = [$productId];
        $didarId = $_SESSION['didar_id'] ?? '';
        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, 'kpi', (string)$didarId);
        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => implode(',', $ownerDidarIds),
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => implode(',', $productIds),
            'deal_statuses' => $dealStatuses,
            'deal_statuses_csv' => implode(',', $dealStatuses),
            'deal_lead_types' => $dealLeadTypes,
            'deal_lead_types_csv' => implode(',', $dealLeadTypes),
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo,
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());
        try {
            $payload = $this->kpiService->calculateKPISection($filters, $section);
            $this->successResponse([
                'section' => $section,
                'data' => $payload,
                'filters' => [
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'owner_didar_ids' => $ownerDidarIds,
                    'product_ids' => $productIds,
                    'deal_statuses' => $dealStatuses,
                    'deal_lead_types' => $dealLeadTypes,
                    'criteria' => $this->extractCriteriaFilters($filters)
                ],
                'can_manage_targets' => $this->authService->isAdmin()
            ]);
        } catch (\Exception $e) {
            Logger::logError('Failed to calculate KPI section', $e, ['section' => $section, 'filters' => $filters]);
            $this->errorResponse('خطا در بارگذاری بخش KPI: ' . $e->getMessage(), 500);
        }
    }

    public function getCommissionKpis()
    {
        if (!$this->commissionService) {
            $this->errorResponse('سرویس پورسانت در دسترس نیست', 500);
            return;
        }
        $this->requireRbac('kpi.view', 'دسترسی محدود');
        $role = trim((string)($_SESSION['role'] ?? ''));
        if ($role === 'crm_specialist') {
            $this->errorResponse('دسترسی محدود', 403);
            return;
        }

        $dateFrom = trim((string)($_POST['date_from'] ?? date('Y-m-01')));
        $dateTo = trim((string)($_POST['date_to'] ?? date('Y-m-t')));
        $ownerDidarId = trim((string)($_POST['owner_didar_id'] ?? ''));
        if ($ownerDidarId === '' && !$this->authService->isAdmin()) {
            $ownerDidarId = trim((string)($_SESSION['didar_id'] ?? ''));
        }

        $rep = $this->commissionService->calculateRepCommissionKpis([
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => $ownerDidarId,
        ]);
        $manager = $this->commissionService->calculateManagerCommissionKpis([
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
        ]);

        $this->successResponse([
            'rep' => $rep,
            'manager' => $manager,
            'filters' => [
                'date_from' => $dateFrom,
                'date_to' => $dateTo,
                'owner_didar_id' => $ownerDidarId,
            ],
        ]);
    }

    /**
     * Drill-down رکوردهای پشت یک سلول KPI
     */
    public function getKpiDrilldown()
    {
        $tableId = trim((string)($_POST['table_id'] ?? ''));
        $drillCap = ($tableId === 'performance_charts' || in_array($tableId, [
            'activity_summary','activity_type_details','deal_status','lead_status','conversion_status',
            'payment_mix','payment_status','product_status','product_sold_by_owner_day',
            'product_requests_by_owner_day','product_failed_by_owner_day','failure_reasons'
        ], true)) ? 'performance.drilldown' : 'kpi.drilldown';
        $this->requireRbac($drillCap, 'دسترسی محدود - Drilldown مجاز نیست');

        $role = $_SESSION['role'] ?? '';
        $didarId = $_SESSION['didar_id'] ?? '';

        if ($role === 'crm_specialist') {
            $this->errorResponse('دسترسی محدود - کارشناسان CRM به داشبورد KPI دسترسی ندارند', 403);
            return;
        }

        $metricKey = trim((string)($_POST['metric_key'] ?? ''));
        $rowDate = trim((string)($_POST['row_date'] ?? ''));
        $rowOwnerDidarId = trim((string)($_POST['row_owner_didar_id'] ?? ''));
        $rowOwnerName = trim((string)($_POST['row_owner_name'] ?? ''));
        $rowProductName = trim((string)($_POST['row_product_name'] ?? ''));
        $rowFailureReason = trim((string)($_POST['row_failure_reason'] ?? ''));
        $rowActivityType = trim((string)($_POST['row_activity_type'] ?? ''));
        $rowStage = trim((string)($_POST['row_stage'] ?? ''));

        if ($tableId === '' || $metricKey === '') {
            $this->errorResponse('پارامترهای Drill-down ناقص است.');
            return;
        }

        $dateFrom = $_POST['date_from'] ?? date('Y-m-01');
        $dateTo = $_POST['date_to'] ?? date('Y-m-t');
        $ownerDidarId = $_POST['owner_didar_id'] ?? '';
        $productId = $_POST['product_id'] ?? '';
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $dealStatuses = $this->parseMultiSelectInput($_POST['deal_statuses'] ?? null);
        $dealLeadTypes = $this->parseMultiSelectInput($_POST['deal_lead_types'] ?? null);

        if (empty($ownerDidarIds) && !empty($ownerDidarId)) {
            $ownerDidarIds = [$ownerDidarId];
        }
        if (empty($productIds) && !empty($productId)) {
            $productIds = [$productId];
        }

        $isAdmin = $this->authService->isAdmin();

        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, $drillCap === 'performance.drilldown' ? 'performance' : 'kpi', (string)$didarId);

        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => implode(',', $ownerDidarIds),
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => implode(',', $productIds),
            'deal_statuses' => $dealStatuses,
            'deal_statuses_csv' => implode(',', $dealStatuses),
            'deal_lead_types' => $dealLeadTypes,
            'deal_lead_types_csv' => implode(',', $dealLeadTypes),
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());

        $rowContext = [
            'date' => $rowDate,
            'owner_didar_id' => $rowOwnerDidarId,
            'owner_name' => $rowOwnerName,
            'product_name' => $rowProductName,
            'failure_reason' => $rowFailureReason,
            'activity_type' => $rowActivityType,
            'stage' => $rowStage
        ];

        try {
            $data = $this->kpiService->getKpiDrilldown($filters, $tableId, $metricKey, $rowContext);
            $this->successResponse($data);
        } catch (\Exception $e) {
            Logger::logError('Failed to get KPI drilldown', $e, [
                'table_id' => $tableId,
                'metric_key' => $metricKey,
                'row' => $rowContext
            ]);
            $this->errorResponse('خطا در Drill-down KPI: ' . $e->getMessage(), 500);
        }
    }

    /**
     * داشبورد عملکرد (برای Agent/Admin)
     */
    public function getPerformanceDashboard()
    {
        $this->requireRbac('performance.view', 'دسترسی محدود - دسترسی به داشبورد عملکرد مجاز نیست');
        $role = $_SESSION['role'] ?? '';
        $didarId = $_SESSION['didar_id'] ?? '';

        if ($role === 'crm_specialist' || $role === 'accountant') {
            $this->errorResponse('دسترسی محدود - فقط مدیر و کارشناس فروش مجاز هستند', 403);
            return;
        }

        $dateFrom = $_POST['date_from'] ?? date('Y-m-01');
        $dateTo = $_POST['date_to'] ?? date('Y-m-t');
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $ownerDidarId = trim((string)($_POST['owner_didar_id'] ?? ''));
        $productId = trim((string)($_POST['product_id'] ?? ''));

        if (empty($ownerDidarIds) && $ownerDidarId !== '') {
            $ownerDidarIds = [$ownerDidarId];
        }
        if (empty($productIds) && $productId !== '') {
            $productIds = [$productId];
        }

        $isAdmin = $this->authService->isAdmin();

        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, 'performance', (string)$didarId);

        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => implode(',', $ownerDidarIds),
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => implode(',', $productIds),
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());

        try {
            $dashboard = $this->kpiService->calculatePerformanceDashboard($filters);
            $this->successResponse([
                'dashboard' => $dashboard,
                'filters' => [
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'owner_didar_ids' => $ownerDidarIds,
                    'product_ids' => $productIds,
                    'criteria' => $this->extractCriteriaFilters($filters)
                ],
                'filters_meta' => [
                    'role' => $role
                ]
            ]);
        } catch (\Exception $e) {
            Logger::logError('Failed to get performance dashboard', $e, ['filters' => $filters, 'role' => $role]);
            $this->errorResponse('خطا در بارگذاری داشبورد عملکرد: ' . $e->getMessage(), 500);
        }
    }

    public function getPerformanceDashboardSection()
    {
        $this->requireRbac('performance.view', 'دسترسی محدود - دسترسی به داشبورد عملکرد مجاز نیست');
        $role = $_SESSION['role'] ?? '';
        $didarId = $_SESSION['didar_id'] ?? '';
        if ($role === 'crm_specialist' || $role === 'accountant') {
            $this->errorResponse('دسترسی محدود - فقط مدیر و کارشناس فروش مجاز هستند', 403);
            return;
        }

        $section = trim((string)($_POST['section'] ?? 'summary'));
        $dateFrom = $_POST['date_from'] ?? date('Y-m-01');
        $dateTo = $_POST['date_to'] ?? date('Y-m-t');
        $ownerDidarIds = $this->parseMultiSelectInput($_POST['owner_didar_ids'] ?? null);
        $productIds = $this->parseMultiSelectInput($_POST['product_ids'] ?? null);
        $ownerDidarId = trim((string)($_POST['owner_didar_id'] ?? ''));
        $productId = trim((string)($_POST['product_id'] ?? ''));
        if (empty($ownerDidarIds) && $ownerDidarId !== '') $ownerDidarIds = [$ownerDidarId];
        if (empty($productIds) && $productId !== '') $productIds = [$productId];
        $isAdmin = $this->authService->isAdmin();
        $isSystemRole = method_exists($this->authService, 'isSystemRole') && $this->authService->isSystemRole();
        $isAdminLike = $isAdmin || $isSystemRole;
        $ownerDidarIds = $this->applyOwnerDidarScope($ownerDidarIds, 'performance', (string)$didarId);
        $filters = [
            'date_from' => $dateFrom,
            'date_to' => $dateTo,
            'owner_didar_id' => count($ownerDidarIds) === 1 ? $ownerDidarIds[0] : '',
            'owner_didar_ids' => $ownerDidarIds,
            'owner_didar_ids_csv' => implode(',', $ownerDidarIds),
            'product_id' => count($productIds) === 1 ? $productIds[0] : '',
            'product_ids' => $productIds,
            'product_ids_csv' => implode(',', $productIds),
            'person_date_from' => $dateFrom,
            'person_date_to' => $dateTo
        ];
        $filters = array_merge($filters, $this->buildKpiCalculationCriteriaFromRequest());

        try {
            $data = $this->kpiService->calculatePerformanceDashboardSection($filters, $section);
            $this->successResponse([
                'section' => $section,
                'data' => $data,
                'filters' => [
                    'date_from' => $dateFrom,
                    'date_to' => $dateTo,
                    'owner_didar_ids' => $ownerDidarIds,
                    'product_ids' => $productIds,
                    'criteria' => $this->extractCriteriaFilters($filters)
                ],
                'filters_meta' => [
                    'role' => $role
                ]
            ]);
        } catch (\Exception $e) {
            Logger::logError('Failed to get performance dashboard section', $e, ['section' => $section, 'filters' => $filters, 'role' => $role]);
            $this->errorResponse('خطا در بارگذاری بخش داشبورد عملکرد: ' . $e->getMessage(), 500);
        }
    }

    private function parseMultiSelectInput($raw): array
    {
        if ($raw === null) {
            return [];
        }
        if (is_array($raw)) {
            $values = $raw;
        } else {
            $raw = trim((string)$raw);
            if ($raw === '') {
                return [];
            }
            $values = explode(',', $raw);
        }

        $out = [];
        foreach ($values as $v) {
            $value = trim((string)$v);
            if ($value === '' || strtolower($value) === 'all') {
                continue;
            }
            $out[$value] = true;
        }

        return array_keys($out);
    }

    private function buildKpiCalculationCriteriaFromRequest(): array
    {
        return [
            'kpi_sales_date_basis' => trim((string)($_POST['kpi_sales_date_basis'] ?? 'ui_payment_date')),
            'kpi_sales_count_rule' => trim((string)($_POST['kpi_sales_count_rule'] ?? 'first_payment_only')),
            'kpi_payment_date_basis' => trim((string)($_POST['kpi_payment_date_basis'] ?? 'ui_payment_date')),
            'kpi_payment_count_rule' => trim((string)($_POST['kpi_payment_count_rule'] ?? 'all_payments')),
            'kpi_payment_status_scope' => trim((string)($_POST['kpi_payment_status_scope'] ?? 'confirmed_only')),
            'legacy_deal_scope' => trim((string)($_POST['legacy_deal_scope'] ?? 'exclude')),
        ];
    }

    private function extractCriteriaFilters(array $filters): array
    {
        return [
            'kpi_sales_date_basis' => (string)($filters['kpi_sales_date_basis'] ?? 'ui_payment_date'),
            'kpi_sales_count_rule' => (string)($filters['kpi_sales_count_rule'] ?? 'first_payment_only'),
            'kpi_payment_date_basis' => (string)($filters['kpi_payment_date_basis'] ?? 'ui_payment_date'),
            'kpi_payment_count_rule' => (string)($filters['kpi_payment_count_rule'] ?? 'all_payments'),
            'kpi_payment_status_scope' => (string)($filters['kpi_payment_status_scope'] ?? 'confirmed_only'),
            'legacy_deal_scope' => (string)($filters['legacy_deal_scope'] ?? 'exclude'),
        ];
    }
}
