<?php

/**
 * 文件功能：会员进退场主题服务
 * 统一解析会员等级主题、用户自定义文案、特效和横幅风格，
 * 避免聊天室进场与离场逻辑在多个位置重复拼装数据。
 */

namespace App\Services;

use App\Models\User;

/**
 * 会员进退场与购买成功主题服务
 * 统一生成会员欢迎横幅、离场横幅与购买成功喜报所需的文本、颜色、特效和样式数据。
 */
class VipPresenceService
{
    /**
     * 构造会员进退场主题服务实例。
     */
    public function __construct(
        private readonly VipService $vipService,
    ) {}

    /**
     * 构建会员入场主题数据。
     *
     * @return array<string, string|null|bool>
     */
    public function buildJoinTheme(User $user): array
    {
        return $this->buildTheme($user, 'join');
    }

    /**
     * 构建会员离场主题数据。
     *
     * @return array<string, string|null|bool>
     */
    public function buildLeaveTheme(User $user): array
    {
        return $this->buildTheme($user, 'leave');
    }

    /**
     * 构建会员购买成功主题数据。
     *
     * @return array<string, string|null|bool>
     */
    public function buildPurchaseTheme(User $user): array
    {
        $vipLevel = $user->vipLevel;

        if (! $user->isVip() || ! $vipLevel) {
            return [
                'enabled' => false,
                'type' => 'purchase',
                'text' => null,
                'color' => null,
                'effect' => null,
                'banner_style' => null,
                'level_name' => null,
                'icon' => null,
            ];
        }

        return [
            'enabled' => true,
            'type' => 'purchase',
            'text' => sprintf(
                '恭喜 %s 成功开通【%s %s】，尊享 VIP 特权，大家掌声欢迎！',
                $user->username,
                $vipLevel->icon ?: '👑',
                $vipLevel->name
            ),
            'color' => $vipLevel->color ?: '#f59e0b',
            'effect' => 'fireworks',
            'banner_style' => $vipLevel->joinBannerStyleKey(),
            'level_name' => $vipLevel->name,
            'icon' => $vipLevel->icon,
        ];
    }

    /**
     * 统一构建会员进场或离场的主题数据。
     *
     * @param  string  $type  join|leave
     * @return array<string, string|null|bool>
     */
    private function buildTheme(User $user, string $type): array
    {
        $vipLevel = $user->vipLevel;

        if (! $user->isVip() || ! $vipLevel) {
            return [
                'enabled' => false,
                'type' => $type,
                'text' => null,
                'color' => null,
                'effect' => null,
                'banner_style' => null,
                'level_name' => null,
                'icon' => null,
            ];
        }

        // 先读取个人自定义文案，只有等级允许时才参与覆盖。
        $customMessage = $type === 'join'
            ? $this->formatCustomMessage($user->custom_join_message, $user->username)
            : $this->formatCustomMessage($user->custom_leave_message, $user->username);

        if (! $user->canCustomizeVipPresence()) {
            $customMessage = null;
        }

        // 如果用户没有填写自定义文案，则回退到等级模板。
        $templateMessage = $type === 'join'
            ? $this->vipService->getJoinMessage($user)
            : $this->vipService->getLeaveMessage($user);

        // 只有在等级允许自定义时，才允许覆盖默认特效。
        $customEffect = $type === 'join'
            ? $user->custom_join_effect
            : $user->custom_leave_effect;

        if (! $user->canCustomizeVipPresence()) {
            $customEffect = null;
        }

        return [
            'enabled' => true,
            'type' => $type,
            'text' => $customMessage ?: $templateMessage,
            'color' => $vipLevel->color ?: '#f59e0b',
            'effect' => $this->normalizeEffect($customEffect ?: ($type === 'join' ? $vipLevel->joinEffectKey() : $vipLevel->leaveEffectKey())),
            'banner_style' => $type === 'join' ? $vipLevel->joinBannerStyleKey() : $vipLevel->leaveBannerStyleKey(),
            'level_name' => $vipLevel->name,
            'icon' => $vipLevel->icon,
        ];
    }

    /**
     * 格式化用户自定义文案，支持 {username} 占位符。
     */
    private function formatCustomMessage(?string $message, string $username): ?string
    {
        $message = trim((string) $message);

        if ($message === '') {
            return null;
        }

        return str_replace('{username}', $username, $message);
    }

    /**
     * 把 none 这类占位值转换为 null，方便外部判断是否要播特效。
     */
    private function normalizeEffect(string $effect): ?string
    {
        return $effect === 'none' ? null : $effect;
    }
}
