package com.kdanmobile.reader.thumb

import android.app.Activity
import android.app.AlertDialog
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.helper.ItemTouchHelper
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import com.kdanmobile.reader.R
import com.kdanmobile.reader.ReaderActivity
import com.kdanmobile.reader.thumb.mode.EditMode
import com.kdanmobile.reader.thumb.mode.NormalMode
import com.kdanmobile.reader.widget.drag.OnRecyclerItemClickListener
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_pdf_thumb.*
import java.io.File

abstract class PdfThumbActivity: AppCompatActivity(), PdfThumbAdapter.PageMoveHandler {

    abstract fun provideIntent():Intent
    abstract fun canDelete(): Boolean
    abstract fun canExtract() : Boolean
    abstract fun canChangePage() : Boolean
    abstract fun getTrialDays(): Long
    abstract fun getSubscribeRunnable(): Runnable
    abstract fun getHeight(): Int
    abstract fun getWidth(): Int
    abstract fun getPadding(): Int
    abstract fun getColumns(): Int
    abstract fun getCreateExtractBlankFile(pdfFilename: String, selectPage: String): File

    companion object {
        const val THUMB_NORMAL = 0
    }
    private lateinit var viewModel: PdfThumbViewModel
    private lateinit var pdfThumbAdapter: PdfThumbAdapter

    private var disposable: Disposable? = null
    private var editMode = EditMode()
    private var normalMode = NormalMode()
    private var columns = 0
    private var height = 0
    private var width = 0
    private var padding = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        setContentView(R.layout.activity_pdf_thumb)
        setSupportActionBar(toolbar_pdfThumb)
        val factory = PdfThumbViewModelFactory()
        viewModel = ViewModelProviders.of(this, factory).get(PdfThumbViewModel::class.java)
        initView()
        initToolBar()
    }

    private fun initView() {
        id_recyclerview.setHasFixedSize(true)
        setViewSize()
        disposable = viewModel.initThumbData(height, width, padding)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    pdfThumbAdapter = PdfThumbAdapter(it,this, viewModel.thumbnailHandler)
                    id_recyclerview.adapter = pdfThumbAdapter
                    id_recyclerview.layoutManager = GridLayoutManager(this, columns)
                    id_recyclerview.addOnItemTouchListener(object : OnRecyclerItemClickListener(id_recyclerview) {
                        override fun onItemClick(vh: RecyclerView.ViewHolder) {
                            viewModel.mode.onPageItemClick(this@PdfThumbActivity, vh.adapterPosition, THUMB_NORMAL, viewModel.mapSelect, pdfThumbAdapter)
                        }
                        override fun onItemLongClick(vh: RecyclerView.ViewHolder) {}
                    })
                    id_recyclerview.scrollToPosition(viewModel.pdfInfoHandler.getCurrentPage())
                    val itemTouchHelperCallBack = ItemTouchHelpCallback(pdfThumbAdapter)
                    val itemTouchHelper = ItemTouchHelper(itemTouchHelperCallBack)
                    itemTouchHelper.attachToRecyclerView(id_recyclerview)
                }, {
                    it.printStackTrace()
                })
    }

    private fun initToolBar() {
        viewModel.isEdit.also {
            if (it){
                toolbar_pdfThumb.setNavigationIcon(R.drawable.selector_close_btn_navigation)
                supportActionBar?.title = resources.getString(R.string.pdf_thumb_title_edit_mode)
            } else {
                toolbar_pdfThumb.setNavigationIcon(R.drawable.selector_arrowback)
                supportActionBar?.title = resources.getString(R.string.thumbnail)
            }
        }
        toolbar_pdfThumb.setNavigationOnClickListener(this::onClickToolBarNavigation)
    }

    private fun setViewSize() {
        if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            if (ScreenUtil.getXDp(this) >= 720) {
                columns = 6
                width = (ScreenUtil.getScreenWidth(this) / 6.6).toInt()
            } else {
                columns = 5
                width = (ScreenUtil.getScreenWidth(this) / 5.5).toInt()
            }
        } else {
            if (ScreenUtil.getXDp(this) >= 720) {
                columns = 4
                width = (ScreenUtil.getScreenWidth(this) / 4.4).toInt()
            } else {
                columns = 3
                width = (ScreenUtil.getScreenWidth(this) / 3.3).toInt()
            }
        }
        padding = (ScreenUtil.getScreenWidth(this) - width * columns) / 2 * (columns + 1)
        height = 234 * width / 180
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        if (!viewModel.passwordHandler.isNeedPassword()) menuInflater.inflate(R.menu.menu_thumb, menu)
        return true
    }

    override fun onPrepareOptionsMenu(menu: Menu): Boolean {
        if (!viewModel.passwordHandler.isNeedPassword()) {
            when (viewModel.isEdit) {
                true -> {
                    val isExtractEnable = viewModel.hasSelectItem()
                    val isRotateEnable = viewModel.hasSelectItem()
                    val isDeleteEnable = viewModel.hasSelectItem() && !viewModel.isAllItemSelect()
                    val visible = viewModel.isPdf
                    menu.findItem(R.id.item_action_edit_thumb).isVisible = false
                    menu.findItem(R.id.item_action_select_all_thumb)
                            .setVisible(visible)
                            .setIcon(if (viewModel.isAllItemSelect()) R.drawable.selector_deselect_all_btn_action_bar else R.drawable.selector_select_all_btn_action_bar)
                    menu.findItem(R.id.item_action_extract_thumb)
                            .setVisible(visible).isEnabled = isExtractEnable
                    menu.findItem(R.id.item_action_rorate_thumb)
                            .setVisible(visible).isEnabled = isRotateEnable
                    menu.findItem(R.id.item_action_delete_thumb)
                            .setVisible(visible).isEnabled = isDeleteEnable
                }
                false -> {
                    val visible = viewModel.isPdf
                    menu.findItem(R.id.item_action_edit_thumb).isVisible = visible
                    menu.findItem(R.id.item_action_select_all_thumb).isVisible = false
                    menu.findItem(R.id.item_action_extract_thumb).isVisible = false
                    menu.findItem(R.id.item_action_rorate_thumb).isVisible = false
                    menu.findItem(R.id.item_action_delete_thumb).isVisible = false
                }
            }
        }
        return super.onPrepareOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.item_action_edit_thumb -> switchToEditMode()
            R.id.item_action_select_all_thumb -> onClickSelectAllBtn()
            R.id.item_action_rorate_thumb -> onClickRotateBtn()
            R.id.item_action_delete_thumb -> onClickDeleteBtn()
            R.id.item_action_extract_thumb -> onClickExtractBtn()
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onBackPressed() {
        val data = Intent()
        data.putExtra("result", viewModel.pdfInfoHandler.getCurrentPage())
        data.putExtra("operate", THUMB_NORMAL)
        setResult(Activity.RESULT_OK, data)
        finish()
    }

    override fun onStop() {
        viewModel.updateBookmarkDisplay()
        viewModel.temporarySave()
        super.onStop()
    }

    private fun onClickToolBarNavigation(v: View){
        when(viewModel.isEdit){
            true -> {
                switchToNormalMode()
                invalidateOptionsMenu()
                onModeSwitched()
            }
            false -> {
                onBackPressed()
            }
        }
    }

    private fun switchToEditMode() {
        viewModel.mode = editMode
        viewModel.isEdit = true
        viewModel.thumbData.isEditMode = true
        pdfThumbAdapter.setThumbData(viewModel.thumbData)
        onModeSwitched()
    }

    private fun switchToNormalMode() {
        viewModel.mode = normalMode
        viewModel.isEdit = false
        viewModel.thumbData.isEditMode = false
        pdfThumbAdapter.setThumbData(viewModel.thumbData)
        viewModel.setAllUnSelect()
        onModeSwitched()
    }

    private fun onModeSwitched() {
        updateToolbar()
    }

    fun updateToolbar() {
        invalidateOptionsMenu()
        when(viewModel.isEdit) {
            true -> {
                supportActionBar?.setTitle(R.string.pdf_thumb_title_edit_mode)
                toolbar_pdfThumb.setNavigationIcon(R.drawable.selector_close_btn_navigation)
            }
            false -> {
                supportActionBar?.setTitle(R.string.thumbnail)
                toolbar_pdfThumb.setNavigationIcon(R.drawable.selector_arrowback)
            }
        }
    }

    private fun onClickSelectAllBtn() {
        if (!viewModel.isAllItemSelect()) {
            viewModel.setAllSelect()
        } else {
            viewModel.setAllUnSelect()
        }
        pdfThumbAdapter.notifyItemRangeChanged(0, pdfThumbAdapter.itemCount)
        updateToolbar()
    }

    private fun onClickRotateBtn() {
        val runnable = Runnable {
            for (key in viewModel.mapSelect.keys) {
                if (viewModel.mapSelect[key] == true) {
                    pdfThumbAdapter.notifyItemChanged(key)
                }
            }
        }
        viewModel.pageRotate(runnable)
    }

    private fun onClickExtractBtn() {
        if (!canExtract()) {
            getSubscribeRunnable().run()
        } else {
            val pagesForFile = FileUtil.generateSelectedPagesString(viewModel.getSelectPage())
            val dst = FileUtil.createExtractBlankFile(viewModel.pdfInfoHandler.getOpenPdfFilename(), pagesForFile, FileUtil.getKdanPDFReaderFolder())
            val runnable = Runnable {
                val filePath = String.format("/%s/%s", dst.parentFile.name, dst.name)
                val msg = getString(R.string.pdf_thumb_extract_page_suc_dialog_msg, filePath)
                AlertDialog.Builder(this)
                        .setTitle(R.string.pdf_thumb_extract_page_suc_dialog_title)
                        .setMessage(msg)
                        .setPositiveButton(R.string.pdf_thumb_extract_page_suc_dialog_positive_btn) { _, _ ->
                            val intent = provideIntent()
                            intent.putExtra(ReaderActivity.KEY_FILE_ABSOLUTE, dst.absolutePath)
                            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
                            startActivity(intent)
                        }
                        .show()
            }
            val runnableForFail = Runnable {
                AlertDialog.Builder(this)
                        .setTitle(R.string.pdf_thumb_extract_page_failed_dialog_title)
                        .setMessage(R.string.pdf_thumb_extract_page_failed_dialog_msg)
                        .show()
            }
            viewModel.pageExtract(dst, runnable, runnableForFail)
        }
    }

    private fun onClickDeleteBtn() {
        if (!canDelete()) {
            getSubscribeRunnable().run()
        } else {
            val builder = AlertDialog.Builder(this)
            builder.setMessage(R.string.pdf_thumb_delete_check_dialog_msg)
            builder.setNegativeButton(android.R.string.no) { dialog, _ -> dialog.dismiss() }
            builder.setPositiveButton(android.R.string.yes) { _, _ ->
                viewModel.pageDelete(Runnable {
                    viewModel.setAllUnSelect()
                    updateToolbar()
                    pdfThumbAdapter.notifyDataSetChanged() }) }
            builder.create().show()
        }
    }


    override fun onPageMove(fromPage: Int, toPage: Int) {
        if (!canChangePage()) {
            getSubscribeRunnable().run()
        } else {
            viewModel.reorderPage(fromPage, toPage)
        }
    }
}