package app.furmeet.events.brasilfurfest.schedule

import android.annotation.SuppressLint
import android.content.Intent
import android.content.res.Resources
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.CalendarContract
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
import app.furmeet.events.brasilfurfest.CountdownActivity
import com.adlerosn.brasilfurfest.R
import app.furmeet.events.brasilfurfest.SplashActivity
import app.furmeet.events.brasilfurfest.TranslatableAppCompatActivity
import app.furmeet.events.brasilfurfest.helper.*
import app.furmeet.events.brasilfurfest.helper.observables.Observable
import app.furmeet.events.brasilfurfest.helper.observables.Observer
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.convention.FilterableNamedColoredAttribute
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.managed.Actions
import app.furmeet.events.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConFavorite
import app.furmeet.events.brasilfurfest.schedule.managers.RemoteAssets
import app.furmeet.events.brasilfurfest.schedule.managers.ScheduleManagerGetter
import com.google.android.material.snackbar.Snackbar
import com.google.gson.GsonBuilder
import kotlinx.android.synthetic.main.activity_event.*
import kotlinx.android.synthetic.main.activity_event_content.*
import kotlinx.android.synthetic.main.activity_event_content_keypair.view.*
import kotlinx.android.synthetic.main.activity_event_share.view.*
import org.jetbrains.anko.doAsync
import kotlin.math.roundToInt


class EventActivity : TranslatableAppCompatActivity() {

    private var fromNotification = false


    override fun onCreate(savedInstanceState: Bundle?) {
        ActivitiesForFragments[this.javaClass.simpleName] = this
        super.onCreate(savedInstanceState)
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
        window.statusBarColor = Color.TRANSPARENT
        setContentView(R.layout.activity_event)
        resourcesAliased = this.resources
        setSupportActionBar(toolbar)

        toolbar_layout.setCollapsedTitleTextAppearance(R.style.CollapsedAppBar)
        toolbar_layout.setExpandedTitleTextAppearance(R.style.ExpandedAppBar)

        val scheduleManager = ScheduleManagerGetter[this]
        val favorite = intent.getSerializableExtra("favorite") as AttendeeConFavorite
        val offerStar = intent.getBooleanExtra("offerStar", false)
        fromNotification = intent.getBooleanExtra("fromNotification", false)
        val event = favorite.findInConvention(scheduleManager.convention)
        toolbar_layout.title = event?.titles?.solved ?: favorite.getString()
        doAsync {
            uiThreadWithLogger {
                event?.assetImage?.solved?.fromCacheManagerToImageOf(app_bar_image)
                        ?: scheduleManager.convention.imageDefaultEvent?.solved?.fromCacheManagerToImageOf(app_bar_image)
            }
        }

        val timerClickListener = View.OnClickListener { _ ->
            Intent(this, CountdownActivity::class.java).let {
                it.putExtra("label", favorite.getString())
                it.putExtra("counter", favorite.timeRange.start.timeInMillis)
                it.putExtra("finishesAt", favorite.timeRange.finish.timeInMillis)
                startActivity(it)
            }
        }

        keypairs.removeAllViews()
        inflateKeyPair(
                R.string.schedule_event_key_activity.getString(),
                favorite.getString(),
                keypairs
        )
        if (event?.subtitles?.solved?.isNotEmpty() == true)
            inflateKeyPair(
                    R.string.schedule_event_key_detail.getString(),
                    event.subtitles.solved!!,
                    keypairs
            )
        val whenButton = inflateKeyPair(
                R.string.schedule_event_key_when.getString(),
                R.string.schedule_event_key_when_formatted.getString().format(
                        favorite.timeRange.start.timeInMillis.formatAsLongDayOfWeekWithNumber(),
                        favorite.timeRange.start.timeInMillis.formatAsHoursAndMinutes(),
                        favorite.timeRange.finish.timeInMillis.formatAsHoursAndMinutes()
                ).capitalize(),
                keypairs
        ).apply {
            touchableIndicator.visibility = View.VISIBLE
            setOnClickListener(timerClickListener)
        }
        if (favorite.isSecondaryStringPlace) {
            inflateKeyPair(
                    R.string.schedule_event_key_place.getString(),
                    favorite.getSecondaryString(),
                    keypairs
            )
        }
        if (event != null) {
            if (event.places.isNotEmpty())
                inflateKeyPair(
                        event.places.size.pluralize(R.string.schedule_event_key_place, R.string.schedule_event_key_places).getString(),
                        formatSpannableWithColor(event.places),
                        keypairs
                )
            if (event.language != null)
                inflateKeyPair(
                        R.string.schedule_event_key_language.getString(),
                        event.language.language.getString(),
                        keypairs
                )
            event.descriptions.solved?.let {
                if (it.isNotEmpty())
                    inflateKeyPair(
                            R.string.schedule_event_key_description.getString(),
                            it,
                            keypairs
                    )
            }
            if (event.tags.isNotEmpty())
                inflateKeyPair(
                        event.tags.size.pluralize(R.string.schedule_event_key_category, R.string.schedule_event_key_categories).getString(),
                        formatSpannableWithColor(event.tags),
                        keypairs
                )
            if (event.conbookPages.isNotEmpty() && !(event.conbookPages.size == 1 && event.conbookPages[0] == 0))
                inflateKeyPair(
                        event.conbookPages.size.pluralize(R.string.schedule_event_key_on_conbooks_page, R.string.schedule_event_key_on_conbooks_pages).getString(),
                        event.conbookPages.map { it.toString() }.textuallyJoined,
                        keypairs
                )
            if (event.conbookId.isNotEmpty() && event.conbookId != "0")
                inflateKeyPair(
                        R.string.schedule_event_key_identified_on_conbook_as.getString(),
                        event.conbookId,
                        keypairs
                )
            if (event.attendableBy.isNotEmpty())
                inflateKeyPair(
                        event.attendableBy.size.pluralize(R.string.schedule_event_key_elegible_registration, R.string.schedule_event_key_elegible_registrations).getString(),
                        event.attendableBy.map { it.names.solved!! }.textuallyJoined,
                        keypairs
                )
            @SuppressLint("RestrictedApi")
            if (event.hiddenFromTimeTable or scheduleManager.canAttend(event).not()) {
                fab.visibility = View.GONE
                fabCalendar.visibility = View.GONE
                fabShare.visibility = View.GONE
            }
        }
        @SuppressLint("RestrictedApi")
        if (!offerStar) {
            fab.visibility = View.GONE
            fabCalendar.visibility = View.GONE
            fabShare.visibility = View.GONE
        }


        fab.setOnClickListener { _ ->
            R.drawable.ic_star_half_white_24dp.asImageOf(fab)
            if (favorite in scheduleManager.attendeeFavorites)
                scheduleManager.attendeeFavorites.remove(favorite)
            else
                scheduleManager.attendeeFavorites.add(favorite)
        }
        fab.isLongClickable = true
        fab.setOnLongClickListener {
            Snackbar.make(it.rootView, R.string.add_or_remove_favorite, Snackbar.LENGTH_LONG).apply {
                setActionTextColor(this@EventActivity.getColorCompat(R.color.colorBase20))
                view.setBackgroundColor(this@EventActivity.getColorCompat(R.color.colorBase03))
                view.let {
                    it.setPadding(
                            it.paddingLeft,
                            it.paddingTop,
                            it.paddingRight,
                            it.paddingBottom + (48 * Resources.getSystem().displayMetrics.density).toInt()
                    )
                    show()
                }
            }
            true
        }
        fabCalendar.setOnClickListener { _ ->
            val intent = Intent(Intent.ACTION_EDIT)
            intent.type = "vnd.android.cursor.item/event"
            intent.putExtra(CalendarContract.Events.TITLE, favorite.getString())
            if (event != null) {
                intent.putExtra(CalendarContract.Events.EVENT_LOCATION, event.places.map {
                    it.names.solved ?: ""
                }.textuallyJoined)
                intent.putExtra(CalendarContract.Events.DESCRIPTION, event.descriptions.solved
                        ?: "")
            } else if (favorite.kind == Actions.Intention.ROOMPARTY) {
                intent.putExtra(CalendarContract.Events.EVENT_LOCATION, favorite.getSecondaryString())
            }
            intent.putExtra(
                    CalendarContract.EXTRA_EVENT_BEGIN_TIME,
                    favorite.timeRange.start.timeInMillis
            )
            intent.putExtra(
                    CalendarContract.EXTRA_EVENT_END_TIME,
                    favorite.timeRange.finish.timeInMillis
            )
            startActivity(intent)
        }
        fabShare.isLongClickable = true
        fabShare.setOnClickListener {
            val gson = GsonBuilder().create()
            val link = RemoteAssets.prefixRoomParty + Uri.encode(gson.toJson(favorite))
            val dialog = AlertDialog.Builder(this).create()
            dialog.setTitle(R.string.event_share_question.getString())
            val view = layoutInflater.inflate(R.layout.activity_event_share)
            view.btnLink.setOnClickListener {
                toClipboard(link, "Room party link", true)
                startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND).apply { type = "text/plain"; putExtra(Intent.EXTRA_TEXT, link) }, null))
                dialog.dismiss()
            }
            view.btnQr.setOnClickListener {
                startActivity(Intent(this, QRCodeViewerActivity::class.java).apply { putExtra("data", link) })
                dialog.dismiss()
            }
            dialog.setView(view)
            dialog.show()
        }
        fabShare.setOnLongClickListener {
            Snackbar.make(it.rootView, R.string.shows_you_how_you_can_share_this, Snackbar.LENGTH_LONG).apply {
                setActionTextColor(this@EventActivity.getColorCompat(R.color.colorBase20))
                view.setBackgroundColor(this@EventActivity.getColorCompat(R.color.colorBase03))
                view.let {
                    it.setPadding(
                            it.paddingLeft,
                            it.paddingTop,
                            it.paddingRight,
                            it.paddingBottom + 48.asDpToPx.roundToInt()
                    )
                    show()
                }
            }
            true
        }
        if (favorite.isShareable.not())
            @SuppressLint("RestrictedApi")
            fabShare.visibility = View.INVISIBLE
        fabCalendar.isLongClickable = true
        fabCalendar.setOnLongClickListener {
            Snackbar.make(it.rootView, R.string.adds_to_your_agenda_app, Snackbar.LENGTH_LONG).apply {
                setActionTextColor(this@EventActivity.getColorCompat(R.color.colorBase20))
                view.setBackgroundColor(this@EventActivity.getColorCompat(R.color.colorBase03))
                view.let {
                    it.setPadding(
                            it.paddingLeft,
                            it.paddingTop,
                            it.paddingRight,
                            it.paddingBottom + 48.asDpToPx.roundToInt()
                    )
                    show()
                }
            }
            true
        }
        whenButton.isLongClickable = true
        whenButton.setOnLongClickListener {
            Snackbar.make(it.rootView, R.string.opens_timer, Snackbar.LENGTH_LONG).apply {
                setActionTextColor(this@EventActivity.getColorCompat(R.color.colorBase20))
                view.setBackgroundColor(this@EventActivity.getColorCompat(R.color.colorBase03))
                view.let {
                    it.setPadding(
                            it.paddingLeft,
                            it.paddingTop,
                            it.paddingRight,
                            it.paddingBottom + 48.asDpToPx.roundToInt()
                    )
                    show()
                }
            }
            true
        }
        scheduleManager.addObserver(Observer { _: Observable<Any?>, _: Any? ->
            if (favorite in scheduleManager.attendeeFavorites)
                R.drawable.ic_star_white_24dp.asImageOf(fab)
            else
                R.drawable.ic_star_border_white_24dp.asImageOf(fab)
        }.apply { this.update(Observable(), null) })
    }

    private fun inflateKeyPair(key: String, value: CharSequence, into: ViewGroup? = null) =
            layoutInflater.inflate(R.layout.activity_event_content_keypair).apply {
                textKey.text = key
                textValue.text = value
                into?.addView(this)
                touchableIndicator.visibility = View.GONE
            }

    override fun onBackPressed() {
        if (!fromNotification)
            super.onBackPressed()
        else {
            val intent = Intent(this, SplashActivity::class.java)
            intent.flags =
                    Intent.FLAG_ACTIVITY_NEW_TASK or
                            Intent.FLAG_ACTIVITY_TASK_ON_HOME
            intent.putExtra("fastStart", true)
            this.startActivity(intent)
            this.finish()
        }
    }

    private fun formatSpannableWithColor(collection: List<FilterableNamedColoredAttribute>): Spannable =
            collection.map {
                SpannableString(
                        it.names.solved!!,
                        RoundedBackgroundAndForegroundColorsSpan(
                                it.color,
                                it.color.decideBestForegroundColor(
                                        applicationContext.getColorCompat(R.color.colorBase03),
                                        applicationContext.getColorCompat(R.color.colorBase21)
                                )
                        )
                )
            }.textuallyJoined.let { SpannableStringBuilder().append(it).append(" ") }
}
