<?php

declare(strict_types=1);

namespace Atdt\Screens;

use Atdt\Ansi;
use Atdt\Ctx;
use Atdt\In;
use Atdt\Pipe;
use Atdt\Screen;

/**
 * Rumors (SPEC §10.6): the full list + submissions. A random one already
 * greets callers in the post-login sequence; sysop moderation (approved
 * flag) arrives with the M6 console.
 */
final class RumorsScreen implements Screen
{
    private const ROW_IN = 22;
    private const ROW_MSG = 24;

    public function describe(): string
    {
        return 'Trading rumors';
    }

    /**
     * 1.5.0: callers only POST here. Showing the pile would spoil the
     * one-random-rumor-at-dawn surprise; the full list lives in the
     * SysOp's Community desk.
     */
    public function enter(Ctx $c): array
    {
        $c->set('step', 'list');
        $count = (int)$c->db()->val('SELECT COUNT(*) FROM rumors WHERE approved = 1');
        $o = $c->out()->cls();
        $o->at(2, 1)->txt($c->center($c->tstr('rumor.title')));
        $o->at(3, 1)->txt($c->center($c->tstr('rumor.blurb')));
        $o->at(8, 1)->txt($c->center($c->tstr('rumor.pile', ['RC' => (string)$count])));
        $o->at(10, 1)->txt($c->center($c->tstr('rumor.tease')));
        $o->at(21, 1)->txt($c->center($c->tstr('rumor.prompt')));
        return [$c->ansi($o->str()), $c->hotkey()];
    }

    public function input(Ctx $c, In $in): array
    {
        if ($in->kind === 'line') {
            $c->set('step', 'list');
            $body = \Atdt\Chat::clean((string)$in->line, 79);
            if ($in->line === null || $body === '') {
                return $this->enter($c);
            }
            $u = $c->user();
            $c->db()->insert('rumors', [
                'user_id' => (int)($u['id'] ?? 0),
                'handle' => (string)($u['handle'] ?? 'caller'),
                'body' => $body,
                'at' => now_utc(),
                'approved' => 1,
            ]);
            $frames = $this->enter($c);
            $frames[] = $c->ansi(Ansi::make()->at(self::ROW_MSG, 1)->txt("\x1b[K")
                ->txt($c->center($c->tstr('rumor.added')))->str());
            return $frames;
        }
        if ($in->kind !== 'key' || $c->get('step') !== 'list') {
            return [$c->bell()];
        }
        switch (strtoupper((string)$in->key)) {
            case 'A':
                // The prompt gets its own row so the whole 79 columns fit.
                $c->set('step', 'add');
                $o = Ansi::make()
                    ->at(self::ROW_IN - 1, 1)->txt("\x1b[K")
                    ->at(self::ROW_IN, 1)->txt("\x1b[K")
                    ->at(self::ROW_IN - 1, 3)->txt($c->tstr('rumor.ask'));
                return [$c->ansi($o->str()), $c->line(2, self::ROW_IN, 79)];
            case 'Q':
            case 'ESC':
                return $c->pop();
            case '?':
                return $this->enter($c);
            default:
                return [$c->bell()];
        }
    }
}
