package com.autotech.we1l.fragments

import android.os.Bundle
import android.support.v4.widget.NestedScrollView
import android.support.v7.widget.AppCompatTextView
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.afollestad.materialdialogs.MaterialDialog
import com.android.volley.VolleyError
import com.autotech.we1l.R
import com.autotech.we1l.adapters.AdsAdapter
import com.autotech.we1l.adapters.HotDealsAdapter
import com.autotech.we1l.adapters.PromotionsAdapter
import com.autotech.we1l.app.AppLanguage
import com.autotech.we1l.app.User
import com.autotech.we1l.fragments.dialog_fragments.AdDetailsDialogFragment
import com.autotech.we1l.fragments.dialog_fragments.UnregisteredPromptDialogFragment
import com.autotech.we1l.helpers.InputMap
import com.autotech.we1l.helpers.AnimatorUtils
import com.autotech.we1l.items.Ad
import com.autotech.we1l.items.HotDeal
import com.autotech.we1l.items.Promotion
import com.autotech.we1l.my_classes.BaseAdapter
import com.autotech.we1l.my_classes.BaseFragment
import com.autotech.we1l.my_classes.BaseList
import com.autotech.we1l.tools.*
import com.autotech.we1l.tools.Language.attr_promotions
import com.autotech.we1l.tools.Language.attr_today_s_hot_deals
import com.autotech.we1l.tools.Language.btn_request_ad
import com.autotech.we1l.tools.Language.dialog_opt_no
import com.autotech.we1l.tools.Language.dialog_opt_yes
import com.autotech.we1l.tools.Language.dialog_take_promotion
import com.autotech.we1l.tools.Language.err_no_internet_connection
import com.autotech.we1l.tools.Language.err_server_connection_error
import com.autotech.we1l.tools.Language.prompt_please_retry
import com.autotech.we1l.tools.Language.toast_done_check_email
import com.autotech.we1l.tools.Language.txt_v_bronze_ads
import com.autotech.we1l.tools.Language.txt_v_gold_ads
import com.autotech.we1l.tools.Language.txt_v_no_bronze_ads
import com.autotech.we1l.tools.Language.txt_v_no_gold_ads
import com.autotech.we1l.tools.Language.txt_v_no_silver_ads
import com.autotech.we1l.tools.Language.txt_v_silver_ads
import com.autotech.we1l.volley.IVolleyRequest
import com.autotech.we1l.volley.VolleyRequest
import kotlinx.android.synthetic.main.fragment_ads.*
import org.json.JSONObject
import pub.devrel.easypermissions.EasyPermissions

class AdsFragment : BaseFragment() {

    var sharedAdImageUrl = ""

    private val adsMap = HashMap<String, HashMap<String, BaseList<Ad>>>()
    private val adaptersMap = HashMap<String, HashMap<String, AdsAdapter>>()
    private val rvsMap = HashMap<String, HashMap<String, RecyclerView>>()
    private val noAdsMap = HashMap<String, AppCompatTextView>()

    // Adapters:
    private lateinit var promotionsAdapter: PromotionsAdapter
    private lateinit var hotDealsAdapter: HotDealsAdapter

    // Lists:
    private val hotDeals = BaseList<HotDeal>()
    private val promotions = BaseList<Promotion>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        rootView = inflater.inflate(R.layout.fragment_ads, container, false)
        return rootView
    }

    override fun setupViews() {
        adsMap[Ad.Type.GOLD] = HashMap<String, BaseList<Ad>>().apply {
            put(Ad.Size.FULL, BaseList())
            put(Ad.Size.MID, BaseList())
            put(Ad.Size.SMALL, BaseList())
        }

        adsMap[Ad.Type.SILVER] = HashMap<String, BaseList<Ad>>().apply {
            put(Ad.Size.FULL, BaseList())
            put(Ad.Size.MID, BaseList())
            put(Ad.Size.SMALL, BaseList())
        }

        adsMap[Ad.Type.BRONZE] = HashMap<String, BaseList<Ad>>().apply {
            put(Ad.Size.FULL, BaseList())
            put(Ad.Size.MID, BaseList())
            put(Ad.Size.SMALL, BaseList())
        }

        val onClickListener = object : BaseAdapter.OnClickListener<Ad> {
            override fun onClick(holder: RecyclerView.ViewHolder, position: Int, ad: Ad) {
                AdDetailsDialogFragment().apply {
                    arguments = Bundle().apply {
                        putSerializable(ATTR_AD, ad)
                    }
                }.show(childFragmentManager, "AdDetailsDialogFragment")
            }
        }

        adaptersMap[Ad.Type.GOLD] = HashMap<String, AdsAdapter>().apply {
            put(Ad.Size.FULL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.FULL))
            put(Ad.Size.MID, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.MID))
            put(Ad.Size.SMALL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.SMALL))
        }

        adaptersMap[Ad.Type.SILVER] = HashMap<String, AdsAdapter>().apply {
            put(Ad.Size.FULL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.FULL))
            put(Ad.Size.MID, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.MID))
            put(Ad.Size.SMALL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.SMALL))
        }

        adaptersMap[Ad.Type.BRONZE] = HashMap<String, AdsAdapter>().apply {
            put(Ad.Size.FULL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.FULL))
            put(Ad.Size.MID, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.MID))
            put(Ad.Size.SMALL, AdsAdapter(context!!, BaseList(), onClickListener, Ad.Size.SMALL))
        }

        rvsMap[Ad.Type.GOLD] = HashMap<String, RecyclerView>().apply {
            put(Ad.Size.FULL, gold_full_rv)
            put(Ad.Size.MID, gold_mid_rv)
            put(Ad.Size.SMALL, gold_small_rv)
        }

        rvsMap[Ad.Type.SILVER] = HashMap<String, RecyclerView>().apply {
            put(Ad.Size.FULL, silver_full_rv)
            put(Ad.Size.MID, silver_mid_rv)
            put(Ad.Size.SMALL, silver_small_rv)
        }

        rvsMap[Ad.Type.BRONZE] = HashMap<String, RecyclerView>().apply {
            put(Ad.Size.FULL, bronze_full_rv)
            put(Ad.Size.MID, bronze_mid_rv)
            put(Ad.Size.SMALL, bronze_small_rv)
        }

        noAdsMap[Ad.Type.GOLD] = no_gold_ads
        noAdsMap[Ad.Type.SILVER] = no_silver_ads
        noAdsMap[Ad.Type.BRONZE] = no_bronze_ads

        rvsMap.keys.forEachIndexed { _, key1 ->
            rvsMap[key1]!!.keys.forEachIndexed { _, key2 ->
                Tools.setupRVHorizontal(rvsMap[key1]!![key2], adaptersMap[key1]!![key2])
            }
        }

        hotDealsAdapter = HotDealsAdapter(context!!, hotDeals, object : BaseAdapter.OnClickListener<HotDeal> {
            override fun onClick(holder: RecyclerView.ViewHolder, position: Int, hotDeal: HotDeal) {
                launchProductDetails(context!!, hotDeal.product.id.toString())
            }
        })

        promotionsAdapter = PromotionsAdapter(context!!, promotions, object : BaseAdapter.OnClickListener<Promotion> {
            override fun onClick(holder: RecyclerView.ViewHolder, position: Int, promotion: Promotion) {
                if (User.isValid()) {
                    MaterialDialog.Builder(context!!)
                            .content(AppLanguage.getString(dialog_take_promotion))
                            .positiveText(AppLanguage.getString(dialog_opt_yes))
                            .onPositive { _, _ ->
                                VolleyRequest.getInstance()
                                        .post(REQUEST_TAKE_PROMOTION, InputMap().apply {
                                            put(ATTR_SYSTEM_PASSCODE, SYSTEM_PASSCODE)
                                            put(ATTR_CUSTOMER, User.instance!!.id.toString())
                                            put(ATTR_PROMOTION, promotion.id.toString())
                                        }, object : IVolleyRequest {

                                            override fun onSuccess(response: JSONObject?) {
                                                when (response!!.getInt(ATTR_ERROR_CODE)) {
                                                    CODE_OK -> {
                                                        Toast.makeText(context, AppLanguage.getString(toast_done_check_email), Toast.LENGTH_LONG).show()
                                                    }
                                                }
                                            }

                                            override fun onFail(errorListener: VolleyError?) {
                                                Toast.makeText(context, AppLanguage.getString(err_server_connection_error),
                                                        Toast.LENGTH_LONG).show()
                                            }
                                        })
                            }
                            .negativeText(AppLanguage.getString(dialog_opt_no))
                            .show()
                } else {
                    val unregisteredPromptDialogFragment = UnregisteredPromptDialogFragment()
                    unregisteredPromptDialogFragment.show(childFragmentManager, "UnregisteredPromptDialogFragment")
                }

            }
        })

        Tools.setupRVHorizontal(hot_deals_rv, hotDealsAdapter)

        Tools.setupRVHorizontal(promotions_rv, promotionsAdapter)

        main_layout.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, x, y, oldX, oldY ->
            if (y > oldY && request_ad.fabTextVisibility == View.VISIBLE) {
                request_ad.fabTextVisibility = View.GONE
            } else if (y < oldY && request_ad.fabTextVisibility == View.GONE) {
                request_ad.fabTextVisibility = View.VISIBLE
            }
        })

    }

    override fun setupClickListeners() {
        refresh_layout.setOnRefreshListener {
            crucialRequests()
        }

        request_ad.setOnClickListener {
            launchRequestAd(context!!)
        }
    }

    override fun setupLanguages() {
        super.setupLanguages()
        gold_ads.text = AppLanguage.getString(txt_v_gold_ads)
        silver_ads.text = AppLanguage.getString(txt_v_silver_ads)
        bronze_ads.text = AppLanguage.getString(txt_v_bronze_ads)

        no_gold_ads.text = AppLanguage.getString(txt_v_no_gold_ads)
        no_silver_ads.text = AppLanguage.getString(txt_v_no_silver_ads)
        no_bronze_ads.text = AppLanguage.getString(txt_v_no_bronze_ads)

        promotions_title.text = AppLanguage.getString(attr_promotions)
        todays_title.text = AppLanguage.getString(attr_today_s_hot_deals)

        request_ad.setFabText(AppLanguage.getString(btn_request_ad))
    }

    private fun getAds() {
        loading(main_layout)
        VolleyRequest.getInstance()
                .post(REQUEST_GET_ADS, InputMap().apply {
                    put(ATTR_SYSTEM_PASSCODE, SYSTEM_PASSCODE)
                }, object : IVolleyRequest {

                    override fun onSuccess(response: JSONObject?) {
                        showData(main_layout)
                        refresh_layout.isRefreshing = false
                        when (response!!.getInt(ATTR_ERROR_CODE)) {
                            CODE_OK -> {
                                val data = response.getJSONObject(ATTR_DATA)
                                val itr1 = data.keys().iterator()
                                while (itr1.hasNext()) {
                                    var isSectionEmpty = false
                                    val key1 = itr1.next()
                                    val itr2 = data.getJSONObject(key1).keys().iterator()
                                    while (itr2.hasNext()) {
                                        val key2 = itr2.next()
                                        val array = data.getJSONObject(key1).getJSONArray(key2)
                                        adsMap[key1]!![key2]!!.clear()
                                        for (i in 0 until array.length()) {
                                            adsMap[key1]!![key2]!!.add(Ad(array.getJSONObject(i)))
                                        }
                                        adaptersMap[key1]!![key2]!!.updateData(adsMap[key1]!![key2]!!)
                                        rvsMap[key1]!![key2]!!.visibility = if (adsMap[key1]!![key2]!!.isEmpty()) {
                                            isSectionEmpty = true
                                            View.GONE
                                        } else {
                                            rvsMap[key1]!![key2]!!.scrollToPosition(0)
                                            View.VISIBLE
                                        }
                                    }
                                    noAdsMap[key1]!!.visibility = if (isSectionEmpty) View.VISIBLE else View.GONE
                                }
                            }
                        }
                    }

                    override fun onFail(errorListener: VolleyError?) {
                        showData(main_layout)
                        refresh_layout.isRefreshing = false
                        Toast.makeText(context, AppLanguage.getString(err_server_connection_error), Toast.LENGTH_LONG).show()
                    }
                }).apply { requestsArray.add(this) }
    }

    private fun refresh() {
        adsMap.keys.forEachIndexed { _, key1 ->
            adsMap[key1]!!.keys.forEachIndexed { _, key2 ->
                Tools.setupRV(rvsMap[key1]!![key2]!!, adaptersMap[key1]!![key2]!!)
                adaptersMap[key1]!![key2]!!.updateData(adsMap[key1]!![key2])
            }
        }
    }

    private fun getHotDeals() {
        val inputMap = InputMap()
        inputMap[ATTR_SYSTEM_PASSCODE] = SYSTEM_PASSCODE
        inputMap[ATTR_LANGUAGE] = User.getUserLanguageId(context!!)!!.toString()

        if (!isNetworkAvailable(context!!)) {
            Toast.makeText(context, AppLanguage.getString(err_no_internet_connection), Toast.LENGTH_LONG).show()
        }

        VolleyRequest.getInstance().post(REQUEST_TODAY_HOT_DEALS, inputMap, object : IVolleyRequest {
            override fun onSuccess(response: JSONObject?) {
                if (refresh_layout != null)
                    refresh_layout.isRefreshing = false
                when (response!!.getInt(ATTR_ERROR_CODE)) {
                    CODE_OK -> {
                        hotDeals.clear()
                        val data = response.getJSONObject(ATTR_DATA).getJSONArray(ATTR_DATA)
                        for (i in 0 until data.length()) {
                            hotDeals.add(HotDeal(data.getJSONObject(i)))
                        }
                        hotDealsAdapter.updateData(hotDeals)

                        if (hotDeals.isEmpty()) hot_deals_layout.visibility = View.GONE else AnimatorUtils.show(hot_deals_layout)
                    }
                }
            }

            override fun onFail(errorListener: VolleyError?) {
                if (refresh_layout != null)
                    refresh_layout.isRefreshing = false
                noData(hot_deals_rv, AppLanguage.getString(prompt_please_retry))
                Toast.makeText(context, AppLanguage.getString(err_server_connection_error), Toast.LENGTH_LONG).show()
            }
        }).apply { requestsArray.add(this) }
    }

    private fun getPromotions() {
        if (!isNetworkAvailable(context!!)) Toast.makeText(context, AppLanguage.getString(err_no_internet_connection), Toast.LENGTH_LONG).show()

        VolleyRequest.getInstance()
                .post(REQUEST_PROMOTIONS, InputMap().apply {
                    put(ATTR_SYSTEM_PASSCODE, SYSTEM_PASSCODE)
                    put(ATTR_LANGUAGE, User.getUserLanguageId(context!!)!!.toString())
                }, object : IVolleyRequest {

                    override fun onSuccess(response: JSONObject?) {
                        if (refresh_layout != null)
                            refresh_layout.isRefreshing = false
                        when (response!!.getInt(ATTR_ERROR_CODE)) {
                            CODE_OK -> {
                                promotions.clear()
                                val data = response.getJSONObject(ATTR_DATA).getJSONArray(ATTR_DATA)
                                for (i in 0 until data.length()) {
                                    promotions.add(Promotion(data.getJSONObject(i)))
                                }

                                if (promotions.isEmpty()) promotions_layout.visibility = View.GONE else AnimatorUtils.show(promotions_layout)

                                promotionsAdapter.updateData(promotions)
                            }
                        }
                    }

                    override fun onFail(errorListener: VolleyError?) {
                        if (refresh_layout != null)
                            refresh_layout.isRefreshing = false
                        Toast.makeText(context, AppLanguage.getString(err_server_connection_error), Toast.LENGTH_LONG).show()
                    }
                }).apply { requestsArray.add(this) }
    }

    override fun crucialRequests() {
        getAds()
        getHotDeals()
        getPromotions()
    }

}