<?php

namespace App\Controllers;

use App\Models\Procedure;
use App\Models\State;
use App\Services\AreaService;
use App\Services\ProcessService;
use App\Services\SearchValidator;
use App\Services\UserService;

class SearchController extends BaseController
{
    protected ProcessService $processService;
    protected AreaService $areaService;

    public function __construct() {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }

        $this->processService = new ProcessService();
        $this->areaService = new AreaService();
    }

    public function index() {
        $priorities = State::getActives();
        $procedures = Procedure::getActives();
        $periods = $this->processService->getDistinctPeriods();
        $areas = $this->areaService->getAreasWithRelations();
        $this->render('search/search-index', ['priorities' => $priorities, 'procedures' => $procedures, 'periods' => $periods, 'areas' => $areas]);
    }

    public function search()
    {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            header("Location: " . BASE_HEADER . "search");
            exit;
        }

        $filters = [];
        $processes = null;
        $derivation_results = null;
        $state_results = null;

        if (!empty($_POST['search_type'])) {
            $search_type = $_POST['search_type'];

            switch ($search_type) {
                case 'name':
                    $filters = SearchValidator::validateNameSearch($_POST);
                    $processes = $this->processService->searchByName($filters);
                    break;

                case 'dni':
                    $filters = SearchValidator::validateDniSearch($_POST);
                    $processes = $this->processService->searchByDni($filters);
                    break;

                case 'dates':
                    $filters = SearchValidator::validateDateRangeSearch($_POST);
                    $processes = $this->processService->searchByDateRange($filters);
                    break;

                case 'priority':
                    $filters = SearchValidator::validatePrioritySearch($_POST);
                    $processes = $this->processService->searchByPriority($filters);
                    break;

                case 'procedure':
                    $filters = SearchValidator::validateProcedureSearch($_POST);
                    $processes = $this->processService->searchByProcedure($filters);
                    break;

                case 'derivados':
                    $filters = SearchValidator::validateDerivationSearch($_POST);
                    $derivation_results = $this->processService->searchByDerivationDate($filters);
                    break;

                case 'state':
                    $role = $_SESSION['role'];
                    $isAdmin = $role === 'ADMIN';

                    if (!$isAdmin) {
                        $_POST['group_id'] = UserService::getUser()->group_id;
                        $_POST['subgroup_id'] = UserService::getUser()->subgroup_id;
                    }

                    $filters = SearchValidator::validateStateSearch($_POST, $isAdmin);
                    $state_results = $this->processService->searchByState($filters);
                    break;

                case 'process_number':
                    $filters = SearchValidator::validateProcessNumberSearch($_POST);
                    $processes = $this->processService->searchByProcessNumber($filters);
                    break;

                default:
                    $this->setErrorAndRedirect("Error: Tipo de búsqueda no válido.");
            }
        }

        $this->render('search/search-index', [
            'derivation_results' => $derivation_results,
            'processes' => $processes,
            'state_results' => $state_results,
            'filters' => $filters,
            'search_type' => $search_type,
            'priorities' => State::getActives(),
            'procedures' => Procedure::getActives(),
            'periods' => $this->processService->getDistinctPeriods(),
            'areas' => $this->areaService->getAreasWithRelations(),
        ]);
    }

    private function setErrorAndRedirect(string $message): void
    {
        $_SESSION['message'] = $message;
        $_SESSION['message_type'] = 'danger';
        header("Location: " . BASE_HEADER . "search");
        exit;
    }   
}
