<?php
declare(strict_types=1);

namespace App\Services\Deployment;

use App\Core\Auth;
use App\Core\Controller;
use Throwable;

final class EnterpriseDeploymentOrchestratorHttpService
{
    /**
     * @param array<string,mixed> $query
     */
    public function renderIndex(
        Controller $controller,
        array $query
    ): void {
        $selectedId = isset($query['id'])
            ? (int) $query['id']
            : null;

        $this->render(
            $controller,
            (new EnterpriseDeploymentOrchestratorService())
                ->dashboard($selectedId)
        );
    }

    /**
     * @param array<string,mixed> $input
     */
    public function create(
        Controller $controller,
        array $input
    ): void {
        try {
            $result = (new EnterpriseDeploymentOrchestratorService())->create(
                (int) ($input['root_registry_id'] ?? 0),
                isset($input['automatic_rollback']),
                isset($input['stop_on_warning']),
                (int) (Auth::user()['id'] ?? 0) ?: null
            );

            $_SESSION['success'] =
                'Orchestration créée. Le plan peut maintenant être exécuté.';

            $_SESSION['deployment_orchestration_focus'] =
                (int) ($result['orchestration']['id'] ?? 0);
        } catch (Throwable $error) {
            $_SESSION['error'] =
                'Création impossible : ' . $error->getMessage();
        }

        $this->redirectIndex($controller);
    }

    /**
     * @param array<string,mixed> $input
     */
    public function advance(array $input): never
    {
        try {
            $result = (new EnterpriseDeploymentOrchestratorService())->advance(
                (int) ($input['orchestration_id'] ?? 0),
                (int) (Auth::user()['id'] ?? 0) ?: null
            );

            $this->json($result, 200);
        } catch (Throwable $error) {
            $this->json(
                [
                    'ok' => false,
                    'error' => $error->getMessage(),
                ],
                422
            );
        }
    }

    /**
     * @param array<string,mixed> $query
     */
    public function status(array $query): never
    {
        try {
            $result = (new EnterpriseDeploymentOrchestratorService())->status(
                (int) ($query['id'] ?? 0)
            );

            $this->json($result, 200);
        } catch (Throwable $error) {
            $this->json(
                [
                    'ok' => false,
                    'error' => $error->getMessage(),
                ],
                404
            );
        }
    }

    /**
     * @param array<string,mixed> $input
     */
    public function cancel(
        Controller $controller,
        array $input
    ): void {
        try {
            (new EnterpriseDeploymentOrchestratorService())->cancel(
                (int) ($input['orchestration_id'] ?? 0)
            );

            $_SESSION['success'] = 'Orchestration annulée.';
        } catch (Throwable $error) {
            $_SESSION['error'] =
                'Annulation impossible : ' . $error->getMessage();
        }

        $this->redirectIndex($controller);
    }

    /**
     * @param array<string,mixed> $deploymentData
     */
    private function render(
        Controller $controller,
        array $deploymentData
    ): void {
        $reflection = new \ReflectionClass($controller);
        $method = $reflection->getMethod('view');
        $method->setAccessible(true);

        $method->invoke(
            $controller,
            'platform/deployment_orchestrator',
            [
                'pageTitle' =>
                    'Enterprise Deployment Orchestrator PRO',
                'deploymentData' => $deploymentData,
            ]
        );
    }

    private function redirectIndex(
        Controller $controller
    ): never {
        $reflection = new \ReflectionClass($controller);
        $method = $reflection->getMethod('redirect');
        $method->setAccessible(true);

        $method->invoke(
            $controller,
            '/administration/plateforme/deploiement-orchestre'
        );

        exit;
    }

    /**
     * @param array<string,mixed> $payload
     */
    private function json(
        array $payload,
        int $status
    ): never {
        http_response_code($status);
        header('Content-Type: application/json; charset=UTF-8');
        header('Cache-Control: no-store, private');

        echo json_encode(
            $payload,
            JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
        );

        exit;
    }
}
