package com.remax.base.controller

import com.remax.base.BuildConfig
import com.remax.base.ext.KvBoolDelegate
import com.remax.base.ext.KvStringDelegate
import com.remax.base.log.BaseLogger

/**
 * 用户渠道控制器
 * 统一管理用户渠道类型，提供渠道设置和监听功能
 */
object UserChannelController {
    
    private const val TAG = "UserChannelController"
    private const val KEY_USER_CHANNEL = "user_channel_type"
    private const val KEY_CHANNEL_SET_ONCE = "user_channel_set_once"
    
    /**
     * 用户渠道类型枚举
     */
    enum class UserChannelType(val value: String) {
        NATURAL("natural"),  // 自然渠道
        PAID("paid")        // 买量渠道
    }
    
    /**
     * 渠道变化监听接口
     */
    interface ChannelChangeListener {
        /**
         * 渠道类型变化回调
         * @param oldChannel 旧渠道类型
         * @param newChannel 新渠道类型
         */
        fun onChannelChanged(oldChannel: UserChannelType, newChannel: UserChannelType)
    }
    
    // 使用KvStringDelegate进行持久化存储
    private var channelTypeString by KvStringDelegate(KEY_USER_CHANNEL, getDefaultChannelValue())
    private var channelSetOnce by KvBoolDelegate(KEY_CHANNEL_SET_ONCE, false)
    
    // 监听器列表
    private val listeners = mutableListOf<ChannelChangeListener>()
    
    /**
     * 获取默认渠道值
     * 优先使用BuildConfig中的配置，如果没有则使用NATURAL作为默认值
     * @return 默认渠道值
     */
    private fun getDefaultChannelValue(): String {
        return try {
            // 尝试从BuildConfig获取默认渠道配置
            val defaultChannel = BuildConfig.DEFAULT_USER_CHANNEL
            
            // 验证配置值是否有效
            if (UserChannelType.values().any { it.value == defaultChannel }) {
                BaseLogger.d("使用BuildConfig默认渠道: %s", defaultChannel)
                defaultChannel
            } else {
                BaseLogger.w("BuildConfig默认渠道无效: %s，使用NATURAL", defaultChannel)
                UserChannelType.NATURAL.value
            }
        } catch (e: Exception) {
            // 如果无法获取BuildConfig或字段不存在，使用默认值
            BaseLogger.e("获取BuildConfig默认渠道失败，使用NATURAL", e)
            UserChannelType.NATURAL.value
        }
    }
    
    /**
     * 获取当前用户渠道类型
     * @return 当前渠道类型，默认为自然渠道
     */
    fun getCurrentChannel(): UserChannelType {
        return try {
            val currentChannelString = channelTypeString
            if (currentChannelString.isNullOrEmpty()) {
                BaseLogger.w("渠道字符串为空，使用默认NATURAL")
                return UserChannelType.NATURAL
            }
            
            UserChannelType.values().find { it.value == currentChannelString } 
                ?: run {
                    BaseLogger.w("无效的渠道字符串: %s，使用默认NATURAL", currentChannelString)
                    UserChannelType.NATURAL
                }
        } catch (e: Exception) {
            BaseLogger.e("获取当前渠道失败，使用默认NATURAL", e)
            UserChannelType.NATURAL
        }
    }
    
    /**
     * 设置用户渠道类型
     * @param channelType 新的渠道类型
     * @return 是否成功设置（如果已经设置过则返回false）
     */
    fun setChannel(channelType: UserChannelType): Boolean {
        // 如果已经设置过，则不再允许修改
        if (channelSetOnce) {
            BaseLogger.w("用户渠道已设置过，无法修改: %s", getCurrentChannel().value)
            return false
        }
        
        val oldChannel = getCurrentChannel()
        if (oldChannel != channelType) {
            channelTypeString = channelType.value
            channelSetOnce = true // 标记为已设置
            
            BaseLogger.d("用户渠道设置成功: %s -> %s", oldChannel.value, channelType.value)
            
            // 通知所有监听器
            notifyChannelChanged(oldChannel, channelType)
        } else {
            BaseLogger.d("用户渠道未变化，保持: %s", channelType.value)
        }
        return true
    }
    
    /**
     * 添加渠道变化监听器
     * @param listener 监听器
     */
    fun addChannelChangeListener(listener: ChannelChangeListener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener)
        }
    }
    
    /**
     * 移除渠道变化监听器
     * @param listener 监听器
     */
    fun removeChannelChangeListener(listener: ChannelChangeListener) {
        listeners.remove(listener)
    }
    
    /**
     * 清除所有监听器
     */
    fun clearListeners() {
        listeners.clear()
    }
    
    /**
     * 通知所有监听器渠道变化
     * @param oldChannel 旧渠道类型
     * @param newChannel 新渠道类型
     */
    private fun notifyChannelChanged(oldChannel: UserChannelType, newChannel: UserChannelType) {
        BaseLogger.d("通知渠道变化监听器，监听器数量: %d", listeners.size)
        listeners.forEach { listener ->
            try {
                listener.onChannelChanged(oldChannel, newChannel)
            } catch (e: Exception) {
                // 忽略监听器异常，避免影响其他监听器
                BaseLogger.e("渠道变化监听器异常", e)
            }
        }
    }
    
    /**
     * 检查是否为自然渠道
     * @return 是否为自然渠道
     */
    fun isNaturalChannel(): Boolean {
        return getCurrentChannel() == UserChannelType.NATURAL
    }
    
    /**
     * 检查是否为买量渠道
     * @return 是否为买量渠道
     */
    fun isPaidChannel(): Boolean {
        return getCurrentChannel() == UserChannelType.PAID
    }
    
    /**
     * 检查是否已经设置过渠道
     * @return 是否已经设置过
     */
    fun isChannelSetOnce(): Boolean {
        return channelSetOnce
    }
    
    /**
     * 重置渠道设置状态（仅用于测试或特殊情况）
     * 注意：此方法会清除已设置标记，允许重新设置渠道
     */
    fun resetChannelSetting() {
        channelSetOnce = false
    }
    
    /**
     * 强制设置渠道类型（忽略已设置标记）
     * 注意：此方法仅用于特殊情况，如测试或数据迁移
     * @param channelType 新的渠道类型
     */
    fun forceSetChannel(channelType: UserChannelType) {
        val oldChannel = getCurrentChannel()
        channelTypeString = channelType.value
        channelSetOnce = true
        
        BaseLogger.d("强制设置用户渠道: %s -> %s", oldChannel.value, channelType.value)
        
        // 通知所有监听器
        notifyChannelChanged(oldChannel, channelType)
    }
    
    /**
     * 获取渠道类型字符串（用于日志等）
     * @return 渠道类型字符串
     */
    fun getChannelString(): String {
        return getCurrentChannel().value
    }
}
