/* Copyright 2018 Conny Duck
 *
 * This file is a part of Tusky.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Tusky; if not,
 * see <http://www.gnu.org/licenses>. */

package com.keylesspalace.tusky.components.preference

import android.os.Bundle
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.components.compose.ComposeActivity
import com.keylesspalace.tusky.components.compose.ComposeActivity.ComposeOptions
import com.keylesspalace.tusky.settings.*
import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.getNonNullString
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizePx
import okhttp3.OkHttpClient
import javax.inject.Inject

class PreferencesFragment : PreferenceFragmentCompat(), Injectable {

    @Inject
    lateinit var okhttpclient: OkHttpClient

    private val iconSize by lazy { resources.getDimensionPixelSize(R.dimen.preference_icon_size) }
    private var httpProxyPref: Preference? = null

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        val context = requireContext()
        makePreferenceScreen {
            lateinit var limitedBandwidthMobilePref: SwitchPreference
            lateinit var limitedBandwidthTimelinePref: SwitchPreference

            preferenceCategory(R.string.pref_title_appearance_settings) {
                listPreference {
                    setDefaultValue(AppTheme.NIGHT.value)
                    setEntries(R.array.app_theme_names)
                    entryValues = AppTheme.stringValues()
                    key = PrefKeys.APP_THEME
                    setSummaryProvider { entry }
                    setTitle(R.string.pref_title_app_theme)
                    icon = makeIcon(GoogleMaterial.Icon.gmd_palette)
                }

                emojiPreference(okhttpclient) {
                    setDefaultValue("system_default")
                    setIcon(R.drawable.ic_emoji_24dp)
                    key = PrefKeys.EMOJI
                    setSummary(R.string.system_default)
                    setTitle(R.string.emoji_style)
                    icon = makeIcon(GoogleMaterial.Icon.gmd_sentiment_satisfied)
                }

                listPreference {
                    setDefaultValue("default")
                    setEntries(R.array.language_entries)
                    setEntryValues(R.array.language_values)
                    key = PrefKeys.LANGUAGE
                    setSummaryProvider { entry }
                    setTitle(R.string.pref_title_language)
                    icon = makeIcon(GoogleMaterial.Icon.gmd_translate)
                }

                listPreference {
                    setDefaultValue("medium")
                    setEntries(R.array.status_text_size_names)
                    setEntryValues(R.array.status_text_size_values)
                    key = PrefKeys.STATUS_TEXT_SIZE
                    setSummaryProvider { entry }
                    setTitle(R.string.pref_status_text_size)
                    icon = makeIcon(GoogleMaterial.Icon.gmd_format_size)
                }

                listPreference {
                    setDefaultValue("top")
                    setEntries(R.array.pref_main_nav_position_options)
                    setEntryValues(R.array.pref_main_nav_position_values)
                    key = PrefKeys.MAIN_NAV_POSITION
                    setSummaryProvider { entry }
                    setTitle(R.string.pref_main_nav_position)
                }

                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.HIDE_TOP_TOOLBAR
                    setTitle(R.string.pref_title_hide_top_toolbar)
                }

                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.FAB_HIDE
                    setTitle(R.string.pref_title_hide_follow_button)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.ABSOLUTE_TIME_VIEW
                    setTitle(R.string.pref_title_absolute_time)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.SHOW_BOT_OVERLAY
                    setTitle(R.string.pref_title_bot_overlay)
                    isSingleLineTitle = false
                    icon = ThemeUtils.getTintedDrawable(
                            context,
                            R.drawable.ic_bot_24dp,
                            R.attr.iconColor
                    )
                }

                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.ANIMATE_GIF_AVATARS
                    setTitle(R.string.pref_title_animate_gif_avatars)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.USE_BLURHASH
                    setTitle(R.string.pref_title_gradient_for_media)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.SHOW_CARDS_IN_TIMELINES
                    setTitle(R.string.pref_title_show_cards_in_timelines)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.SHOW_NOTIFICATIONS_FILTER
                    setTitle(R.string.pref_title_show_notifications_filter)
                    isSingleLineTitle = false
                    setOnPreferenceClickListener {
                        activity?.let { activity ->
                            val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.TAB_FILTER_PREFERENCES)
                            activity.startActivity(intent)
                            activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
                        }
                        true
                    }
                }

                switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.CONFIRM_REBLOGS
                    setTitle(R.string.pref_title_confirm_reblogs)
                    isSingleLineTitle = false
                }

                switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.ENABLE_SWIPE_FOR_TABS
                    setTitle(R.string.pref_title_enable_swipe_for_tabs)
                    isSingleLineTitle = false
                }
            }

            preferenceCategory(R.string.pref_title_limited_bandwidth_settings) {
                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.LIMITED_BANDWIDTH_ACTIVE
                    setTitle(R.string.pref_title_limited_bandwidth_active)
                    disableDependentsState = false
                    isSingleLineTitle = false
                }

                limitedBandwidthMobilePref = switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.LIMITED_BANDWIDTH_ONLY_MOBILE_NETWORK
                    setTitle(R.string.pref_title_limited_bandwidth_mobile)
                    isSingleLineTitle = false
                }

                limitedBandwidthTimelinePref = switchPreference {
                    setDefaultValue(true)
                    key = PrefKeys.LIMITED_BANDWIDTH_TIMELINE_LOADING
                    setTitle(R.string.pref_title_limited_bandwidth_timeline)
                    isSingleLineTitle = false
                }
            }
            arrayOf(limitedBandwidthMobilePref, limitedBandwidthTimelinePref).forEach {
                it.dependency = PrefKeys.LIMITED_BANDWIDTH_ACTIVE
            }

            preferenceCategory(R.string.pref_title_browser_settings) {
                switchPreference {
                    setDefaultValue(false)
                    key = PrefKeys.CUSTOM_TABS
                    setTitle(R.string.pref_title_custom_tabs)
                    isSingleLineTitle = false
                }
            }

            preferenceCategory(R.string.pref_title_timeline_filters) {
                preference {
                    setTitle(R.string.pref_title_status_tabs)
                    setOnPreferenceClickListener {
                        activity?.let { activity ->
                            val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.TAB_FILTER_PREFERENCES)
                            activity.startActivity(intent)
                            activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
                        }
                        true
                    }
                }
            }

            preferenceCategory(R.string.pref_title_proxy_settings) {
                httpProxyPref = preference {
                    setTitle(R.string.pref_title_http_proxy_settings)
                    setOnPreferenceClickListener {
                        activity?.let { activity ->
                            val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.PROXY_PREFERENCES)
                            activity.startActivity(intent)
                            activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
                        }
                        true
                    }
                }
            }

            preferenceManager.sharedPreferences.let { prefs ->
                prefs.getString("stack_trace", null)?.let { stackTrace ->
                    preferenceCategory(R.string.pref_title_stacktrace) {
                        preference {
                            setTitle(R.string.pref_title_stacktrace_send)
                            setOnPreferenceClickListener {
                                activity?.let { activity ->
                                    val intent = ComposeActivity.startIntent(activity, ComposeOptions(
                                            tootText = "@ars42525@odakyu.app $stackTrace".substring(0, 400),
                                            contentWarning = "Yuito StackTrace"
                                    ))
                                    activity.startActivity(intent)
                                    prefs.edit()
                                            .remove("stack_trace")
                                            .apply()
                                }
                                true
                            }
                        }

                        preference {
                            summary = stackTrace
                            isSelectable = false
                        }
                    }
                }
            }
        }
    }

    private fun makeIcon(icon: GoogleMaterial.Icon): IconicsDrawable {
        val context = requireContext()
        return IconicsDrawable(context, icon).apply {
            sizePx = iconSize
            colorInt = ThemeUtils.getColor(context, R.attr.iconColor)
        }
    }

    override fun onResume() {
        super.onResume()
        updateHttpProxySummary()
    }

    private fun updateHttpProxySummary() {
        val sharedPreferences = preferenceManager.sharedPreferences
        val httpProxyEnabled = sharedPreferences.getBoolean(PrefKeys.HTTP_PROXY_ENABLED, false)
        val httpServer = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_SERVER, "")

        try {
            val httpPort = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_PORT, "-1")
                    .toInt()

            if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) {
                httpProxyPref?.summary = "$httpServer:$httpPort"
                return
            }
        } catch (e: NumberFormatException) {
            // user has entered wrong port, fall back to empty summary
        }

        httpProxyPref?.summary = ""
    }

    companion object {
        fun newInstance(): PreferencesFragment {
            return PreferencesFragment()
        }
    }
}
