package com.remax.visualnovel.extension

import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import com.remax.visualnovel.widget.ui.bannerindicator.RectangleIndicator
import com.youth.banner.Banner

/**
 * Created by HJW on 2025/7/31
 */

/**
 * 安全反转列表，不使用 reversed() 或 asReversed()，避免 NoSuchMethodError。
 * @param input 任意输入（List、null 或其他类型）。
 * @return 反转后的列表，若输入无效则返回空列表。
 */
fun <T> Any?.safeReverseList(): List<T> {
    // 处理 null 输入
    if (this == null) {
        return emptyList()
    }

    // 检查是否为 List 类型
    if (this !is List<*>) {
        return emptyList()
    }

    // 创建新的可变列表用于存储反转结果
    val result = mutableListOf<T>()

    // 手动反转：从最后一个元素开始向前遍历
    for (i in this.size - 1 downTo 0) {
        try {
            // 安全转换元素类型，避免 ClassCastException
            @Suppress("UNCHECKED_CAST")
            val element = this[i] as T
            result.add(element)
        } catch (e: ClassCastException) {
            // 类型转换失败，记录日志并跳过该元素
            println("跳过无效元素: ${e.message}")
            continue
        }
    }

    // 返回只读列表，防止外部修改
    return result.toList()
}


/**
 * 将数据按 @param chunkNum 个一页展示在banner上
 * @receiver List<T> 原始数据
 * @param indicator RectangleIndicator banner指示器
 * @param banner Banner<*, *> banner控件
 * @param transform Function1<T, RewardUIData>  请求回来的数据转换成UI数据
 * @param placeholderFactory 新增工厂函数，用于创建占位符
 */
inline fun <reified T, reified U> List<T>.getBannerChunkData(
    chunkNum: Int,
    banner: Banner<*, *>,
    transform: (T) -> U,
    placeholderFactory: (U) -> U,
    owner: LifecycleOwner? = null,
    indicator: RectangleIndicator? = null
): List<List<U>> {
    val splitData = this.map(transform).chunked(chunkNum).toMutableList()
    indicator?.isVisible = splitData.size > 1
    /**
     * 从第二页开始，补满8个item，预防高度发生变化
     */
    splitData.forEachIndexed { index, rewardUIData ->
        if (index > 0 && rewardUIData.size < chunkNum) {
            val mutableData = rewardUIData.toMutableList()
            val first = mutableData.firstOrNull()
            repeat(chunkNum - mutableData.size) {
                first?.let {
                    mutableData.add(placeholderFactory(it))
                }
            }
            splitData[index] = mutableData
        }
    }
    indicator?.let {
        banner.setIndicator(indicator, false)
    }
    banner.addBannerLifecycleObserver(owner)
    return splitData.toList()
}