<?php

declare(strict_types=1);



class AdminSupportController
{
    private const MAX_FILES = 6;
    private const MAX_FILE_BYTES = 5242880;  
    private const ALLOWED_MIME = ['image/png', 'image/jpeg', 'image/webp', 'image/gif'];

    public static function routes(): void
    {
        Router::get('/admin/support/context', [self::class, 'context']);
        Router::get('/admin/support/tickets', [self::class, 'listTickets']);
        Router::post('/admin/support/tickets', [self::class, 'create']);
        Router::get('/admin/support/tickets/{id}', [self::class, 'getTicket']);
        Router::post('/admin/support/tickets/{id}/reply', [self::class, 'reply']);
        Router::post('/admin/support/tickets/{id}/close', [self::class, 'close']);
        Router::post('/admin/support/tickets/{id}/delete', [self::class, 'remove']);
        Router::get('/admin/support/attachment/{id}', [self::class, 'attachment']);
    }

     
    public static function context(): void
    {
        Auth::requireAdmin();
        session_write_close();
        Router::json([
            'connected'   => CatalogueClient::isConfigured(),
            'domain'      => CatalogueClient::getSiteDomain(),
            'site_url'    => rtrim(Setting::get('site_url', ''), '/'),
            'cms_version' => defined('APP_VERSION') ? APP_VERSION : '',
            'php_version' => PHP_VERSION,
        ]);
    }

    public static function listTickets(): void
    {
        Auth::requireAdmin();
        session_write_close();
        if (!CatalogueClient::isConfigured()) {
            Router::json(['connected' => false, 'tickets' => []]);
        }
        $res = CatalogueClient::supportList();
        if ($res === null) {
            Router::json(['connected' => true, 'error' => 'unreachable', 'tickets' => []]);
        }
        Router::json(['connected' => true, 'tickets' => $res['tickets'] ?? []]);
    }

    public static function getTicket(): void
    {
        Auth::requireAdmin();
        session_write_close();
        self::requireConnected();
        $id = (int) Router::param('id');
        $res = CatalogueClient::supportGet($id);
        if ($res === null || empty($res['ticket'])) {
            Router::json(['error' => 'not_found'], 404);
        }
        Router::json(['ticket' => $res['ticket']]);
    }

    public static function create(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }
        session_write_close();
        self::requireConnected();

        $payload = self::buildPayload();
        if ($payload['subject'] === '' || $payload['message'] === '') {
            Router::json(['error' => 'Subject and message are required.'], 422);
        }
         
         

        self::relayResult(CatalogueClient::supportCreate($payload), 'Could not create the ticket.');
    }

    public static function reply(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }
        session_write_close();
        self::requireConnected();
        $id = (int) Router::param('id');
        $message = trim($_POST['message'] ?? '');
        $atts = self::collectAttachments();
        if ($message === '' && empty($atts)) {
            Router::json(['error' => 'Message is required.'], 422);
        }
        self::relayResult(
            CatalogueClient::supportReply($id, ['message' => $message, 'attachments' => $atts]),
            'Could not send the reply.'
        );
    }

    public static function close(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }
        session_write_close();
        self::requireConnected();
        $id = (int) Router::param('id');
        self::relayResult(CatalogueClient::supportClose($id), 'Could not close the ticket.');
    }

    public static function remove(): void
    {
        Auth::requireAdmin();
        if (!Router::verifyCsrf()) {
            Router::json(['error' => 'Invalid CSRF token'], 403);
        }
        session_write_close();
        self::requireConnected();
        $id = (int) Router::param('id');
        $res = CatalogueClient::supportDelete($id);
        if ($res === null) {
            Router::json(['error' => 'Support service is unreachable. Please try again shortly.'], 502);
        }
        if (!empty($res['_error'])) {
            Router::json(['error' => $res['error'] ?? 'Could not delete the ticket.'], (int) ($res['_http_code'] ?? 400));
        }
        Router::json(['success' => true, 'deleted' => (int) ($res['deleted'] ?? $id)]);
    }

    public static function attachment(): void
    {
        Auth::requireAdmin();
        session_write_close();
        self::requireConnected();
        $id = (int) Router::param('id');
        $res = CatalogueClient::supportFetchAttachment($id);
        if ($res === null) {
            http_response_code(404);
            echo 'Not found';
            exit;
        }
        while (ob_get_level() > 0) {
            ob_end_clean();
        }
        header('Content-Type: ' . $res['content_type']);
        header('X-Content-Type-Options: nosniff');
        header('Cache-Control: private, max-age=300');
        echo $res['body'];
        exit;
    }

     

    private static function requireConnected(): void
    {
        if (!CatalogueClient::isConfigured()) {
            Router::json(['error' => 'not_connected'], 403);
        }
    }

    private static function relayResult(?array $res, string $fallback): void
    {
        if ($res === null) {
            Router::json(['error' => 'Support service is unreachable. Please try again shortly.'], 502);
        }
        if (!empty($res['_error'])) {
            Router::json(['error' => $res['error'] ?? $fallback], (int) ($res['_http_code'] ?? 400));
        }
        Router::json(['success' => true, 'ticket' => $res['ticket'] ?? null]);
    }

    

    private static function safeHealth(): array
    {
        try {
            return AdminSettingController::runHealthChecks();
        } catch (\Throwable $e) {
            return [];
        }
    }

    private static function buildPayload(): array
    {
        $creds = [];
        foreach (['admin_login', 'admin_pass', 'server_ip', 'server_user', 'server_pass'] as $k) {
            $v = trim($_POST[$k] ?? '');
            if ($v !== '') {
                $creds[$k] = $v;
            }
        }
        return [
            'subject'     => trim($_POST['subject'] ?? ''),
            'message'     => trim($_POST['message'] ?? ''),
            'category'    => $_POST['category'] ?? 'other',
            'priority'    => $_POST['priority'] ?? 'normal',
            'domain'      => trim($_POST['domain'] ?? '') ?: CatalogueClient::getSiteDomain(),
            'admin_url'   => trim($_POST['admin_url'] ?? ''),
            'cms_version' => defined('APP_VERSION') ? APP_VERSION : '',
            'php_version' => PHP_VERSION,
            'health'      => self::safeHealth(),
            'credentials' => $creds,
            'attachments' => self::collectAttachments(),
        ];
    }

     
    private static function collectAttachments(): array
    {
        $out = [];
        if (empty($_FILES['screenshots']) || !is_array($_FILES['screenshots']['name'] ?? null)) {
            return $out;
        }
        $f = $_FILES['screenshots'];
        $n = count($f['name']);
        for ($i = 0; $i < $n && count($out) < self::MAX_FILES; $i++) {
            if (($f['error'][$i] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
                continue;
            }
            if (!is_uploaded_file($f['tmp_name'][$i])) {
                continue;
            }
            if (($f['size'][$i] ?? 0) > self::MAX_FILE_BYTES) {
                continue;
            }
            $bytes = @file_get_contents($f['tmp_name'][$i]);
            if ($bytes === false) {
                continue;
            }
            $info = @getimagesizefromstring($bytes);
            if ($info === false || !in_array($info['mime'] ?? '', self::ALLOWED_MIME, true)) {
                continue;
            }
            $out[] = ['name' => mb_substr((string) $f['name'][$i], 0, 200), 'data' => base64_encode($bytes)];
        }
        return $out;
    }
}
