package com.sambath.kunkhmer.screen.report

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.View
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.cocking.fight.screen.dialogfragment.StatementDialogViewModel
import com.cocking.fight.screen.dialogfragment.StatementDialogViewState
import com.cocking.fight.screen.report.ReportAdapter
import com.cocking.fight.screen.report.Type
import com.google.android.material.button.MaterialButton
import com.sambath.kunkhmer.R
import com.sambath.kunkhmer.app.App
import com.sambath.kunkhmer.app.ShareActivity
import com.sambath.kunkhmer.app.getErrorCode
import com.sambath.kunkhmer.base.BaseFragment
import com.sambath.kunkhmer.extension.btnClick
import com.sambath.kunkhmer.remote.*
import com.sambath.kunkhmer.util.Const
import com.sambath.kunkhmer.util.ModelPreferencesManager
import com.sambath.kunkhmer.util.PrefHelper
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.fragment_statement.*
import java.text.DecimalFormat
import java.util.concurrent.TimeUnit

/**
 * A simple [Fragment] subclass as the second destination in the navigation.
 */
class StatementFragment : BaseFragment(R.layout.fragment_statement) {
    private lateinit var adapterDep: ReportAdapter
    private lateinit var adapterWith: ReportAdapter
    private lateinit var adapterTb1: ReportAdapter
    private lateinit var adapterTb2: ReportAdapter
    private lateinit var adapterTb3: ReportAdapter
    private lateinit var rvTabDeposit: RecyclerView
    private lateinit var rvTabWithdraw: RecyclerView
    private lateinit var rvTab1: RecyclerView
    private lateinit var rvTab2: RecyclerView
    private lateinit var rvTab3: RecyclerView
    private lateinit var user: User
    private lateinit var layoutManagerDep: LinearLayoutManager
    private lateinit var layoutManagerWit: LinearLayoutManager
    private lateinit var layoutManager1: LinearLayoutManager
    private lateinit var layoutManager2: LinearLayoutManager
    private lateinit var linTabDeposit: LinearLayoutCompat
    private lateinit var linTabWithdraw: LinearLayoutCompat
    private lateinit var linTab1: LinearLayoutCompat
    private lateinit var linTab2: LinearLayoutCompat
    private lateinit var linTab3: LinearLayoutCompat
    private var pageDeposit: Int = 1
    private var totalPageDeposit: Int = 1
    private var totalRecordDeposit: Int = 0
    private var isLoadingDeposit: Boolean = false
    private var pageWithdraw: Int = 1
    private var totalPageWithdraw: Int = 1
    private var totalRecordWithdraw: Int = 0
    private var isLoadingWithdraw: Boolean = false
    private var pageOne: Int = 1
    private var totalPageOne: Int = 1
    private var totalRecordOne: Int = 0
    private var isLoadingOne: Boolean = false
    private var pageTwo: Int = 1
    private var totalPageTwo: Int = 1
    private var totalRecordTwo: Int = 0
    private val rowPerPage : Int = 50
    private var isLoadingTwo: Boolean = false
    private var listDeposit: List<ReportDeposit> = arrayListOf()
    private var listWithdraw: List<ReportWithdraw> = arrayListOf()
    private var listOne: List<ReportOne> = arrayListOf()
    private var listTwo: List<ReportTwo> = arrayListOf()
    private val apiService = App.injectApiService()
    private lateinit var currency: String
    private lateinit var sharePref: PrefHelper
    private lateinit var btnClose: MaterialButton
    private lateinit var statementDialogViewModel: StatementDialogViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        sharePref = App.injectPrefHelper()
        user = ModelPreferencesManager.get<User>(Const.USER_KEY)!!
        statementDialogViewModel =
            StatementDialogViewModel(App.injectApiService(), App.injectPrefHelper())
        (requireActivity() as ShareActivity).apply {
            user = userShare
        }
//        when (user.currencyType) {
//            1 -> {//dollar
//                currency = "$"
//            }
//            2 -> {//riel
//                currency ="៛"
//            }
//            3 -> {//baht
//                currency = "฿"
//            }
//        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        (requireActivity() as? ShareActivity)?.apply {
            groupToolbarIcons.isVisible = false
            layCfStatus.isVisible = false
            btnClose = view.findViewById<MaterialButton>(R.id.btn_close)
            btnClose.setOnClickListener {
                it.btnClick().subscribe {
                    onBackPressed()
                }
            }
        }
        tvDepAmount.text = "Amount ($currency)"
        tvWithAmount.text = "Amount ($currency)"
        tvReportAmount.text = "Amount ($currency)"
        tvStatementAmount.text = "Amount ($currency)"
        linTabDeposit = view.findViewById(R.id.lin_tab_deposit)
        linTabWithdraw = view.findViewById(R.id.lin_tab_withdraw)
        linTab1 = view.findViewById(R.id.lin_tab_1)
        linTab2 = view.findViewById(R.id.lin_tab_2)
        linTab3 = view.findViewById(R.id.lin_tab_3)
        rvTabDeposit = view.findViewById(R.id.rv_tb_deposit)
        rvTabWithdraw = view.findViewById(R.id.rv_tb_withdraw)
        rvTab1 = view.findViewById(R.id.rv_tb1)
        rvTab2 = view.findViewById(R.id.rv_tb2)
        rvTab3 = view.findViewById(R.id.rv_tb3)
        linMainTabDeposit.setOnClickListener {
            bg_select_deposit.visibility = View.VISIBLE
            bg_select_withdraw.visibility = View.INVISIBLE
            bg_select_tab1.visibility = View.INVISIBLE
            bg_select_tab2.visibility = View.INVISIBLE
            bg_select_tab3.visibility = View.INVISIBLE

            linTabDeposit.visibility = View.VISIBLE
            linTabWithdraw.visibility = View.GONE
            linTab1.visibility = View.GONE
            linTab2.visibility = View.GONE
            linTab3.visibility = View.GONE
        }
        linMainTabWithdraw.setOnClickListener {
            bg_select_deposit.visibility = View.INVISIBLE
            bg_select_withdraw.visibility = View.VISIBLE
            bg_select_tab1.visibility = View.INVISIBLE
            bg_select_tab2.visibility = View.INVISIBLE
            bg_select_tab3.visibility = View.INVISIBLE

            linTabDeposit.visibility = View.GONE
            linTabWithdraw.visibility = View.VISIBLE
            linTab1.visibility = View.GONE
            linTab2.visibility = View.GONE
            linTab3.visibility = View.GONE
        }
        linTabMainStatement.setOnClickListener {
            bg_select_deposit.visibility = View.INVISIBLE
            bg_select_withdraw.visibility = View.INVISIBLE
            bg_select_tab1.visibility = View.VISIBLE
            bg_select_tab2.visibility = View.INVISIBLE
            bg_select_tab3.visibility = View.INVISIBLE

            linTabDeposit.visibility = View.GONE
            linTabWithdraw.visibility = View.GONE
            linTab1.visibility = View.VISIBLE
            linTab2.visibility = View.GONE
            linTab3.visibility = View.GONE
        }
        linTabResult.setOnClickListener {
            bg_select_deposit.visibility = View.INVISIBLE
            bg_select_withdraw.visibility = View.INVISIBLE
            bg_select_tab1.visibility = View.INVISIBLE
            bg_select_tab2.visibility = View.VISIBLE
            bg_select_tab3.visibility = View.INVISIBLE

            linTabDeposit.visibility = View.GONE
            linTabWithdraw.visibility = View.GONE
            linTab1.visibility = View.GONE
            linTab2.visibility = View.VISIBLE
            linTab3.visibility = View.GONE
        }
//        linTabReport.setOnClickListener {
//            bg_select_deposit.visibility = View.INVISIBLE
//            bg_select_withdraw.visibility = View.INVISIBLE
//            bg_select_tab1.visibility = View.INVISIBLE
//            bg_select_tab2.visibility = View.INVISIBLE
//            bg_select_tab3.visibility = View.VISIBLE
//
//            linTabDeposit.visibility = View.GONE
//            linTabWithdraw.visibility = View.GONE
//            linTab1.visibility = View.GONE
//            linTab2.visibility = View.GONE
//            linTab3.visibility = View.VISIBLE
//        }
        init()
        exDeposit(ReportBody(rowPerPage, pageDeposit, "", ""))
        exWithdraw(ReportBody(rowPerPage, pageWithdraw, "", ""))
        exOne(ReportBody(rowPerPage, pageOne, "", ""))
        exTwo(ReportBody(rowPerPage, pageTwo, "", ""))
//        statementDialogViewModel.getReportThree()
//        statementDialogViewModel.stateThree.observe(
//            viewLifecycleOwner,
//            androidx.lifecycle.Observer {
//                getReportThree(it)
//            })
        rvTab1.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val total: Int = adapterTb1.itemCount
                if (!isLoadingOne) {
                    if (total < totalRecordOne) {
//                        Log.d("getReport", "itemCount1 :: " + total)
                        exOne(ReportBody(rowPerPage, pageOne, "", ""))
                    }
                }
                super.onScrolled(recyclerView, dx, dy)
            }
        })
        rvTab2.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val visibleItemCount: Int = layoutManager2.childCount
                val pastVisibleItem: Int = layoutManager2.findFirstCompletelyVisibleItemPosition()
                val total: Int = adapterTb2.itemCount
                if (!isLoadingTwo) {
//                    Log.d("getReport", "total :: plus " + total + " :: " + totalRecordTwo)
                    if (total < totalRecordTwo) {
//                        Log.d("getReport", "itemCount2 :: " + total)
                        exTwo(ReportBody(rowPerPage, pageTwo, "", ""))
                    }
                }
                super.onScrolled(recyclerView, dx, dy)
            }
        })

    }

    private fun getReportThree(data: StatementDialogViewState) {
        if (data.reportThreeList != null) {
            progress.isVisible = false
//            Log.d("getReport", "3 :: " + data.reportThreeList!!.size)
            adapterTb3.submitList(data.reportThreeList)
        }
    }

    private fun exOne(reportBetting: ReportBody) {
//        Log.d("getReport", "load listOne")
        isLoadingOne = true
        pageOne++
        val disposables = CompositeDisposable()
        disposables.add(
            apiService.getReportOne(reportBetting)
                .timeout(60, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    progress.isVisible = false
                    if (it.resultCode == "1") {
                        totalPageOne = it.data.totalPages
                        totalRecordOne = it.data.totalRows
                        val li: List<ReportOne> = it.data.reports
                        listOne = concatenate(listOne, li)
//                        Log.d("getReport", "listOne :: " + listOne.size)
                        adapterTb1.submitList(listOne)
                        isLoadingOne = false
                    } else {
                        isLoadingOne = false
                        val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.message.description
                    }
                }, {
                    progress.isVisible = false
                    isLoadingOne = false
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.getErrorCode()
                })
        )
    }

    private fun exTwo(reportResult: ReportBody) {
//        Log.d("getReport", "load listTwo")
        isLoadingTwo = true
        pageTwo++
        val disposables = CompositeDisposable()
        disposables.add(
            apiService.getReportTwo(reportResult)
                .timeout(60, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    progress.isVisible = false
                    if (it.resultCode == "1") {
                        totalPageTwo = it.data.totalPages
                        totalRecordTwo = it.data.totalRows
                        val li: List<ReportTwo> = it.data.results
                        listTwo = concatenate(listTwo, li)
//                        Log.d("getReport", "listTwo :: " + listTwo.size)
                        adapterTb2.submitList(listTwo)
                        isLoadingTwo = false
                    } else {
                        val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.message.description
                    }
                }, {
                    progress.isVisible = false
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.getErrorCode()
                })
        )
    }

    private fun exDeposit(reportResult: ReportBody) {
        isLoadingDeposit = true
        pageDeposit++
        val disposables = CompositeDisposable()
        disposables.add(
            apiService.getReportDeposit(reportResult)
                .timeout(60, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    progress.isVisible = false
                    if (it.resultCode == "1") {
                        tvDepTurnOver.text = it.data.totalAmount
                        totalPageDeposit = it.data.totalPages
                        totalRecordDeposit = it.data.totalRows
                        val li: List<ReportDeposit> = it.data.reports
                        listDeposit = concatenate(listDeposit, li)
                        adapterDep.submitList(listDeposit)
                        isLoadingDeposit = false
                    } else {
                        val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.message.description
                    }
                }, {
                    progress.isVisible = false
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.getErrorCode()
                })
        )
    }

    private fun exWithdraw(reportResult: ReportBody) {
        isLoadingWithdraw = true
        pageWithdraw++
        val disposables = CompositeDisposable()
        disposables.add(
            apiService.getReportWithdraw(reportResult)
                .timeout(60, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    progress.isVisible = false
                    if (it.resultCode == "1") {
                        tvWithTurnOver.text = it.data.totalAmount
                        totalPageWithdraw = it.data.totalPages
                        totalRecordWithdraw = it.data.totalRows
                        val li: List<ReportWithdraw> = it.data.reports
                        listWithdraw = concatenate(listWithdraw, li)
                        adapterWith.submitList(listWithdraw)
                        isLoadingWithdraw = false
                    } else {
                        val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.message.description
                    }
                }, {
                    progress.isVisible = false
                    val message: String = "ប្រតិបត្តិការមិនជោគជ័យ\n" + it.getErrorCode()
                })
        )
    }

    fun init() {
        adapterDep = ReportAdapter(Type.DEPOSIT)
        rvTabDeposit.setHasFixedSize(true)
        layoutManagerDep = LinearLayoutManager(context)
        rvTabDeposit.layoutManager = layoutManagerDep
        rvTabDeposit.adapter = adapterDep

        adapterWith = ReportAdapter(Type.DEPOSIT)
        rvTabWithdraw.setHasFixedSize(true)
        layoutManagerWit = LinearLayoutManager(context)
        rvTabWithdraw.layoutManager = layoutManagerWit
        rvTabWithdraw.adapter = adapterWith

        adapterTb1 = ReportAdapter(Type.WIN)
        rvTab1.setHasFixedSize(true)
        layoutManager1 = LinearLayoutManager(context)
        rvTab1.layoutManager = layoutManager1
        rvTab1.adapter = adapterTb1
        adapterTb1.printButtonListener = { reportOne: ReportOne ->
        }

        adapterTb2 = ReportAdapter(Type.WIN_LOST)
        rvTab2.setHasFixedSize(true)
        layoutManager2 = LinearLayoutManager(context)
        rvTab2.layoutManager = layoutManager2
        rvTab2.adapter = adapterTb2

        adapterTb3 = ReportAdapter(Type.STATEMENT)
        rvTab3.setHasFixedSize(true)
        rvTab3.layoutManager = LinearLayoutManager(context)
        rvTab3.adapter = adapterTb3
    }

    fun currencyFormat(amount: Double): String? {
        val formatter = DecimalFormat("#,###")
        return formatter.format(amount)
    }

    private fun <T> concatenate(vararg lists: List<T>): List<T> {
        return listOf(*lists).flatten()
    }
}
