<?php

namespace Leantime\Plugins\AllTasks\Hxcontrollers;

use Leantime\Core\Controller\HtmxController;
use Leantime\Domain\Auth\Services\Auth as AuthService;
use Leantime\Domain\Projects\Services\Projects as ProjectService;
use Leantime\Domain\Tickets\Services\Tickets as TicketService;
use Leantime\Domain\Users\Services\Users as UserService;

/**
 * AllTasks Widget Controller
 * Shows all tasks from all users with filters
 */
class AllTasks extends HtmxController
{
    protected static string $view = 'alltasks::get';

    private TicketService $ticketsService;
    private ProjectService $projectsService;
    private UserService $usersService;
    private AuthService $authService;
    private int $limit = 50;

    public function init(
        TicketService $ticketsService,
        ProjectService $projectsService,
        UserService $usersService,
        AuthService $authService
    ) {
        $this->ticketsService = $ticketsService;
        $this->projectsService = $projectsService;
        $this->usersService = $usersService;
        $this->authService = $authService;
    }

    /**
     * Get all tasks with filters
     */
    public function get()
    {
        // Verify user is admin
        if (!$this->authService->userIsAtLeast('admin')) {
            $this->tpl->assign('error', 'alltasks.errors.not_authorized');
            return;
        }

        $params = $this->incomingRequest->query->all();

        // Get filter parameters - use array_key_exists to properly handle empty strings
        $projectFilter = array_key_exists('projectFilter', $params) ? $params['projectFilter'] : session('allTasksProjectFilter', '');
        $userFilter = array_key_exists('userFilter', $params) ? $params['userFilter'] : session('allTasksUserFilter', '');
        $statusFilter = array_key_exists('statusFilter', $params) ? $params['statusFilter'] : session('allTasksStatusFilter', 'not_done');
        $groupBy = array_key_exists('groupBy', $params) ? $params['groupBy'] : session('allTasksGroupBy', 'user');

        // Save filters in session
        session(['allTasksProjectFilter' => $projectFilter]);
        session(['allTasksUserFilter' => $userFilter]);
        session(['allTasksStatusFilter' => $statusFilter]);
        session(['allTasksGroupBy' => $groupBy]);

        // Set pagination
        if (!isset($params['limit'])) {
            $params['limit'] = $this->limit;
        }
        // Note: When showing multiple projects, limit is distributed among them

        // STEP 1: Get admin's projects (only open projects)
        $userProjects = $this->projectsService->getProjectsAssignedToUser(session('userdata.id'), 'open');
        $userProjectIds = array_column($userProjects, 'id');

        // If no projects found, return empty
        if (empty($userProjectIds)) {
            $this->tpl->assign('ticketsGrouped', []);
            $this->tpl->assign('groupNames', []);
            $this->tpl->assign('projectNames', []);
            $this->tpl->assign('statusLabels', []);
            $this->tpl->assign('allProjects', []);
            $this->tpl->assign('allUsers', []);
            $this->tpl->assign('projectFilter', $projectFilter);
            $this->tpl->assign('userFilter', $userFilter);
            $this->tpl->assign('statusFilter', $statusFilter);
            $this->tpl->assign('groupBy', $groupBy);
            $this->tpl->assign('totalTasks', 0);
            $this->tpl->assign('hasMoreTickets', false);
            return;
        }

        // STEP 2: Prepare project filter
        $effectiveProjectIds = $userProjectIds; // By default, all user's projects
        
        if (!empty($projectFilter)) {
            // Specific project selected - verify access
            if (in_array($projectFilter, $userProjectIds)) {
                $effectiveProjectIds = [$projectFilter];
            } else {
                // User doesn't have access, return empty
                $effectiveProjectIds = [];
            }
        }

        // STEP 3: Get all tasks from those projects
        $allTickets = [];
        $statusLabels = [];
        $projectNames = [];

        // Calculate per-project limit to avoid getting too many tickets from first projects
        $perProjectLimit = !empty($projectFilter) ? $params['limit'] : (int)ceil($params['limit'] / count($effectiveProjectIds));

        foreach ($effectiveProjectIds as $projectId) {
            // Get project info and status labels
            $project = $this->projectsService->getProject($projectId);
            $projectNames[$projectId] = $project['name'] ?? 'Unknown Project';
            $statusLabels[$projectId] = $this->ticketsService->getStatusLabels($projectId);

            // Prepare search criteria for this project
            $searchCriteria = [
                'currentProject' => $projectId,
                'users' => $userFilter, // Empty = all users, or specific user ID
                'status' => $statusFilter, // 'not_done', 'done', or '' for all
                'sprint' => '',
            ];

            // Get tickets for this project
            $projectTickets = $this->ticketsService->getAll($searchCriteria, $perProjectLimit);
            
            if ($projectTickets && is_array($projectTickets)) {
                $allTickets = array_merge($allTickets, $projectTickets);
            }
        }

        // STEP 4: Group tickets by project or user depending on groupBy parameter
        $ticketsGrouped = [];
        $groupNames = []; // Store group names (project names or user names)
        
        if ($groupBy === 'user') {
            // Group by user (editorId)
            foreach ($allTickets as $ticket) {
                $userId = $ticket['editorId'] ?? 0;
                
                if (!isset($ticketsGrouped[$userId])) {
                    $ticketsGrouped[$userId] = [];
                    // Store user name
                    if ($userId > 0) {
                        $groupNames[$userId] = ($ticket['editorFirstname'] ?? '') . ' ' . ($ticket['editorLastname'] ?? '');
                        if (trim($groupNames[$userId]) === '') {
                            $groupNames[$userId] = 'Unknown User';
                        }
                    } else {
                        $groupNames[$userId] = 'Unassigned';
                    }
                }
                
                $ticketsGrouped[$userId][] = $ticket;
            }
        } else {
            // Group by project (default behavior)
            foreach ($allTickets as $ticket) {
                $projectId = $ticket['projectId'] ?? 'unknown';
                
                if (!isset($ticketsGrouped[$projectId])) {
                    $ticketsGrouped[$projectId] = [];
                    $groupNames[$projectId] = $projectNames[$projectId] ?? 'Unknown Project';
                }
                
                $ticketsGrouped[$projectId][] = $ticket;
            }
        }

        // STEP 5: Get all users for filter
        $allUsers = $this->usersService->getAll();
        
        // STEP 6: Count total tasks
        $totalTasks = count($allTickets);

        // Assign template variables
        $this->tpl->assign('ticketsGrouped', $ticketsGrouped);
        $this->tpl->assign('groupNames', $groupNames);
        $this->tpl->assign('projectNames', $projectNames);
        $this->tpl->assign('statusLabels', $statusLabels);
        $this->tpl->assign('allProjects', $userProjects);
        $this->tpl->assign('allUsers', $allUsers);
        $this->tpl->assign('projectFilter', $projectFilter);
        $this->tpl->assign('userFilter', $userFilter);
        $this->tpl->assign('statusFilter', $statusFilter);
        $this->tpl->assign('groupBy', $groupBy);
        $this->tpl->assign('totalTasks', $totalTasks);
        $this->tpl->assign('hasMoreTickets', $totalTasks >= $params['limit']);
    }
}
