<?php

declare(strict_types=1);

namespace Atdt\Screens;

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

/**
 * New scan (SPEC §10.5): walk every area with unread messages, offering a
 * read-through in order. Stateless hand-off: the Reader (scan mode) pops
 * back here; if the area it was reading still has unread, the caller quit
 * early and the whole scan stops — otherwise the scan advances.
 */
final class NewScanScreen implements Screen
{
    private const ROW_MSG = 24;

    public function describe(): string
    {
        return 'Scanning for new messages';
    }

    public function enter(Ctx $c): array
    {
        $db = $c->db();
        $user = $c->user();

        $cur = $c->get('cur');
        if ($cur !== null && Messages::unreadCount($db, $user, (int)$cur) > 0) {
            return $this->finish($c, 'scan.stopped'); // reader was quit mid-area
        }
        $areas = Messages::areasFor($db, $user);
        // A pinned scan (1.6.5): a targeted item or a scoped menu narrows
        // the walk to one area. The global scan is untouched -- and it
        // deliberately includes unlisted areas (SPEC 4.5): unlisted is
        // discovery, and a caller with access deserves to hear about
        // their new mail.
        $pin = $c->get('area_id');
        if ($pin !== null) {
            $areas = array_values(array_filter(
                $areas,
                fn(array $a) => (int)$a['id'] === (int)$pin
            ));
        }
        foreach ($areas as $area) {
            if ((int)$area['unread'] > 0) {
                $c->set('cur', (int)$area['id']);
                $c->set('any', true);
                return $c->push('Reader', [
                    'area_id' => (int)$area['id'],
                    'scan' => true,
                ]);
            }
        }
        return $this->finish($c, $c->get('any') ? 'scan.done' : 'scan.nothing');
    }

    public function input(Ctx $c, In $in): array
    {
        return $c->pop(); // never sits on input; any stray key exits
    }

    private function finish(Ctx $c, string $stringKey): array
    {
        $frames = $c->pop();
        $frames[] = $c->ansi(
            Ansi::make()->at(self::ROW_MSG, 1)->txt("\x1b[K")
                ->txt($c->center($c->tstr($stringKey)))->str()
        );
        return $frames;
    }
}
