package com.gamedog.vididin.manager

import com.ama.core.architecture.util.SpUtil
import com.gamedog.vididin.beans.BaseRecord
import com.gamedog.vididin.beans.RecordCash
import com.gamedog.vididin.beans.RecordCashShow
import com.gamedog.vididin.beans.RecordGold
import com.gamedog.vididin.beans.RecordGoldShow
import com.gamedog.vididin.beans.RecordZero
import com.gamedog.vididin.beans.RecordZeroShow
import com.gamedog.vididin.beans.toShowBean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.concurrent.locks.ReentrantLock


class RecordsManager private constructor() {
    private val mCashHelper by lazy { CashRecordHelper() }
    private val mGoldHelper by lazy { GoldRecordHelper() }
    private val mZeroHelper by lazy { ZeroRecordHelper() }

    companion object {
        @Volatile
        private var instance: RecordsManager? = null

        fun instance(): RecordsManager {
            return instance ?: synchronized(this) {
                instance ?: RecordsManager().also {
                    instance = it
                }
            }
        }
    }


    fun appendCashRecord(newRecord: RecordCash) {
        mCashHelper.addRecord(newRecord)
    }

    fun updateCashRecord(updateRecord: RecordCash) {
        mCashHelper.updateRecord(updateRecord)
    }

    fun appendGoldRecord(newRecord: RecordGold) {
        mGoldHelper.addRecord(newRecord)
    }

    fun appendZeroRecord(newRecord: RecordZero) {
        mZeroHelper.addRecord(newRecord)
    }

    fun getCashRecords() : List<RecordCashShow> {
        val resultList = mutableListOf<RecordCashShow>()
        val dataList = mCashHelper.getRecordList()
        dataList.forEach {
            resultList.add(it.toShowBean())
        }
        return resultList.toList()
    }

    fun getGoldRecords() : List<RecordGoldShow> {
        val resultList = mutableListOf<RecordGoldShow>()
        val dataList = mGoldHelper.getRecordList()
        dataList.forEach {
            resultList.add(it.toShowBean())
        }
        return resultList.toList()
    }

    fun getZeroRecords() : List<RecordZeroShow> {
        val resultList = mutableListOf<RecordZeroShow>()
        val dataList = mZeroHelper.getRecordList()
        dataList.forEach {
            resultList.add(it.toShowBean())
        }
        return resultList.toList()
    }

}





class CashRecordHelper() : BaseRecordHelper<RecordCash>() {
    override val mSpKey = SpUtil.KEY_RECORD_CASH
    override fun loadRecordsFromSp(): List<RecordCash> {
        return SpUtil.instance().getList<RecordCash>(mSpKey)
    }
}

class GoldRecordHelper() : BaseRecordHelper<RecordGold>() {
    override val mSpKey = SpUtil.KEY_RECORD_GOLD
    override fun loadRecordsFromSp(): List<RecordGold> {
        return SpUtil.instance().getList<RecordGold>(mSpKey)
    }
}

class ZeroRecordHelper() : BaseRecordHelper<RecordZero>() {
    override val mSpKey = SpUtil.KEY_RECORD_ZERO
    override fun loadRecordsFromSp(): List<RecordZero> {
        return SpUtil.instance().getList<RecordZero>(mSpKey)
    }
}


abstract class BaseRecordHelper<T: BaseRecord> {
    abstract val mSpKey: String
    private val mbgScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private val mRecordLocker = ReentrantLock()
    private val mRecordList: MutableList<T> by lazy { loadRecordsFromSp().toMutableList() }


    init {
        /*mbgScope.launch {
            mRecordList = loadRecordsFromSp().toMutableList()
        }*/
    }

    abstract fun loadRecordsFromSp() : List<T>


    fun getRecordList(): List<T> {
        return mRecordList.toList()
    }

    private fun saveRecordList() {
        mbgScope.launch {
            try {
                mRecordLocker.lock()
                SpUtil.instance().putList(mSpKey, mRecordList)
            } finally {
                mRecordLocker.unlock()
            }

        }
    }

    fun addRecord(dataBean: T) {
        mbgScope.launch {
            try {
                mRecordLocker.lock()
                mRecordList.add(dataBean)
                saveRecordList()
            } finally {
                mRecordLocker.unlock()
            }

        }
    }

    fun updateRecord(updateBean: T) {
        mbgScope.launch {
            try {
                mRecordLocker.lock()
                mRecordList.forEachIndexed { index, data ->
                    if (data.uuid == updateBean.uuid) {
                        mRecordList.remove(data)
                        mRecordList.add(index, updateBean)
                        return@forEachIndexed
                    }
                }

                saveRecordList()
            } finally {
                mRecordLocker.unlock()
            }
        }
    }

}

