<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Controller;
use App\Core\Csrf;
use App\Core\Permission;
use App\Workflow\WorkflowRepository;
use Throwable;

final class WorkflowController extends Controller
{
    public function index(): void
    {
        Auth::requireLogin();
        Permission::require('axiom.workflow.view');
        $repo = new WorkflowRepository();
        $workflowId = max(0, (int)($_GET['workflow'] ?? 0));
        $this->view('axiom_workflow/index', [
            'pageTitle' => 'AXIOM Workflow Engine',
            'workflows' => $repo->workflows(),
            'selectedWorkflow' => $workflowId ? $repo->workflow($workflowId) : null,
            'states' => $workflowId ? $repo->states($workflowId) : [],
            'transitions' => $workflowId ? $repo->transitions($workflowId) : [],
            'objects' => $repo->objects(),
            'instances' => $repo->instances(),
            'tasks' => $repo->tasks(false),
            'canManage' => Permission::can('axiom.workflow.manage'),
            'canExecute' => Permission::can('axiom.workflow.execute'),
            'flashSuccess' => $_SESSION['axiom_workflow_success'] ?? null,
            'flashError' => $_SESSION['axiom_workflow_error'] ?? null,
        ]);
        unset($_SESSION['axiom_workflow_success'], $_SESSION['axiom_workflow_error']);
    }

    public function saveWorkflow(): void { $this->run('axiom.workflow.manage', fn(WorkflowRepository $r) => $r->saveWorkflow($_POST), 'Workflow enregistré.'); }
    public function saveState(): void { $this->run('axiom.workflow.manage', fn(WorkflowRepository $r) => $r->saveState($_POST), 'État enregistré.', (int)($_POST['workflow_id'] ?? 0)); }
    public function saveTransition(): void { $this->run('axiom.workflow.manage', fn(WorkflowRepository $r) => $r->saveTransition($_POST), 'Transition enregistrée.', (int)($_POST['workflow_id'] ?? 0)); }
    public function startInstance(): void { $this->run('axiom.workflow.execute', fn(WorkflowRepository $r) => $r->startInstance($_POST, $this->userId()), 'Instance de workflow démarrée.'); }
    public function applyTransition(): void { $this->run('axiom.workflow.execute', fn(WorkflowRepository $r) => $r->applyTransition($_POST, $this->userId()), 'Transition appliquée.'); }
    public function completeTask(): void { $this->run('axiom.workflow.execute', fn(WorkflowRepository $r) => $r->completeTask((int)($_POST['task_id'] ?? 0), $this->userId()), 'Tâche terminée.'); }

    private function run(string $permission, callable $action, string $success, int $workflowId = 0): void
    {
        Auth::requireLogin();
        Permission::require($permission);
        Csrf::verify($_POST['_csrf'] ?? null);
        try {
            $result = $action(new WorkflowRepository());
            if (is_int($result) && $workflowId === 0) $workflowId = $result;
            $_SESSION['axiom_workflow_success'] = $success;
        } catch (Throwable $e) {
            $_SESSION['axiom_workflow_error'] = $e->getMessage();
        }
        $url = '/administration/axiom/workflows';
        if ($workflowId > 0) $url .= '?workflow=' . $workflowId;
        $this->redirect($url);
    }

    private function userId(): ?int
    {
        return isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : null;
    }
}
