package com.jishisongfu.duobibi.util

import android.content.Context
import android.util.Log
import com.jishisongfu.duobibi.data.repo.PriceRepository
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

/**
 * 示例数据注入器(占审用)。
 *
 * 调用方:MainActivity 在隐私同意之后调一次 [seedIfNeeded],幂等。
 *
 * 三道闸:
 *   1. DemoDataPrefs.seeded(ctx) = true → 已处理过(不论 seed 成功还是跳过),直接返回
 *   2. 用户已有真实数据(cluster 不为空)→ 老用户升级,**不污染** 他的列表;但 mark seeded=true 以后不再判断
 *   3. 全新空库 → 先清残留 demo(防部分 seed 重试重复)→ 调 repo.seedDemoData() 注入 → mark seeded=true
 *
 * 并发:[mutex] 保证同时只一个 seedIfNeeded 在跑。Activity 重建 / 快速 backstack 会触发多次,
 * 但 Mutex 排队后第二份进来会发现 seeded=true 直接返回,不会重复注入。
 */
object DemoDataSeeder {

    private const val TAG = "DUOBIBI-DEMO"

    private val mutex = Mutex()

    suspend fun seedIfNeeded(ctx: Context, repo: PriceRepository) {
        if (DemoDataPrefs.seeded(ctx)) return
        mutex.withLock {
            // 双重检查:第一份跑完后第二份才拿到锁,此时 seeded 已 true,直接返回
            if (DemoDataPrefs.seeded(ctx)) return@withLock
            try {
                // 老用户升级 / 用户在我们 seed 之前已经手动记过价 → 不污染真实数据
                if (repo.hasAnyRealData()) {
                    Log.i(TAG, "skip seed: user has real data already")
                    DemoDataPrefs.setSeeded(ctx, true)
                    return@withLock
                }
                // 防"上次 seed 中途进程被杀,残留半套 demo"的重试场景:
                // 先 clearDemoData 把残留清掉再 seed,保证最终是干净的 17 条而不是叠加。
                repo.clearDemoData()
                repo.seedDemoData()
                DemoDataPrefs.setSeeded(ctx, true)
                Log.i(TAG, "demo data seeded")
            } catch (e: Exception) {
                Log.w(TAG, "seed failed: ${e.message}", e)
                // 失败不 mark seeded,下次冷启动还会重试(顶部 clearDemoData 保证幂等)
            }
        }
    }

    /**
     * 用户在设置页主动清除。语义:**"我不要 demo 数据"** —— 所以这里 setSeeded=true
     * 阻止下次冷启动自动重注入。用户已表态,我们尊重。
     *
     * 副作用:这也意味着用户清完之后想"找回 demo"得清 App 数据走首启流程。占审期可接受。
     */
    suspend fun clearAndUnseed(ctx: Context, repo: PriceRepository) {
        mutex.withLock {
            repo.clearDemoData()
            DemoDataPrefs.setSeeded(ctx, true)
            Log.i(TAG, "demo data cleared (user request)")
        }
    }
}
