<?php
namespace App\Controllers;

use App\Repositories\PersonRepository;
use App\Repositories\DealRepository;
use App\Repositories\ActivityRepository;
use App\Services\AuthService;

class DashboardController extends ApiController
{
    private $personRepo;
    private $dealRepo;
    private $activityRepo;
    private $authService;

    private function getRbacScopeForResource(string $resourceKey): ?array
    {
        global $app;
        if (!isset($app->services->rbac) || !$app->services->rbac) {
            return null;
        }
        $scope = (array)$app->services->rbac->getDataScope($resourceKey);
        $scopeType = trim((string)($scope['scope_type'] ?? ''));
        if ($resourceKey === 'dashboard' && ($scopeType === '' || ($scopeType === 'self' && empty($scope['selected_user_ids'])))) {
            // Dashboard often follows leads visibility if a dedicated dashboard scope was not configured yet.
            $fallback = (array)$app->services->rbac->getDataScope('leads');
            if (!empty($fallback)) {
                return $fallback;
            }
        }
        return $scope;
    }

    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) {}
        }
        return array_keys($didarIds);
    }

    private function applyDashboardOwnerScope(array &$filters, string $requestedOwnerDidarId, string $selfDidarId): void
    {
        $scope = $this->getRbacScopeForResource('dashboard');
        if (!$scope) {
            return;
        }

        $scopeType = trim((string)($scope['scope_type'] ?? ''));
        if ($scopeType === '' || $scopeType === 'all') {
            if ($requestedOwnerDidarId !== '') {
                $filters['owner_didar_id'] = $requestedOwnerDidarId;
            } else {
                unset($filters['owner_didar_id']);
            }
            return;
        }

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

        if ($scopeType === 'selected_users') {
            $allowed = $this->mapSelectedUserIdsToDidarIds((array)($scope['selected_user_ids'] ?? []));
            if ($requestedOwnerDidarId !== '') {
                $filters['owner_didar_id'] = in_array($requestedOwnerDidarId, $allowed, true) ? $requestedOwnerDidarId : '__rbac_scope_none__';
                return;
            }
            // DashboardController currently supports single owner filter only.
            // For selected_users without explicit owner, aggregate is not implemented yet, so use no-result sentinel.
            $filters['owner_didar_id'] = '__rbac_scope_none__';
        }
    }

    public function __construct(
        PersonRepository $personRepo,
        DealRepository $dealRepo,
        ActivityRepository $activityRepo,
        AuthService $authService
    ) {
        $this->personRepo = $personRepo;
        $this->dealRepo = $dealRepo;
        $this->activityRepo = $activityRepo;
        $this->authService = $authService;
    }

    public function getStats()
    {
        $isAdmin = $this->authService->isAdmin();
        $isAdminOrCrm = $this->authService->isAdminOrCrmSpecialist();
        $didarId = $_SESSION['didar_id'] ?? '';
        
        $ownerFilter = $_POST['owner_didar_id'] ?? '';
        $statusFilter = $_POST['status'] ?? 'all';

        $stats = [];
        
        // Get total leads count (without pagination)
        $filters = [];
        if ($isAdminOrCrm && !empty($ownerFilter)) {
            $filters['owner_didar_id'] = $ownerFilter;
        } elseif (!$isAdminOrCrm && !empty($didarId)) {
            $filters['owner_didar_id'] = $didarId;
        }
        $this->applyDashboardOwnerScope($filters, (string)$ownerFilter, (string)$didarId);
        
        // Use getLeadsCount for accurate total count
        $stats['total_leads'] = $this->personRepo->getLeadsCount($filters);

        // Lead success/fail based on sale_status
        $db = $this->personRepo->getDb();
        $pdo = $db->getPdo();
        $whereClause = "didar_contact_id IS NOT NULL";
        $params = [];
        if (!empty($filters['owner_didar_id'])) {
            $whereClause .= " AND owner_didar_id = ?";
            $params[] = $filters['owner_didar_id'];
        }
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM persons WHERE $whereClause AND sale_status = 1");
        $stmt->execute($params);
        $stats['successful_leads'] = (int)$stmt->fetchColumn();
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM persons WHERE $whereClause AND sale_status = 0");
        $stmt->execute($params);
        $stats['failed_leads'] = (int)$stmt->fetchColumn();

        // Deals pipeline stats (NO LIMIT; fixes "always 100" bug)
        $dealFilters = $filters;
        if ($statusFilter !== 'all') {
            $dealFilters['status'] = $statusFilter;
        }

        // Filter out legacy deals for current deals count
        $currentDealFilters = array_merge($dealFilters, ['legacy' => '0']);
        $stats['total_deals'] = $this->dealRepo->countAll($dealFilters); 
        $stats['deals_by_stage'] = $this->dealRepo->getStageCounts($currentDealFilters);
        
        // Define active pipeline stages to sum up for "Ongoing" count
        $activeStages = [
            'بلاتکلیف', 'معامله جدید', 'تماس عدم پاسخ', 'تماس پیگیری', 
            'ارسال لینک پرداخت', 'پرداخت', 'پیگیری مانده حساب', 
            'برگزاری دوره', 'پشتیبانی', 'ارجاع به CRM'
        ];
        
        $ongoingCount = 0;
        foreach ($activeStages as $stage) {
            if (isset($stats['deals_by_stage'][$stage])) {
                $ongoingCount += $stats['deals_by_stage'][$stage];
            }
        }
        $stats['ongoing_deals'] = $ongoingCount;
        
        $this->successResponse(['stats' => $stats]);
    }
}
