<?php

declare(strict_types=1);

namespace Acms\Services\Login;

use Acms\Services\Login\Enums\AuthSystemResolutionType;
use LogicException;

/**
 * 認証系URLの解決結果を表す値オブジェクト
 *
 * getAuthSystemTemplate() 相当の解決処理（resolveAuthSystemRequest()）が返す。
 * 「テンプレートを表示する」「ログイン画面へリダイレクトする」「認証系URLに該当しない」の
 * 3状態を AuthSystemResolutionType で表現し、リダイレクトという副作用は
 * 呼び出し側（main.php）が isRedirect()/isTemplate() の判定を見て実行する。
 * TfaSecretKeyResult と同じ「private コンストラクタ + 名前付きファクトリ + isXxx() 判定」の形に揃える。
 */
final class AuthSystemResolution
{
    /**
     * @param string|null $template 表示するテンプレートパス（テンプレート表示の場合）。それ以外は null
     * @param 'login'|'signin'|null $redirectTo リダイレクト先の認証ページ（リダイレクトの場合）。それ以外は null
     */
    private function __construct(
        public readonly AuthSystemResolutionType $type,
        private readonly ?string $template,
        private readonly ?string $redirectTo,
    ) {
    }

    /**
     * テンプレートを表示する解決結果を生成する
     *
     * @param string $path 表示するテンプレートパス
     * @return self
     */
    public static function template(string $path): self
    {
        return new self(AuthSystemResolutionType::TEMPLATE, $path, null);
    }

    /**
     * 認証ページ（管理者ログイン/会員サインイン）へリダイレクトする解決結果を生成する
     *
     * @param 'login'|'signin' $authPage リダイレクト先
     * @return self
     */
    public static function redirect(string $authPage): self
    {
        return new self(AuthSystemResolutionType::REDIRECT, null, $authPage);
    }

    /**
     * 認証系URLに該当しない（通常のテンプレート処理へ進む）解決結果を生成する
     *
     * @return self
     */
    public static function none(): self
    {
        return new self(AuthSystemResolutionType::NONE, null, null);
    }

    /**
     * 表示すべき有効なテンプレートが解決されたかどうか
     *
     * tplConfig() が未設定キーに対して空文字を返しうるため、空文字は
     * 「有効なテンプレートなし」として扱う（旧 getAuthSystemTemplate() 時代の
     * `is_string($authPath) && $authPath !== ''` と同じ判定基準を踏襲）。
     *
     * @return bool
     */
    public function isTemplate(): bool
    {
        return $this->type === AuthSystemResolutionType::TEMPLATE
            && $this->template !== null
            && $this->template !== '';
    }

    /**
     * 認証ページへリダイレクトすべきかどうか
     *
     * @return bool
     */
    public function isRedirect(): bool
    {
        return $this->type === AuthSystemResolutionType::REDIRECT;
    }

    /**
     * 認証系URLに該当しない（通常のテンプレート処理へ進む）かどうか
     *
     * @return bool
     */
    public function isNone(): bool
    {
        return $this->type === AuthSystemResolutionType::NONE;
    }

    /**
     * 表示するテンプレートパスを取得する。isTemplate() が false の状態で呼ぶと例外。
     *
     * @return string
     */
    public function getTemplate(): string
    {
        if ($this->template === null || $this->template === '') {
            throw new LogicException('Cannot get template from a non-template AuthSystemResolution: ' . $this->type->value);
        }
        return $this->template;
    }

    /**
     * リダイレクト先の認証ページを取得する。isRedirect() が false の状態で呼ぶと例外。
     *
     * @return 'login'|'signin'
     */
    public function getRedirectTo(): string
    {
        if ($this->redirectTo === null) {
            throw new LogicException('Cannot get redirectTo from a non-redirect AuthSystemResolution: ' . $this->type->value);
        }
        return $this->redirectTo;
    }
}
