package com.doverfuelingsolutions.issp.view

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import com.doverfuelingsolutions.issp.R
import com.doverfuelingsolutions.issp.api.SystemApi
import com.doverfuelingsolutions.issp.data.GlobalData
import com.doverfuelingsolutions.issp.databinding.ActivityMainBinding
import com.doverfuelingsolutions.issp.fusion.FusionManager
import com.doverfuelingsolutions.issp.fusion.FusionStatus
import com.doverfuelingsolutions.issp.fusion.callback.OnFusionStatus
import com.doverfuelingsolutions.issp.utils.DFSToastUtil
import com.doverfuelingsolutions.issp.utils.WindowUtil
import com.doverfuelingsolutions.issp.utils.log.DFSLog
import com.doverfuelingsolutions.issp.view.fragment.FragmentReconnect
import com.doverfuelingsolutions.issp.view.fragment.FragmentSelect
import com.doverfuelingsolutions.issp.view.util.LoadingDialogBuilder
import com.wayne.www.waynelib.fdc.FdcClient
import com.youth.banner.adapter.BannerImageAdapter
import com.youth.banner.holder.BannerImageHolder
import kotlinx.coroutines.launch
import java.io.File
import java.util.*

class MainActivity : AppCompatActivity(),
    View.OnClickListener,
    OnFusionStatus {

    companion object {
        fun start(context: Context) {
            Intent(context, MainActivity::class.java).let { context.startActivity(it) }
        }
    }

    private val binding: ActivityMainBinding by lazy {
        DataBindingUtil.setContentView(
            this,
            R.layout.activity_main
        )
    }
    private val mainViewModel: MainViewModel by viewModels()

    private var dialogFusionLinking: AlertDialog? = null

    private var isBlockBackPress = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.lifecycleOwner = this
        binding.mainViewModel = mainViewModel
        binding.handler = this

        supportActionBar?.hide()
        initView()
        initBanner()

        FusionManager.onFusionStatus = this
        lifecycle.addObserver(FusionManager)
    }

    override fun onResume() {
        super.onResume()
        WindowUtil.setFullscreen(this)
        dialogFusionLinking?.let {
            if (it.isShowing) it.hide()
        }
    }

    override fun onDestroy() {
        super.onDestroy()

        FusionManager.onFusionStatus = null
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        lifecycleScope.launch {
            when (requestCode) {
                PreferenceActivity.codeRequestResult -> {
                    data?.let {
                        val isMiddleModified =
                            it.getBooleanExtra(PreferenceActivity.isMiddleModified, false)
                        val isFuelModified =
                            it.getBooleanExtra(PreferenceActivity.isFuelModified, false)
                        if (!isFuelModified && !isMiddleModified) return@let

                        if (isMiddleModified || FusionManager.stateFusion != FdcClient.FdcClientState.Connected) {
                            setFusionLinkingLoading()
                            FusionManager.restart(true)
                        } else if (isFuelModified && FusionManager.stateFusion == FdcClient.FdcClientState.Connected) {
                            val dialog = LoadingDialogBuilder(this@MainActivity)
                                .setLoadingText(R.string.in_get_fuel)
                                .show()
                            val result = FusionManager.getPumpInfo()
                            dialog.dismiss()
                            if (result.success) {
                                DFSToastUtil.success(R.string.get_fuel_success)
                            } else {
                                DFSToastUtil.fail(R.string.get_fuel_failed)
                            }
                        }
                    }
                }
            }
        }
    }

    override fun onBackPressed() {
        if (!isBlockBackPress) super.onBackPressed()
    }

    override fun onClick(v: View?) {
        when (v) {
            binding.stationLogo,
            binding.stationName -> {
                DFSLog.i("refresh station info")
                lifecycleScope.launch {
                    val resultPhone = SystemApi.sessionInfo()
                    if (resultPhone.success && resultPhone.data != null) {
                        GlobalData.stationTel.set(resultPhone.data.phoneNumber)
                        GlobalData.businessName.set(resultPhone.data.currentbuName)
                    }

                    val resultLogo = SystemApi.stationLogo()
                    if (resultLogo.success && !resultLogo.data.isNullOrBlank()) {
                        GlobalData.stationLogoFileName.set(resultLogo.data)
                    }

                    initView()
                    DFSToastUtil.success(R.string.refresh_success)
                }
            }
        }
    }

    override fun onFusionStatus(status: FusionStatus) {
        DFSLog.i("Fusion output status: ${status.name.toLowerCase(Locale.CHINESE)}")
        lifecycleScope.launch {
            dialogFusionLinking?.hide()
            when (status) {
                FusionStatus.Connecting -> {
                    setFusionLinkingLoading()
                }
                FusionStatus.Connected -> {
                    DFSToastUtil.success(R.string.connect_fusion_success)
                    setFragment(FragmentSelect())
                }
                FusionStatus.Disconnected -> {
                    // Disconnected reason
                    // 1. Network problem.
                    // 2. Communication exception and failed retry.
                    DFSToastUtil.fail(R.string.disconnect_fusion)
                    setFragment(FragmentReconnect.build {
                        setFusionLinkingLoading()
                    })
                }
            }
        }
    }

    private fun initView() {
        mainViewModel.stationName.value = GlobalData.businessName.get()
        if (GlobalData.stationLogoFileName.get().isNotEmpty()) {
            binding.stationLogo.setImageURI(Uri.fromFile(File(filesDir, GlobalData.stationLogoFileName.get())))
        }
    }

    private fun initBanner() {
        binding.banner.run {
            addBannerLifecycleObserver(this@MainActivity)
            scrollTime = 500
            adapter =
                object : BannerImageAdapter<Int>(listOf(R.mipmap.banner_1, R.mipmap.banner_2)) {
                    override fun onBindView(
                        holder: BannerImageHolder,
                        data: Int,
                        position: Int,
                        size: Int
                    ) {
                        holder.imageView.setImageResource(data)
                    }
                }
        }
    }

    private fun setFusionLinkingLoading() {
        // Don't dismiss dialog, just show & hide for reuse.
        if (dialogFusionLinking == null) {
            dialogFusionLinking = LoadingDialogBuilder(this@MainActivity)
                .setTitle(R.string.fusion_in_connect)
                .setLoadingText(R.string.reconnect_fusion_tip)
                .setCancelable(false)
                .show()
            dialogFusionLinking?.window?.let { WindowUtil.setFullscreen(it) }
        } else {
            dialogFusionLinking?.show()
        }
    }

    fun setFragment(fragment: Fragment, back: Boolean = false) {
        supportFragmentManager.beginTransaction().run {
            replace(R.id.fragmentBox, fragment)
            if (back) {
                addToBackStack(fragment::class.java.simpleName)
            }
            commit()
        }
    }

    fun blockBackPress(isBlock: Boolean) {
        isBlockBackPress = isBlock
    }

    class MainViewModel : ViewModel() {
        val stationName = MutableLiveData("")
    }
}