package net.pokeranalytics.android.ui.helpers

import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context
import android.content.DialogInterface
import android.text.format.DateFormat
import android.widget.DatePicker
import android.widget.TimePicker
import android.widget.Toast
import net.pokeranalytics.android.R
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentable
import java.util.*

class DateTimePickerManager : DatePickerDialog.OnDateSetListener,
	TimePickerDialog.OnTimeSetListener {

	private var context: Context? = null

	private lateinit var row: RowRepresentable
	private lateinit var delegate: RowRepresentableDelegate
	private lateinit var calendar: Calendar
	private var minimumDate: Date? = null
	private var onlyDate: Boolean = false
	private var onlyTime: Boolean = false
	private var isClearable: Boolean = true

	companion object {
		fun create(
			context: Context,
			row: RowRepresentable,
			delegate: RowRepresentableDelegate,
			date: Date?,
			minimumDate: Date? = null,
			onlyDate: Boolean? = false,
			onlyTime: Boolean? = false,
			isClearable: Boolean? = true
		): DateTimePickerManager {

			val calendar = Calendar.getInstance()
			calendar.time = date ?: Date()

			val dateTimePickerManager = DateTimePickerManager()
			dateTimePickerManager.context = context
			dateTimePickerManager.row = row
			dateTimePickerManager.delegate = delegate
			dateTimePickerManager.calendar = calendar
			dateTimePickerManager.minimumDate = minimumDate
			dateTimePickerManager.onlyDate = onlyDate ?: false
			dateTimePickerManager.onlyTime = onlyTime ?: false
			dateTimePickerManager.isClearable = isClearable ?: true

			if (dateTimePickerManager.onlyTime) {
				dateTimePickerManager.showTimePicker()
			} else {
				dateTimePickerManager.showDatePicker()
			}

			return dateTimePickerManager
		}
	}

	override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
		calendar.set(Calendar.YEAR, year)
		calendar.set(Calendar.MONTH, month)
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
		calendar.set(Calendar.SECOND, 0)
		calendar.set(Calendar.MILLISECOND, 0)
		if (!onlyDate) {
			showTimePicker()
		} else {
			delegate.onRowValueChanged(calendar.time, row)
		}
	}

	override fun onTimeSet(view: TimePicker?, hourOfDay: Int, minute: Int) {
		calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
		calendar.set(Calendar.MINUTE, minute)
		calendar.set(Calendar.SECOND, 0)
		calendar.set(Calendar.MILLISECOND, 0)

		if (minimumDate != null) {
			minimumDate?.let {
				if (calendar.time < it) {
					Toast.makeText(context, R.string.end_date_not_possible, Toast.LENGTH_LONG).show()
				} else {
					delegate.onRowValueChanged(calendar.time, row)
				}
			}
		} else {
			delegate.onRowValueChanged(calendar.time, row)
		}

	}

	/**
	 * Show the date picker
	 */
	private fun showDatePicker() {
		val year = calendar.get(Calendar.YEAR)
		val month = calendar.get(Calendar.MONTH)
		val day = calendar.get(Calendar.DAY_OF_MONTH)
		context?.let {
			val datePickerDialog = DatePickerDialog(it, this, year, month, day)
			minimumDate?.let {
				datePickerDialog.datePicker.minDate = it.time
			}

			if (isClearable) {
				datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ ->
					delegate.onRowValueChanged(null, row)
					dialog.dismiss()
				}
			}

			datePickerDialog.show()
		}
	}

	/**
	 * Show the time picker
	 */
	private fun showTimePicker() {
		val hour = calendar.get(Calendar.HOUR_OF_DAY)
		val minute = calendar.get(Calendar.MINUTE)
		context?.let {
			val timePickerDialog = TimePickerDialog(context, this, hour, minute, DateFormat.is24HourFormat(context))
			timePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, it.getString(R.string.clear)) { dialog, _ ->
				delegate.onRowValueChanged(null, row)
				dialog.dismiss()
			}
			timePickerDialog.show()
		}
	}

}