/**
 * ProjectLaogai
 *
 * Copyright 2019-2020  <seil0@mosad.xyz>
 *
 * 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.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 *
 */

package org.mosad.seil0.projectlaogai.uicomponents.dialogs

import android.content.Context
import android.os.Build
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.Spinner
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.WhichButton
import com.afollestad.materialdialogs.actions.getActionButton
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.bottomsheets.setPeekHeight
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import kotlinx.coroutines.runBlocking
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.preferences.Preferences
import org.mosad.seil0.projectlaogai.controller.cache.CacheController
import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.util.Course
import java.util.stream.Collectors

/**
 * This class creates a new AddLessonDialog.
 */
class AddSubjectDialog(val context: Context) {

    private val dialog = MaterialDialog(context, BottomSheet())

    private val spinnerCourses: Spinner
    private val spinnerSubjects: Spinner

    private val subjectsList = ArrayList<String>()
    private val courseNamesList = getCourseNames()

    var selectedCourse = ""
    var selectedSubject = ""

    init {
        dialog.title(R.string.add_lesson)
            .message(R.string.add_lesson_desc)
            .customView(R.layout.dialog_add_lesson)
            .positiveButton(R.string.add)
            .negativeButton(R.string.cancel)
            .setPeekHeight(900)

        spinnerCourses = dialog.getCustomView().findViewById(R.id.spinner_Courses)
        spinnerSubjects = dialog.getCustomView().findViewById(R.id.spinner_Lessons)

        // fix not working accent color
        dialog.getActionButton(WhichButton.POSITIVE).updateTextColor(Preferences.colorAccent)
        dialog.getActionButton(WhichButton.NEGATIVE).updateTextColor(Preferences.colorAccent)

        initSpinners()
    }

    fun positiveButton(func: AddSubjectDialog.() -> Unit): AddSubjectDialog = apply {
        dialog.positiveButton {
            func()
        }
    }

    fun show() {
        dialog.show()
    }

    fun show(func: AddSubjectDialog.() -> Unit): AddSubjectDialog = apply {
        func()
        this.show()
    }

    @Suppress("unused")
    fun dismiss() {
        dialog.dismiss()
    }

    private fun initSpinners() {
        setArrayAdapter(spinnerCourses, courseNamesList)
        val lessonsAdapter = setArrayAdapter(spinnerSubjects, subjectsList)

        // don't call onItemSelected() on spinnerCourses.onItemSelectedListener
        spinnerCourses.setSelection(0,false)
        spinnerCourses.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
                selectedCourse = parent.getItemAtPosition(pos).toString()

                // TODO show loading dialog while loading
                val lessonSubjects = runBlocking {
                    TCoRAPIController.getSubjectListAsync(parent.getItemAtPosition(pos).toString(), 0).await()
                }

                lessonsAdapter.clear()
                lessonsAdapter.addAll(lessonSubjects)
                lessonsAdapter.notifyDataSetChanged()
            }

            override fun onNothingSelected(parent: AdapterView<*>) {
                // Another interface callback
            }
        }

        // don't call onItemSelected() on spinnerCourses.onItemSelectedListener
        spinnerSubjects.setSelection(0,false)
        spinnerSubjects.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
                selectedSubject = parent.getItemAtPosition(pos).toString()
            }

            override fun onNothingSelected(parent: AdapterView<*>) {
                // Another interface callback
            }
        }
    }

    /**
     * set a new ArrayAdapter for a spinner with a list
     * @param spinner the spinner you wish to set the adapter for
     * @param list the list to set the adapter to
     */
    private fun setArrayAdapter(spinner: Spinner, list: List<String>): ArrayAdapter<String> {
        return ArrayAdapter(context, android.R.layout.simple_spinner_item, list)
            .also { adapter ->
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                spinner.adapter = adapter
            }
    }

    /**
     * get all course names from coursesList
     * @return a list, containing all course names
     */
    private fun getCourseNames(): List<String> {
        val coursesNameList: List<String>
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            coursesNameList = CacheController.coursesList.stream().map(Course::courseName).collect(
                Collectors.toList())
        } else {
            coursesNameList = ArrayList()
            CacheController.coursesList.forEach { course ->
                coursesNameList.add(course.courseName)
            }
        }

        return coursesNameList
    }
}