<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\adminmenu\Controller;

use JTL\Helpers\Request;
use Plugin\tnt_mcp\src\Mcp\Admin\ServerStatusReport;
use Throwable;

/**
 * "Aktivität" tab: one answer to "what happened?" (design §2, step 12).
 *
 * It used to be two tabs. **Anfrage-Protokoll** answered "which requests arrived" and **Änderungen**
 * answered "what did they change" — the same question at two levels of detail, costing two tab
 * slots, and neither name told the merchant which one to open. They are now two sub-views of one
 * tab, and the audit tally that used to sit on Server-Status joins them behind a `<details>`,
 * because a count of `denied:scope` is debugging, not status.
 *
 * ## Why plain links instead of HTMX
 *
 * The design asked for an HTMX sub-nav. The two views are full-page reads with no partial state to
 * preserve, one of them handles an undo POST, and the plugin's tab links already have to carry
 * `cPluginTab` to land on the right pane ({@see \Plugin\tnt_mcp\src\Mcp\Admin\TabUrl}). A link that
 * adds one more parameter to that same URL is the whole feature — an HTMX swap here would add a
 * JavaScript dependency to a navigation that already works, and would break the browser's back
 * button on the change-detail view.
 *
 * ⚠️ {@see Changes::data()} processes the pending undo POST, so it is called exactly once, only for
 * the view that is actually rendered.
 */
final class Activity extends BaseAdminController
{
    public const VIEW_REQUESTS = 'requests';

    public const VIEW_CHANGES = 'changes';

    /** The query parameter naming the sub-view; see {@see TabUrl} for why links carry the tab too. */
    public const VIEW_PARAM = 'tntMcpView';

    public function render(): void
    {
        if (!$this->isAdmin()) {
            $this->notLoggedInNotice();

            return;
        }

        $view = $this->view();

        // A change-detail link (`tntMcpChange`) implies the changes view: a merchant following one
        // must not land on the request log with their deep link silently ignored.
        $sub = $view === self::VIEW_CHANGES
            ? $this->partial('changes.tpl', (new Changes($this->plugin, $this->tabName))->data())
            : $this->partial('request-log.tpl', (new RequestLog($this->plugin, $this->tabName))->data());

        echo $this->fetch('activity.tpl', [
            'subView'       => $sub,
            'view'          => $view,
            'requestsUrl'   => $this->selfUrl([self::VIEW_PARAM => self::VIEW_REQUESTS, 'tntMcpChange' => '']),
            'changesUrl'    => $this->selfUrl([self::VIEW_PARAM => self::VIEW_CHANGES, 'tntMcpChange' => '']),
            'auditSummary'  => $this->auditSummary(),
        ]);
    }

    private function view(): string
    {
        if (\trim((string)Request::verifyGPDataString('tntMcpChange')) !== '') {
            return self::VIEW_CHANGES;
        }

        return Request::verifyGPDataString(self::VIEW_PARAM) === self::VIEW_CHANGES
            ? self::VIEW_CHANGES
            : self::VIEW_REQUESTS;
    }

    /**
     * The outcome tally, moved off Server-Status. Best-effort like everything else on this tab: a
     * missing audit table costs the section, not the page.
     *
     * @return list<array{outcome:string,count:int,label:string,tone:string}>
     */
    private function auditSummary(): array
    {
        try {
            return (new ServerStatusReport($this->db(), $this->language()))->auditOutcomes();
        } catch (Throwable) {
            return [];
        }
    }
}
