<script lang="ts">
	import DropDown from '$lib/components_custom/DropDown.svelte';
	import DropDownElement from '$lib/components_custom/DropDownElement.svelte';
	import { MACHINE_GROUP_ID, apiBaseUrl } from '$lib/components_custom/consts';
	import { LeanChellarisDataStore } from '$lib/stores/ChellarisData';
	import type { ChellarisEmpire, ChellarisGameGroup } from '$lib/types/chellaris';
	import type { EmpireEthic } from '$lib/types/stellaris';
	import { createEventDispatcher } from 'svelte';

	export let empire: ChellarisEmpire;
	export let groups: { [key: number]: ChellarisGameGroup } = {};
	export let newEmpire: boolean = false;
	export let auth: string;

	let newEmpirePrepared = false;
	let newEmpireError: [boolean, string] = [false, ''];

	let oldEmpireData = { ...empire };
	let ethicsBuffer: { [key: number]: EmpireEthic } = {...empire.ethics};

	const dispatch = createEventDispatcher();

	let ethicsIdArray: [boolean, boolean][] = [];
	Object.values($LeanChellarisDataStore.ethics).map((ethic) => (ethicsIdArray[ethic.id] = [false, false]));
	Object.values(empire ? ethicsBuffer : []).map((ethic) => (ethicsIdArray[ethic.ethic_id] = [true, false]));
	Object.values(empire ? ethicsBuffer : [])
		.filter((ethic) => ethic.fanatic)
		.map((entry) => (ethicsIdArray[entry.ethic_id][1] = true));

	const updateRegularEthicsSelection = () => {
		ethicsIdArray.forEach((selected, idx) => {
			if (selected[0]) {
				ethicsBuffer[idx] = {
					ethic_id: idx,
					fanatic: selected[1]
				};
			} else {
				ethicsIdArray[idx][1] = false;
				delete ethicsBuffer[idx];
			}
		});
	};

	const updateFanaticEthicsSelection = () => {
		ethicsIdArray.forEach((selected, idx) => {
			if (selected[0] || selected[1]) {
				ethicsBuffer[idx] = {
					ethic_id: idx,
					fanatic: selected[1]
				};
				ethicsIdArray[idx][0] = true;
			} else {
				delete ethicsBuffer[idx];
			}
		});
	};

	const updateEmpire = () => {
		// Generate Diff:
		let diffEmpire: any = {};

		if (oldEmpireData.name != empire.name) {
			diffEmpire.empire_name = empire.name;
		}

		if (oldEmpireData.discord_user != empire.discord_user) {
			diffEmpire.discord_user = empire.discord_user;
		}

		if (oldEmpireData.group != empire.group) {
			diffEmpire.group_id = empire.group;
		}

		if (oldEmpireData.gestalt != empire.gestalt) {
			diffEmpire.gestalt = empire.gestalt;
		}

		if (JSON.stringify(oldEmpireData.ethics) != JSON.stringify(ethicsBuffer)) {
			diffEmpire.ethics = Object.values(ethicsBuffer);
		}

		if (oldEmpireData.portrait_id != empire.portrait_id) {
			diffEmpire.portrait_id = empire.portrait_id;
		}

		if (oldEmpireData.portrait_group_id != empire.portrait_group_id) {
			diffEmpire.portrait_group_id = empire.portrait_group_id;
		}

		if (Object.values(diffEmpire).length != 0) {
			diffEmpire.empire_id = empire.id;
			diffEmpire.game_id = empire.game;
			fetch(apiBaseUrl + '/v3/empire', {
				method: 'PUT',
				headers: {
					'Content-Type': 'application/json',
					'x-api-key': auth
				},
				body: JSON.stringify(diffEmpire)
			}).then((response) => {
				response.json().then((result) => {
					empire = result;
					oldEmpireData = { ...empire };
					dispatch('updated');
				});
			});
		}
	};

	const createEmpire = () => {
		let validData = true;
		let errorMessages = [];

		if (empire.name == '') {
			// Mark Name Input Window Red
			validData = false;
			errorMessages.push('Empire Name is invalid!');
		}

		if (Object.values(ethicsBuffer).length == 0) {
			// Mark Ethics Input Window Red
			validData = false;
			errorMessages.push('No Ethics Selected!');
		}

		if (validData) {
			let newEmpireData: any = {};
			newEmpireData.group_id = empire.group;
			newEmpireData.game_id = empire.game;
			newEmpireData.empire_name = empire.name;
			newEmpireData.discord_user = empire.discord_user;
			newEmpireData.gestalt = empire.gestalt;
			newEmpireData.portrait_id = empire.portrait_id;
			newEmpireData.portrait_group_id = empire.portrait_group_id;
			newEmpireData.ethics = Object.values(ethicsBuffer);
			fetch(apiBaseUrl + '/v3/empire', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					'x-api-key': auth
				},
				body: JSON.stringify(newEmpireData)
			}).then((response) => {
				response.json().then((result) => {
					empire = result;
					oldEmpireData = { ...empire };
					dispatch('created', {
						new_id: empire.id
					});
				});
			});
		} else {
			newEmpireError[0] = true;
			newEmpireError[1] = errorMessages.join(' | ');
		}
	};

	// Dropdown UUID to make the Click Event work properly
	const groupDropdownId = crypto.randomUUID();
	const speciesDropdownId = crypto.randomUUID();
	const phenotypeDropdownId = crypto.randomUUID();
	const ethicsDropdownId = crypto.randomUUID();

	$: {
		if (empire.portrait_group_id == MACHINE_GROUP_ID) {
			empire.machine = true;
		} else {
			empire.machine = false;
		}
	}

	$: {
		if (newEmpire && !newEmpirePrepared) {
			empire.group = Object.values(groups)[0].id;
			newEmpirePrepared = true;
		}

		if (!newEmpire) {
			newEmpirePrepared = false;
			newEmpireError = [false, ''];
		}
	}
</script>

<div>
	{#if newEmpire && newEmpirePrepared}
	<!-- <div>
		ID: {empire.id}
	</div>
	<div>
		Game ID: {empire.game}
	</div> -->
	<DropDown dropdownTitle={'Group*: ' + groups[empire.group].name} dropdownId={groupDropdownId}>
		{#each Object.values(groups) as group}
			{#if group}
				<DropDownElement dropdownId={groupDropdownId}>
					<input id={'checkbox' + group.id} data-dropdown={groupDropdownId} type="radio" bind:group={empire.group} value={group.id} />
					<label for={'checkbox' + group.id} data-dropdown={groupDropdownId}>{group.name}</label>
				</DropDownElement>
			{/if}
		{/each}
	</DropDown>
	<br />
	<label for="check-gestalt">Gestalt:</label>
	<input id="check-gestalt" type="checkbox" bind:checked={empire.gestalt} />
	<br />
	<label for="check-gestalt">Machine:</label>
	<input id="check-gestalt" type="checkbox" bind:checked={empire.machine} />
	<br />
	<!--TODO: Add Scrolling to Dropdown Element-->
	<DropDown
		dropdownTitle={'Species*: ' + ($LeanChellarisDataStore.phenotypes[empire.portrait_group_id].species[empire.portrait_id].id + 1)}
		dropdownId={speciesDropdownId}
	>
		{#each Object.values($LeanChellarisDataStore.phenotypes[empire.portrait_group_id].species) as species}
			{#if species}
				<DropDownElement dropdownId={speciesDropdownId}>
					<input id={'checkbox' + species.id} data-dropdown={speciesDropdownId} type="radio" bind:group={empire.portrait_id} value={species.id} />
					<label for={'checkbox' + species.id} data-dropdown={speciesDropdownId}>{species.id + 1}</label>
				</DropDownElement>
			{/if}
		{/each}
	</DropDown>
	<br />
	<!--TODO: Add Scrolling to Dropdown Element-->
	<DropDown dropdownTitle={'Phenotype*: ' + $LeanChellarisDataStore.phenotypes[empire.portrait_group_id].display} dropdownId={phenotypeDropdownId}>
		{#each Object.values(Object.values($LeanChellarisDataStore.phenotypes)) as phenotype}
			{#if phenotype}
				<DropDownElement dropdownId={phenotypeDropdownId}>
					<input id={'checkbox' + phenotype.id} data-dropdown={phenotypeDropdownId} type="radio" bind:group={empire.portrait_group_id} value={phenotype.id} />
					<label for={'checkbox' + phenotype.id} data-dropdown={phenotypeDropdownId}>{phenotype.display}</label>
				</DropDownElement>
			{/if}
		{/each}
	</DropDown>
	<br />
	<label for="text-name">Empire Name*:</label>
	<input id="text-name" type="text" bind:value={empire.name} />
	<br />
	<label for="text-discord">Discord User:</label>
	<input id="text-discord" type="text" bind:value={empire.discord_user} />

	<DropDown
		dropdownTitle={'Ethics*: ' +
			Object.values(ethicsBuffer)
				.map((selection) => (selection.fanatic ? 'Fanatic ' : '') + $LeanChellarisDataStore.ethics[selection.ethic_id].display)
				.join(', ')}
		dropdownId={ethicsDropdownId}
	>
		{#each Object.values($LeanChellarisDataStore.ethics) as ethic, index}
			{#if ethic}
				<DropDownElement dropdownId={ethicsDropdownId}>
					<input
						id={'fanatic' + ethic.id}
						data-dropdown={ethicsDropdownId}
						type="checkbox"
						bind:checked={ethicsIdArray[index][1]}
						on:change={updateFanaticEthicsSelection}
						value={ethic.id}
					/>
					<label for={'fanatic' + ethic.id} data-dropdown={ethicsDropdownId}>Fanatic</label>
					<input
						id={'checkbox' + ethic.id}
						data-dropdown={ethicsDropdownId}
						type="checkbox"
						bind:checked={ethicsIdArray[index][0]}
						on:change={updateRegularEthicsSelection}
						value={ethic.id}
					/>
					<label for={'checkbox' + ethic.id} data-dropdown={ethicsDropdownId}>{ethic.display}</label>
				</DropDownElement>
			{/if}
		{/each}
	</DropDown>
	<button on:click={createEmpire}>Save</button>
	{#if newEmpireError[0]}
		<div>{newEmpireError[1]}</div>
	{/if}
{:else if !newEmpire}
	<div>
		{#if empire}
			<!-- <div>
				ID: {empire.id}
			</div>
			<div>
				Game ID: {empire.game}
			</div> -->
			<DropDown dropdownTitle={'Group: ' + groups[empire.group].name} dropdownId={groupDropdownId}>
				{#each Object.values(groups) as group}
					{#if group}
						<DropDownElement dropdownId={groupDropdownId}>
							<input id={'checkbox' + group.id} data-dropdown={groupDropdownId} type="radio" bind:group={empire.group} value={group.id} />
							<label for={'checkbox' + group.id} data-dropdown={groupDropdownId}>{group.name}</label>
						</DropDownElement>
					{/if}
				{/each}
			</DropDown>
			<br />
			<label for="check-gestalt">Gestalt:</label>
			<input id="check-gestalt" type="checkbox" bind:checked={empire.gestalt} />
			<br />
			<label for="check-gestalt">Machine:</label>
			<input id="check-gestalt" type="checkbox" bind:checked={empire.machine} />
			<br />
			<!--TODO: Add Scrolling to Dropdown Element-->
			<DropDown
				dropdownTitle={'Species: ' + ($LeanChellarisDataStore.phenotypes[empire.portrait_group_id].species[empire.portrait_id].id + 1)}
				dropdownId={speciesDropdownId}
			>
				{#each Object.values($LeanChellarisDataStore.phenotypes[empire.portrait_group_id].species) as species}
					{#if species}
						<DropDownElement dropdownId={speciesDropdownId}>
							<input id={'checkbox' + species.id} data-dropdown={speciesDropdownId} type="radio" bind:group={empire.portrait_id} value={species.id} />
							<label for={'checkbox' + species.id} data-dropdown={speciesDropdownId}>{species.id + 1}</label>
						</DropDownElement>
					{/if}
				{/each}
			</DropDown>
			<br />
			<!--TODO: Add Scrolling to Dropdown Element-->
			<DropDown dropdownTitle={'Phenotype: ' + $LeanChellarisDataStore.phenotypes[empire.portrait_group_id].display} dropdownId={phenotypeDropdownId}>
				{#each Object.values(Object.values($LeanChellarisDataStore.phenotypes)) as phenotype}
					{#if phenotype}
						<DropDownElement dropdownId={phenotypeDropdownId}>
							<input
								id={'checkbox' + phenotype.id}
								data-dropdown={phenotypeDropdownId}
								type="radio"
								bind:group={empire.portrait_group_id}
								value={phenotype.id}
							/>
							<label for={'checkbox' + phenotype.id} data-dropdown={phenotypeDropdownId}>{phenotype.display}</label>
						</DropDownElement>
					{/if}
				{/each}
			</DropDown>
			<br />
			<label for="text-name">Empire Name:</label>
			<input id="text-name" type="text" bind:value={empire.name} />
			<br />
			<label for="text-discord">Discord User:</label>
			<input id="text-discord" type="text" bind:value={empire.discord_user} />
			<DropDown
				dropdownTitle={'Ethics*: ' +
					Object.values(ethicsBuffer)
						.map((selection) => (selection.fanatic ? 'Fanatic ' : '') + $LeanChellarisDataStore.ethics[selection.ethic_id].display)
						.join(', ')}
				dropdownId={ethicsDropdownId}
			>
				{#each Object.values($LeanChellarisDataStore.ethics) as ethic, index}
					{#if ethic}
						<DropDownElement dropdownId={ethicsDropdownId}>
							<input
								id={'fanatic' + ethic.id}
								data-dropdown={ethicsDropdownId}
								type="checkbox"
								bind:checked={ethicsIdArray[index][1]}
								on:change={updateFanaticEthicsSelection}
								value={ethic.id}
							/>
							<label for={'fanatic' + ethic.id} data-dropdown={ethicsDropdownId}>Fanatic</label>
							<input
								id={'checkbox' + ethic.id}
								data-dropdown={ethicsDropdownId}
								type="checkbox"
								bind:checked={ethicsIdArray[index][0]}
								on:change={updateRegularEthicsSelection}
								value={ethic.id}
							/>
							<label for={'checkbox' + ethic.id} data-dropdown={ethicsDropdownId}>{ethic.display}</label>
						</DropDownElement>
					{/if}
				{/each}
			</DropDown>
		{:else}
			No Empire Selected
		{/if}
	</div>

	<button on:click={updateEmpire}>Save</button>
{/if}
</div>


<style>
</style>