-- This file is part of thesixthroc's Pirate Ship softmod, licensed under GPLv3 and stored at https://github.com/ComfyFactory/ComfyFactorio and https://github.com/danielmartin0/ComfyFactorio-Pirates.

local Memory = require('maps.pirates.memory')
local Common = require('maps.pirates.common')
local Utils = require('maps.pirates.utils_local')
local Roles = require('maps.pirates.roles.roles')
local Crew = require('maps.pirates.crew')
local GuiCommon = require('maps.pirates.gui.common')
local CoreData = require('maps.pirates.coredata')
local Server = require('utils.server')
local Public = {}
-- local Surfaces = require('maps.pirates.surfaces.surfaces')
-- local SurfacesCommon = require('maps.pirates.surfaces.common')
-- local Hold = require('maps.pirates.surfaces.hold')
-- local Cabin = require 'maps.pirates.surfaces.cabin'
local Permissions = require('maps.pirates.permissions')

local window_name = 'crew'

local function get_selected_player_index(flow)
	if flow.members.body.members_listbox.selected_index ~= 0 then
		return tonumber(flow.members.body.members_listbox.get_item(flow.members.body.members_listbox.selected_index)[2])
	else
		return nil
	end
end

function Public.toggle_window(player)
	local memory = Memory.get_crew_memory()
	local get_global_memory = Memory.get_global_memory()
	local flow, flow2, flow3
	local window

	--*** OVERALL FLOW ***--
	if player.gui.screen[window_name .. '_piratewindow'] then
		player.gui.screen[window_name .. '_piratewindow'].destroy()
		return
	end

	if not Common.is_id_valid(memory.id) then
		return
	end

	window = GuiCommon.new_window(player, window_name)

	flow = window.add({
		type = 'scroll-pane',
		name = 'scroll_pane',
		direction = 'vertical',
		horizontal_scroll_policy = 'never',
		vertical_scroll_policy = 'auto-and-reserve-space',
	})
	flow.style.maximal_height = 500
	flow.style.bottom_margin = 10

	--*** PARAMETERS OF RUN ***--

	flow2 = flow.add({
		name = 'crew_capacity_and_difficulty',
		type = 'label',
	})
	flow2.style.left_margin = 5
	flow2.style.top_margin = 0
	flow2.style.bottom_margin = -3
	flow2.style.single_line = false
	flow2.style.maximal_width = 190
	flow2.style.font = 'default'

	flow2 = flow.add({
		name = 'crew_age',
		type = 'label',
	})
	flow2.style.left_margin = 5
	flow2.style.top_margin = -3
	flow2.style.bottom_margin = 0
	flow2.style.single_line = true
	flow2.style.maximal_width = 200
	flow2.style.font = 'default'

	-- flow2 = flow.add({
	-- 	name = 'crew_difficulty',
	-- 	type = 'label',
	-- })
	-- flow2.style.left_margin = 5
	-- flow2.style.top_margin = -3
	-- flow2.style.bottom_margin = 0
	-- flow2.style.single_line = false
	-- flow2.style.maximal_width = 190
	-- flow2.style.font = 'default'

	--*** MEMBERSHIP BUTTONS ***--

	flow2 = flow.add({
		name = 'membership_buttons',
		type = 'flow',
		direction = 'horizontal',
	})

	flow3 = flow2.add({
		name = 'leave_crew',
		type = 'button',
		caption = { 'pirates.gui_crew_window_buttons_quit_crew' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_buttons_quit_crew_tooltip' }

	--*** MEMBERS ***--

	flow2 = GuiCommon.flow_add_section(flow, 'members', { 'pirates.gui_crew_window_crewmembers' })

	flow3 = flow2.add({
		name = 'members_listbox',
		type = 'list-box',
	})
	flow3.style.margin = 5
	flow3.style.maximal_height = 350

	flow3 = flow2.add({
		name = 'officer_resign',
		type = 'button',
		caption = { 'pirates.gui_crew_window_crewmembers_resign_as_officer' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_crewmembers_resign_as_officer_tooltip' }

	--*** DIFFICULTY VOTE ***--

	flow2 = GuiCommon.flow_add_section(flow, 'difficulty_vote', { 'pirates.gui_crew_window_vote_for_difficulty' })

	for i, o in ipairs(CoreData.difficulty_options) do
		flow3 = flow2.add({
			name = 'difficulty_option_' .. i,
			type = 'button',
			caption = { '', '[item=', o.icon, '] ', o.text },
		})
		flow3.style.minimal_width = 95
		flow3.style.font = 'default-bold'
		flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	end

	--*** CAPTAIN's ACTIONS ***--

	flow2 = GuiCommon.flow_add_section(flow, 'captain', { 'pirates.gui_crew_window_captains_actions' })

	if get_global_memory.disband_crews then
		flow3 = flow2.add({
			name = 'capn_disband_crew',
			type = 'button',
			caption = { 'pirates.gui_crew_window_captains_actions_disband_crew' },
		})
		flow3.style.minimal_width = 95
		flow3.style.font = 'default-bold'
		flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
		flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_disband_crew_tooltip' }

		flow3 = flow2.add({
			name = 'capn_disband_are_you_sure',
			type = 'button',
			caption = { 'pirates.gui_crew_window_captains_actions_disband_crew_check' },
		})
		flow3.style.minimal_width = 95
		flow3.style.font = 'default-bold'
		flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
		flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_disband_crew_check_tooltip' }
	end

	flow3 = flow2.add({
		name = 'capn_renounce',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_renounce_title' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_renounce_title_tooltip' }

	flow3 = flow2.add({
		name = 'capn_pass',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_pass_title' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_pass_title_tooltip' }

	flow3 = flow2.add({
		name = 'capn_plank',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_plank' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_plank_tooltip' }

	flow3 = flow2.add({
		name = 'line',
		type = 'line',
	})
	flow3.style.width = 50
	flow3.style.left_margin = 20
	flow3.style.top_margin = 4
	flow3.style.bottom_margin = 4

	-- flow3 = flow2.add({
	-- 	name = 'capn_undock_normal',
	-- 	type = 'button',
	-- 	caption = 'Undock Boat',
	-- })
	-- flow3.style.minimal_width = 95
	-- flow3.style.font = 'default-bold'
	-- flow3.style.font_color = {r=0.10, g=0.10, b=0.10}

	flow3 = flow2.add({
		name = 'make_officer',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_make_officer' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_make_officer_tooltip' }

	flow3 = flow2.add({
		name = 'unmake_officer',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_unmake_officer' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_unmake_officer_tooltip' }

	flow3 = flow2.add({
		name = 'capn_summon_crew',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_summon_crew' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_summon_crew_tooltip' }

	flow3 = flow2.add({
		name = 'capn_requisition',
		type = 'button',
		caption = { 'pirates.gui_crew_window_captains_actions_tax' },
	})
	flow3.style.minimal_width = 95
	flow3.style.font = 'default-bold'
	flow3.style.font_color = { r = 0.10, g = 0.10, b = 0.10 }
	flow3.tooltip = { 'pirates.gui_crew_window_captains_actions_tax_tooltip', tostring(Common.coin_tax_percentage) }

	flow2 = flow.add({
		name = 'undock_tip',
		type = 'label',
	})
	flow2.style.left_margin = 5
	flow2.style.top_margin = -8
	flow2.style.bottom_margin = 7
	flow2.style.single_line = false
	flow2.style.maximal_width = 190
	flow2.style.font = 'default'
	flow2.caption = { 'pirates.gui_crew_window_captains_actions_undock_tip' }

	GuiCommon.flow_add_close_button(window, window_name .. '_piratebutton')
end

-- function Public.regular_update(player)

-- end

function Public.full_update(player)
	if Public.regular_update then
		Public.regular_update(player)
	end

	if not player.gui.screen[window_name .. '_piratewindow'] then
		return
	end
	local window = player.gui.screen[window_name .. '_piratewindow']
	local flow = window.scroll_pane

	local memory = Memory.get_crew_memory()
	local playercrew_status = GuiCommon.crew_overall_state_bools(player.index)

	--*** WHAT TO SHOW ***--

	flow.difficulty_vote.visible = memory.overworldx and memory.overworldx == 0

	flow.members.body.officer_resign.visible = Common.is_officer(player.index)

	local selected_player_index = get_selected_player_index(flow)
	local other_player_selected = flow.members.body.members_listbox.selected_index ~= 0
		and selected_player_index ~= player.index

	flow.captain.visible = Common.is_captain(player)
	flow.undock_tip.visible = Common.is_captain(player)

	flow.captain.body.capn_pass.visible = other_player_selected
	flow.captain.body.capn_plank.visible = other_player_selected

	flow.captain.body.make_officer.visible = other_player_selected and (not Common.is_officer(selected_player_index))

	flow.captain.body.unmake_officer.visible = other_player_selected and Common.is_officer(selected_player_index)

	-- flow.captain.body.capn_undock_normal.visible = boat and boat.state and ((boat.state == boats.enum_state.LANDED) or (boat.state == Boats.enum_state.APPROACHING) or (boat.state == Boats.enum_state.DOCKED))

	flow.captain.body.capn_summon_crew.visible = false
	flow.captain.body.capn_requisition.visible = true
	-- flow.captain.body.capn_summon_crew.visible = boat and boat.state and (boat.state == Boats.enum_state.RETREATING or boat.state == Boats.enum_state.LEAVING_DOCK)

	local get_global_memory = Memory.get_global_memory()

	if get_global_memory.disband_crews then
		flow.captain.body.capn_disband_are_you_sure.visible = memory.disband_are_you_sure_ticks
			and memory.disband_are_you_sure_ticks[player.index]
			and memory.disband_are_you_sure_ticks[player.index] > game.tick - 60 * 2
		flow.captain.body.capn_disband_crew.visible = not flow.captain.body.capn_disband_are_you_sure.visible
	end

	flow.members.visible = true
	-- flow.crew_age.visible = true
	-- -- flow.crew_age.visible = memory.mode and memory.mode == 'speedrun'
	-- flow.crew_difficulty.visible = true

	flow.membership_buttons.leave_crew.visible = playercrew_status.adventuring

	--== UPDATE CONTENT ==--

	if Common.is_id_valid(memory.id) then
		window.caption = memory.name

		flow.crew_age.caption = { 'pirates.gui_crew_window_crew_age', Utils.time_mediumform((memory.age or 0) / 60) }
		flow.crew_capacity_and_difficulty.caption = {
			'pirates.gui_crew_window_crew_capacity_and_difficulty',
			CoreData.difficulty_options[memory.difficulty_option].text,
			CoreData.capacity_options[memory.capacity_option].text3,
		}
	end

	if flow.members.visible then
		local wrappedcrew = {}
		for _, index in pairs(memory.crewplayerindices) do
			local player2 = game.players[index]
			local tag_text = Roles.tag_text(player2)

			wrappedcrew[#wrappedcrew + 1] = {
				'pirates.crewmember_displayform',
				index,
				player2.color.r,
				player2.color.g,
				player2.color.b,
				player2.name,
				tag_text,
			}
		end
		GuiCommon.update_listbox(flow.members.body.members_listbox, wrappedcrew)

		flow.members.header.caption = { 'pirates.gui_crew_window_crew_count', tostring(#memory.crewplayerindices or 0) }
	end

	-- if flow.captain.body.capn_undock_normal.visible then
	-- 	flow.captain.body.capn_undock_normal.enabled = ((boat.state == Boats.enum_state.LANDED) and Common.query_can_pay_cost_to_leave()) or (boat.state == Boats.enum_state.DOCKED)
	-- end
end

function Public.click(event)
	-- This is only needed since we call click on every single GUI element and if element gets destroyed, it's no good (these checks wouldn't be needed (I think) if GUI was purely event driven)
	if not event.element then
		return
	end
	if not event.element.valid then
		return
	end

	local player = game.players[event.element.player_index]

	local eventname = event.element.name

	if not player.gui.screen[window_name .. '_piratewindow'] then
		return
	end
	local window = player.gui.screen[window_name .. '_piratewindow']
	local flow = window.scroll_pane

	local memory = Memory.get_crew_memory()

	if eventname == 'leave_crew' then
		Crew.leave_crew(player, true)
		return
	end

	-- if eventname == 'promote_officer' then
	-- 	Roles.promote_to_officer(player)
	-- 	return
	-- end

	-- if eventname == 'demote_officer' then
	-- 	Roles.demote_to_officer(player)
	-- 	return
	-- end

	if string.sub(eventname, 1, 18) and string.sub(eventname, 1, 18) == 'difficulty_option_' then
		Crew.difficulty_vote(player.index, tonumber(string.sub(eventname, 19, -1)))
		return
	end

	if eventname == 'capn_summon_crew' then
		--double check:
		if Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN then
			Crew.summon_crew()
		end
		return
	end

	if eventname == 'capn_requisition' then
		--double check:
		if Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN then
			Roles.captain_tax(memory.playerindex_captain)
		end
		return
	end

	if eventname == 'capn_renounce' then
		Roles.renounce_captainhood(player)
		return
	end

	if eventname == 'officer_resign' then
		Roles.resign_as_officer(player)
		return
	end

	if eventname == 'capn_disband_crew' then
		--double check:
		if Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN then
			if not memory.disband_are_you_sure_ticks then
				memory.disband_are_you_sure_ticks = {}
			end
			memory.disband_are_you_sure_ticks[player.index] = game.tick
		end
		return
	end

	if eventname == 'capn_disband_are_you_sure' then
		--double check:
		if Permissions.player_privilege_level(player) >= Permissions.privilege_levels.CAPTAIN then
			local force = memory.force
			if force and force.valid then
				local message = {
					'pirates.crew_disbanded',
					player.name,
					memory.name,
					Utils.time_longform((memory.age_since_first_island or 0) / 60),
				}
				Common.notify_game(message)
				Server.to_discord_embed_raw(
					{ '', CoreData.comfy_emojis.trashbin .. '[' .. memory.name .. '] ', message },
					true
				)
			end
			Crew.disband_crew(true)
		end
		return
	end

	if eventname == 'capn_pass' then
		local other_id = get_selected_player_index(flow)
		Roles.pass_captainhood(player, game.players[other_id])
		return
	end

	if eventname == 'make_officer' then
		local other_id = get_selected_player_index(flow)
		Roles.make_officer(player, game.players[other_id])
		return
	end

	if eventname == 'unmake_officer' then
		local other_id = get_selected_player_index(flow)
		Roles.unmake_officer(player, game.players[other_id])
		return
	end

	if eventname == 'capn_plank' then
		local other_id = get_selected_player_index(flow)

		Crew.plank(player, game.players[other_id])
		return
	end
end

return Public
