extends VBoxContainer

enum Types {
	Creation,
	Edit,
	Info
}

@export var type : Types:
	set(new_type):
		type = new_type

@onready var _main: Main = get_tree().get_current_scene()
@onready var _title := $TopBar/Label
@onready var _back_button := $BottomBar/Left/BackButton
@onready var _apply_button := $BottomBar/Right/ApplyButton
@onready var _delete_button := $BottomBar/Left/DeleteButton
@onready var _error_box := $ErrorBox

@onready var _title_field := $TitleField
@onready var _date_field := $DateField
@onready var _start_time_field := $StartTimeField
@onready var _finish_time_field := $FinishTimeField
@onready var _creator_field := $CreatorField
@onready var _room_field := $RoomField
@onready var _description_field := $DescriptionField

func _process(delta):
	_process_fonts()
	_process_separation()

func _process_fonts():
	_process_font_size(_title, 35)
	_process_font_size(_back_button, 35)
	_process_font_size(_apply_button, 35)
	_process_font_size(_delete_button, 35)
	_process_font_size(_error_box, 35)

func _process_font_size(obj, k):
	var font_size = obj.get_theme_default_font_size()
	var new_font_size = get_viewport_rect().size.y/k
	if font_size != new_font_size:
		obj.add_theme_font_size_override("font_size", new_font_size)

func _process_separation():
	var separation = get_theme_constant("separation")
	var new_separation = get_viewport_rect().size.y/28
	if separation != new_separation:
		add_theme_constant_override("separation", new_separation)

func _ready():
	initialize_signals()
	_error_box.set_message(String())

func initialize_signals():
	_back_button.pressed.connect(_on_back_button_pressed)
	_apply_button.pressed.connect(_on_apply_button_pressed)

	if type == Types.Edit:
		_delete_button.pressed.connect(_on_delete_button_pressed)

func _on_back_button_pressed():
	_main.load_page(Main.Pages.Board)

func _on_apply_button_pressed():
	match type:
		Types.Creation:
			_create_reservation()
		Types.Edit:
			_update_reservation()

func _on_delete_button_pressed():
	_delete_reservation()

func _load_info():
	var reservation_repo = _main.get_reservation_repo()
	var reservation_id = reservation_repo.get_selected_reservation_id()
	var reservation = await reservation_repo.get_reservation(reservation_id)

	var room_repo = _main.get_room_repo()
	var room = await room_repo.get_room(reservation.room_id)
	var room_title = room.title if room != null else ""

	_title_field.set_value(reservation.title)
	_start_time_field.set_value(reservation.start_time)
	_finish_time_field.set_value(reservation.finish_time)
	_room_field.set_value({"title": room_title, "id": reservation.room_id})
	_date_field.set_value(reservation.date)

func _load_room():
	if _room_field.get_value().title == "":
		var room = _main.get_selected_room()
		_room_field.set_value({"title": room.title, "id": room.id})

func _load_date():
	if _date_field.get_value() == "":
		_date_field.set_value(_main.get_selected_date())

func _get_current_room_id():
	var room_repo = _main.get_room_repo()
	var room = room_repo.get_selected_room()
	return room.id if room != null else null

func _create_reservation():
	if not await _fields_are_correct():
		return

	var dto = CreateReservationDTO.new()
	dto.title = _title_field.get_value()
	dto.date = _date_field.get_value()
	dto.start_time = _start_time_field.get_value()
	dto.finish_time = _finish_time_field.get_value()
	dto.creator = _creator_field.get_value()
	dto.room_id = _room_field.get_value().id
	dto.description = _description_field.get_value()
	dto.color = randi_range(1, 3)

	var reservation_repo = _main.get_reservation_repo()
	reservation_repo.create_reservation(dto)

	dto.queue_free()

	_main.load_page(Main.Pages.Board, true)
	clean()

func _update_reservation():
	if not await _fields_are_correct():
		return

	var dto = UpdateReservationDTO.new()
	dto.title = _title_field.get_value()
	dto.date = _date_field.get_value()
	dto.start_time = _start_time_field.get_value()
	dto.finish_time = _finish_time_field.get_value()
	dto.creator = _creator_field.get_value()
	dto.room_id = _room_field.get_value().id
	dto.description = _description_field.get_value()
	dto.color = randi_range(1, 3)

	var reservation_repo = _main.get_reservation_repo()
	var reservation_id = reservation_repo.get_selected_reservation_id()
	reservation_repo.change_reservation(reservation_id, dto)
	reservation_repo.set_selected_reservation_id(null)

	dto.queue_free()

	_main.load_page(Main.Pages.Board, true)
	clean()

func _delete_reservation():
	var repo = _main.get_reservation_repo()
	var reservation_id = repo.get_selected_reservation_id()
	repo.cancel_reservation(reservation_id)

	_main.load_page(Main.Pages.Board, true)
	clean()

func _fields_are_correct():
	var successful := true

	#if len(_title_field.get_value()) < 1:
	#	print("The title is not entered.")
	#	_error_box.set_message("Не введено название встречи")
	#	successful = false

	if not await _time_is_correct():
		successful = false

	return successful

func _time_is_correct():
	var start_time = _start_time_field.get_value()
	var finish_time = _finish_time_field.get_value()

	var time_is_not_entered = \
		start_time["hours"] == 0 and start_time["minutes"] == 0 or \
		finish_time["hours"] == 0 and finish_time["minutes"] == 0

	if time_is_not_entered:
		_error_box.set_message("Введите время начала и окончания встречи")
		return false

	var start_time_is_after_finish_time = \
		start_time["hours"] > finish_time["hours"] or \
		(start_time["hours"] == finish_time["hours"] and \
		start_time["minutes"] >= finish_time["minutes"])

	if start_time_is_after_finish_time:
		print("Start time should not be more than or equal to finish time.")
		_error_box.set_message("Время начала не может быть больше времени окончания")
		return false

	var start_time_in_minutes = start_time.hours*60 + start_time.minutes
	var finish_time_in_minutes = finish_time.hours*60 + finish_time.minutes
	var service = _main.get_reservation_service()
	var selected_room_id = _room_field.get_value().id
	var selected_date = _date_field.get_value()
	var is_busy = await service.is_time_busy(start_time_in_minutes, finish_time_in_minutes, \
		selected_room_id, selected_date)

	if is_busy:
		print("The selected time slot is busy.")
		_error_box.set_message("Выбранный временной интервал занят")
		return false

	return true

func set_start_time(value):
	_start_time_field.set_value(value)

func update():
	_ready()

	if type == Types.Edit:
		_load_info()
	else:
		_load_room()
		_load_date()

func clean():
	_title_field.clean()
	_start_time_field.clean()
	_finish_time_field.clean()
	_date_field.clean()
	_room_field.clean()
