package com.fsck.k9.ui.settings.export

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.fsck.k9.ui.R
import com.fsck.k9.ui.observeNotNull
import com.mikepenz.fastadapter.FastAdapter
import com.mikepenz.fastadapter.adapters.ItemAdapter
import org.koin.androidx.viewmodel.ext.android.viewModel

class SettingsExportFragment : Fragment() {
    private val viewModel: SettingsExportViewModel by viewModel()

    private lateinit var settingsExportAdapter: FastAdapter<CheckBoxItem<*>>
    private lateinit var itemAdapter: ItemAdapter<CheckBoxItem<*>>

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        if (savedInstanceState != null) {
            viewModel.initializeFromSavedState(savedInstanceState)
        }

        val viewHolder = ViewHolder(view)
        initializeSettingsExportList(viewHolder.settingsExportList)

        viewHolder.exportButton.setOnClickListener { viewModel.onExportButtonClicked() }
        viewHolder.shareButton.setOnClickListener { viewModel.onShareButtonClicked() }

        viewModel.getUiModel().observeNotNull(this) { viewHolder.updateUi(it) }
        viewModel.getActionEvents().observeNotNull(this) { handleActionEvents(it) }
    }

    private fun initializeSettingsExportList(recyclerView: RecyclerView) {
        itemAdapter = ItemAdapter()
        settingsExportAdapter = FastAdapter.with(itemAdapter).apply {
            setHasStableIds(true)
            onClickListener = { _, _, item: CheckBoxItem<*>, position ->
                viewModel.onSettingsListItemSelected(position, !item.isSelected)
                true
            }
            addEventHook(
                CheckBoxClickEvent { position, isSelected ->
                    viewModel.onSettingsListItemSelected(position, isSelected)
                },
            )
        }

        recyclerView.adapter = settingsExportAdapter
    }

    private fun ViewHolder.updateUi(model: SettingsExportUiModel) {
        when (model.exportButton) {
            ButtonState.DISABLED -> {
                exportButton.isVisible = true
                exportButton.isEnabled = false
            }
            ButtonState.ENABLED -> {
                exportButton.isVisible = true
                exportButton.isEnabled = true
            }
            ButtonState.INVISIBLE -> exportButton.visibility = View.INVISIBLE
            ButtonState.GONE -> exportButton.visibility = View.GONE
        }

        shareButton.isVisible = model.isShareButtonVisible
        progressBar.isVisible = model.isProgressVisible

        when (model.statusText) {
            StatusText.HIDDEN -> statusText.isVisible = false
            StatusText.EXPORT_SUCCESS -> {
                statusText.isVisible = true
                statusText.text = getString(R.string.settings_export_success_generic)
            }
            StatusText.PROGRESS -> {
                statusText.isVisible = true
                statusText.text = getString(R.string.settings_export_progress_text)
            }
            StatusText.EXPORT_FAILURE -> {
                statusText.isVisible = true
                statusText.text = getString(R.string.settings_export_failure)
            }
        }

        setSettingsList(model.settingsList, model.isSettingsListEnabled)
    }

    // TODO: Update list instead of replacing it completely
    private fun ViewHolder.setSettingsList(items: List<SettingsListItem>, enable: Boolean) {
        val checkBoxItems = items.map { item ->
            val checkBoxItem = when (item) {
                is SettingsListItem.GeneralSettings -> GeneralSettingsItem()
                is SettingsListItem.Account -> AccountItem(item)
            }

            checkBoxItem.apply {
                isSelected = item.selected
                isEnabled = enable
            }
        }

        itemAdapter.set(checkBoxItems)

        settingsExportList.isEnabled = enable
    }

    private fun handleActionEvents(action: Action) {
        when (action) {
            is Action.PickDocument -> pickDocument(action.fileNameSuggestion, action.mimeType)
            is Action.ShareDocument -> shareDocument(action.contentUri, action.mimeType)
        }
    }

    private fun pickDocument(fileNameSuggestion: String, mimeType: String) {
        val createDocumentIntent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
            type = mimeType
            putExtra(Intent.EXTRA_TITLE, fileNameSuggestion)
            addCategory(Intent.CATEGORY_OPENABLE)
        }
        startActivityForResult(createDocumentIntent, RESULT_PICK_DOCUMENT)
    }

    private fun shareDocument(contentUri: Uri, mimeType: String) {
        val shareIntent = Intent(Intent.ACTION_SEND).apply {
            type = mimeType
            putExtra(Intent.EXTRA_STREAM, contentUri)
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }

        startActivity(Intent.createChooser(shareIntent, null))
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        viewModel.saveInstanceState(outState)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == RESULT_PICK_DOCUMENT) {
            val contentUri = data?.data
            if (resultCode == Activity.RESULT_OK && contentUri != null) {
                viewModel.onDocumentPicked(contentUri)
            } else {
                viewModel.onDocumentPickCanceled()
            }
        }
    }

    companion object {
        private const val RESULT_PICK_DOCUMENT = Activity.RESULT_FIRST_USER
    }
}

private class ViewHolder(view: View) {
    val exportButton: View = view.findViewById(R.id.exportButton)
    val shareButton: View = view.findViewById(R.id.shareButton)
    val progressBar: View = view.findViewById(R.id.progressBar)
    val statusText: TextView = view.findViewById(R.id.statusText)
    val settingsExportList: RecyclerView = view.findViewById(R.id.settingsExportList)
}
