<?php

namespace Acms\Services\Setup\Install;

use Acms\Services\Setup\Http\Response;
use Acms\Services\Setup\InstallMessages;
use Acms\Services\Setup\SetupSession;
use Acms\Services\Setup\Tool\ToolErrors;
use Acms\Services\Facades\Application;
use Field;

/**
 * インストールウィザードの ToolView 相当を setup 専用 Twig で描画する Responder。
 *
 * 旧 Factory::renderStep がインラインで組んでいた共通 View データ（CSRF トークン・バージョン・
 * フォーム入力値・エラー/通知メッセージ）の付与を 1 箇所へ集約する。errors/notices（{@see ToolErrors}）は
 * {@see InstallMessages} で表示メッセージへ解決する。フェーズ固有データ（規約文・テーマ・作成テーブル等）は
 * $data として受け取り重ね合わせる。
 */
final class InstallResponder
{
    /**
     * 各フォームが再表示に使う入力値のキー。
     */
    private const FIELD_KEYS = [
        'domain',
        'db_host',
        'db_name',
        'db_user',
        'db_pass',
        'db_prefix',
        'db_charset',
        'db_collation',
        'blog_name',
        'select_theme',
        'user_name',
        'user_mail',
        'user_code',
    ];

    /**
     * @param array<string, mixed> $data フェーズ固有の View データ（viewData + commit の結果）
     */
    public function render(
        string $template,
        string $screen,
        ToolErrors $errors,
        ToolErrors $notices,
        array $data,
        Field $post,
        SetupSession $session
    ): Response {
        $messages = new InstallMessages();
        $view = array_merge([
            'screen' => $screen,
            'setupFormToken' => $session->ensureFormToken(),
            'copyrightYear' => (int)date('Y'),
            'version' => VERSION,
            'phpVersion' => PHP_VERSION,
            'httpRoot' => HTTP_ROOT,
            'loginSegment' => LOGIN_SEGMENT,
            'fields' => $this->collectFields($post),
            'errorMessages' => $messages->errorList($errors->keys()),
            'noticeMessages' => $messages->noticeList($notices->keys()),
        ], $data);

        /** @var \Acms\Services\Template\Twig $twig */
        $twig = Application::make('template.setup.twig');

        return Response::html($twig->renderTemplate($template, $view));
    }

    /**
     * @return array<string, string>
     */
    private function collectFields(Field $post): array
    {
        $fields = [];
        foreach (self::FIELD_KEYS as $key) {
            $fields[$key] = $post->get($key);
        }

        return $fields;
    }
}
