<?php

namespace routes;

use classes\authentication;
use classes\error_report_service;
use Throwable;
use traits\route_t;

class errorReportRoute
{
    use route_t;

    public function run(): void
    {
        $this->post('/error-reports', function () {
            global $response;
            try {
                $response->success((new error_report_service())->createFromCurrentPrincipal($this->requestPayload()), 201);
            } catch (Throwable $throwable) {
                $status = str_contains(strtolower($throwable->getMessage()), 'authentication failed') ? 401 : 400;
                $response->error(['message' => $throwable->getMessage()], $status);
            }
        });

        $this->get('/superuser/error-reports', function () {
            global $response;
            $this->requirePermission('superuser_error_reports_view');
            $response->success((new error_report_service())->list($this->getParametersAsArray()));
        }, [
            'superuser_error_reports_view' => 'View authenticated user error reports',
        ]);

        $this->get('/superuser/error-reports/{id}', function () {
            global $response;
            $this->requirePermission('superuser_error_reports_view');
            try {
                $response->success((new error_report_service())->get($this->routeId()));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 404);
            }
        }, [
            'superuser_error_reports_view' => 'View authenticated user error report details',
        ]);

        $this->patch('/superuser/error-reports/{id}/status', function () {
            global $response;
            $this->requirePermission('superuser_error_reports_resolve');
            try {
                $payload = $this->requestPayload();
                $response->success((new error_report_service())->updateStatus(
                    $this->routeId(),
                    (string)($payload['status'] ?? ''),
                    isset($payload['resolution_note']) ? (string)$payload['resolution_note'] : null,
                    $this->actorUserId()
                ));
            } catch (Throwable $throwable) {
                $response->error(['message' => $throwable->getMessage()], 400);
            }
        }, [
            'superuser_error_reports_resolve' => 'Resolve and reopen authenticated user error reports',
        ]);
    }

    private function routeId(): int
    {
        $id = (int)$this->fromRoute('id');
        $this->requireParameterIntPositive($id, 'id');
        return $id;
    }

    private function actorUserId(): ?int
    {
        try {
            $user = (new authentication())->get_user();
            return $user !== false && isset($user->id) ? (int)$user->id : null;
        } catch (Throwable) {
            return null;
        }
    }

    private function requestPayload(): array
    {
        $payload = json_decode(file_get_contents('php://input'), true);
        if (!is_array($payload)) {
            $payload = [];
        }

        if ($_GET !== []) {
            $payload = array_replace($payload, $_GET);
        }

        return $payload;
    }
}
