<script lang="ts">
	import { applicationStore, type Application } from '$lib/ApplicationsStore.svelte';

	import { put, preventDefault, post, get } from '$lib/utils';
	import { onMount } from 'svelte';
	import ExtractTextDialog from './ExtractTextDialog.svelte';
	import Flair from '../flair/Flair.svelte';
	import NewUrlDialog from './NewUrlDialog.svelte';
	import { userStore } from '$lib/UserStore.svelte';
	import LinkApplication from './LinkApplication.svelte';
	import SearchApplication from './SearchApplication.svelte';
	import NewApplication from './NewApplication.svelte';
	import Timeline from './Timeline.svelte';
	import CompanyField from './CompanyField.svelte';
	import AutoDropZone from './AutoDropZone.svelte';
	import { statusStore } from '$lib/Types.svelte';

	// Not this represents the index in the store array
	let activeItem: number | undefined = $state();

	let derivedItem: Application | undefined = $derived(applicationStore.all[activeItem ?? -1]);

	let extractTokens: HTMLDialogElement;
	let changeUrl: HTMLDialogElement;
	let linkApplication: HTMLDialogElement;

	let lastExtData: any = $state(undefined);
	let autoExtData = false;

	let showExtraData = $state(false);

	let drag = $state(true);

	async function activate(item?: Application, ow = true) {
		if (!item) {
			return;
		}

		if (ow && item.id !== derivedItem?.id) {
			openWindow(item.url);
		}
		openCV(item.id);

		try {
			const toLoadItem: Application = await get(`application/${item.id}`);
			if (!toLoadItem?.simple_url) {
				window.requestAnimationFrame(() => {
					changeUrl.showModal();
				});
			}
			activeItem = applicationStore.getIndexById(toLoadItem.id);
			applicationStore.all[activeItem ?? -1] = toLoadItem;
			applicationStore.reset();
		} catch (e) {
			// Show User
			console.log('info data', e);
		}

		autoExtData = false;
		lastExtData = undefined;
	}

	function openWindow(url: string) {
		if (!url.startsWith('https://')) {
			url = `https://${url}`;
		}

		window.open(
			url,
			'new window',
			`location,height=${window.screen.height},width=${window.screen.width},scrollbars,status,toolbar,menubar,popup`
		);
	}

	function openCV(id?: string) {
		window.open(
			`/cv?id=${id ?? derivedItem!.id}`,
			'cv viwer',
			`location,height=${window.screen.height},width=${window.screen.width},scrollbars,status,toolbar,menubar,popup`
		);
	}

	//
	// Make the CV open on a new page
	//
	function docKey(e: KeyboardEvent) {
		if (derivedItem && e.ctrlKey && e.code === 'KeyO') {
			openCV(derivedItem.id);
			e.stopPropagation();
			e.preventDefault();
			return;
		}
	}
	$effect(() => {
		document.addEventListener('keydown', docKey, false);
		return () => {
			document.removeEventListener('keydown', docKey);
		};
	});
	//
	//
	//

	// Load Ext
	$effect(() => {
		function onMessage(e: MessageEvent) {
			if (e.data.type === 'GOT_INFO_R') {
				lastExtData = e.data;
				if (autoExtData) {
					window.requestAnimationFrame(() => {
						setExtData();
					});
				}
			}
		}

		window.addEventListener('message', onMessage);
		window.postMessage({ type: 'REGISTER_INTEREST' });
		return () => {
			window.removeEventListener('message', onMessage);
		};
	});

	function setExtData() {
		if (!lastExtData || activeItem === undefined || !derivedItem) return;
		applicationStore.all[activeItem].title = lastExtData.jobTitle.replace(/\&amp;/, '&');
		applicationStore.all[activeItem].company = lastExtData.company.replace(/\&amp;/, '&');

		if (
			!(
				applicationStore.all[activeItem].payrange.match('Glassdoor est.') &&
				lastExtData.money.match('Glassdoor est.')
			) &&
			!(applicationStore.all[activeItem].payrange !== '' && lastExtData.money === '')
		) {
			applicationStore.all[activeItem].payrange = lastExtData.money;
		}

		const title: string = lastExtData.jobTitle;
		if (title.match(/intern|apprenticeship/i)) {
			applicationStore.all[activeItem].job_level = 'intern';
		} else if (title.match(/graduate/i)) {
			applicationStore.all[activeItem].job_level = 'entry';
		} else if (title.match(/junior|associate/i)) {
			applicationStore.all[activeItem].job_level = 'junior';
		} else if (title.match(/mid/i)) {
			applicationStore.all[activeItem].job_level = 'mid';
		} else if (title.match(/senior|III/i)) {
			applicationStore.all[activeItem].job_level = 'senior';
		} else if (title.match(/staff/i)) {
			applicationStore.all[activeItem].job_level = 'staff';
		} else if (title.match(/lead/i)) {
			applicationStore.all[activeItem].job_level = 'lead';
		}

		window.requestAnimationFrame(() => {
			save().then(async () => {
				if (activeItem === undefined) return;
				if (!lastExtData.description) {
					lastExtData = undefined;
					return;
				}
				await post('application/text/flair', {
					id: derivedItem.id ?? '',
					text: lastExtData.description
				});
				activate(derivedItem, false);
				lastExtData = undefined;
			});
		});
	}

	onMount(() => {
		userStore.checkLogin();
		statusStore.load();
	});

	$effect(() => {
		if (!applicationStore.loadItem) {
			return;
		}
		(async () => {
			await activate(applicationStore.loadItem, applicationStore.loadItemOpen);
			applicationStore.loadItem = undefined;
		})();
	});

	$effect(() => {
		applicationStore.loadAll();
	});

	async function save() {
		try {
			await put('application/update', applicationStore.all[activeItem ?? -1]);
		} catch (e) {
			// Show User
			console.log('info data', e);
		}
	}

	async function resetUrl() {
		try {
			activeItem = await post(`application/reset/url/${derivedItem?.id}`, {});
		} catch (e) {
			// Show User
			console.log('info data', e);
		}
	}
</script>

<div class="flex flex-col w-full gap-2 min-w-0 relative" role="none">
	{#if activeItem !== undefined && (!applicationStore.dragging || applicationStore.dragging?.id === derivedItem.id)}
		<div
			draggable={drag}
			ondrag={() => {
				applicationStore.dragStart(derivedItem);
			}}
			ondragend={() => {
				window.requestAnimationFrame(() => {
					applicationStore.dragEnd();
				});
			}}
			role="none"
			class="flex flex-col p-2 h-full gap-2 card min-w-0 flex-grow min-h-[50vh]"
		>
			<div class="w-full">
				<!-- TODO add item -->
				{#if derivedItem.status_id !== null}
					<div class="bg-danger text-white p-2 rounded-lg text-lg font-bold">
						{statusStore.nodesR[derivedItem.status_id].name}
					</div>
				{/if}
				{#if showExtraData}
					<fieldset class="max-w-full min-w-0 overflow-hidden">
						<div class="flabel">Id</div>
						<div class="finput bg-white w-full break-keep">
							{derivedItem.id}
						</div>
					</fieldset>
					<fieldset class="max-w-full min-w-0 overflow-hidden">
						<div class="flabel">Create Time</div>
						<div class="finput bg-white w-full break-keep">
							{derivedItem.create_time}
						</div>
					</fieldset>
				{/if}
				<div class="flex gap-2">
					<CompanyField index={activeItem} {save} />
					<fieldset class="grow">
						<label class="flabel" for="title">Recruiter</label>
						<input
							class="finput"
							id="title"
							bind:value={applicationStore.all[activeItem].recruiter}
							onchange={save}
						/>
					</fieldset>
					<fieldset>
						<label class="flabel" for="title">Agency</label>
						<input
							class="finput"
							id="title"
							type="checkbox"
							bind:checked={applicationStore.all[activeItem].agency}
							onchange={save}
						/>
					</fieldset>
				</div>
				<fieldset>
					<label class="flabel" for="title">Title</label>
					<input
						class="finput"
						id="title"
						bind:value={applicationStore.all[activeItem].title}
						onchange={save}
					/>
				</fieldset>
				<fieldset>
					<label class="flabel" for="payrange">Pay Range</label>
					<input
						class="finput"
						id="payrange"
						bind:value={applicationStore.all[activeItem].payrange}
						onchange={save}
					/>
				</fieldset>
				{#if !derivedItem.simple_url || showExtraData}
					<fieldset class="max-w-full min-w-0 overflow-hidden">
						<div class="flabel">Url</div>
						<div class="finput bg-white w-full break-keep">
							{derivedItem.url}
						</div>
					</fieldset>
				{/if}
				{#if derivedItem.simple_url}
					<fieldset class="max-w-full min-w-0 overflow-hidden">
						<div class="flabel">Simple Url</div>
						<div class="finput bg-white w-full break-keep">
							{derivedItem.simple_url}
						</div>
					</fieldset>
				{/if}
				{#if showExtraData}
					<div>
						<div class="flabel">Simple Url</div>
						<div class="flex flex-col gap-2">
							{#each derivedItem.urls as url}
								<div>
									<button
										class="text-violet-300 text-nowrap whitespace-nowrap overflow-x-hidden"
										onclick={() => {
											openWindow(url);
										}}>{url}</button
									>
								</div>
							{/each}
						</div>
					</div>
				{/if}
				<fieldset>
					<label class="flabel" for="title">Job Level</label>
					<select
						class="finput"
						id="job_level"
						bind:value={applicationStore.all[activeItem].job_level}
						onchange={save}
					>
						<option value="intern"> Intern </option>
						<option value="entry"> Entry </option>
						<option value="junior"> Junior </option>
						<option value="mid"> Mid </option>
						<option value="senior"> Senior </option>
						<option value="staff"> Staff </option>
						<option value="lead"> Lead </option>
					</select>
				</fieldset>
				<div>
					<div class="flabel">Tags</div>
					<div class="flex gap-2 flex-wrap">
						{#each derivedItem.flairs as item}
							<Flair
								{item}
								allowDelete
								application={derivedItem}
								updateApplication={(item) =>
									(applicationStore.all[activeItem ?? -1] = item)}
							/>
						{/each}
					</div>
				</div>
				<fieldset>
					<label class="flabel" for="extra">Extra Info</label>
					<textarea
						class="finput"
						id="extra"
						bind:value={applicationStore.all[activeItem].extra_data}
						onchange={save}
					></textarea>
				</fieldset>
				<fieldset>
					<label class="flabel" for="extra">Message</label>
					<textarea
						class="finput"
						id="extra"
						bind:value={applicationStore.all[activeItem].message}
						onchange={save}
					></textarea>
				</fieldset>
			</div>
			<div class="flex btns">
				<button
					class="btn-confirm"
					onclick={() => {
						openWindow(derivedItem!.url);
					}}
				>
					Open
				</button>
				<button class="btn-primary" onclick={() => openCV()}> Open CV </button>
				<div class="px-10"></div>
				<button class="btn-primary" onclick={() => extractTokens.showModal()}>
					Extract Flair
				</button>
				{#if lastExtData !== undefined}
					<button class="btn-primary" onclick={() => setExtData()}> Ext Data </button>
				{:else}
					<button
						class="btn-primary"
						onclick={() => {
							autoExtData = true;
							window.postMessage({ type: 'R_GET_DATA_FROM_PAGE' });
						}}
					>
						Get Ext Data
					</button>
				{/if}
				<button
					class={derivedItem.simple_url ? 'btn-danger' : 'btn-primary'}
					onclick={() => changeUrl.showModal()}
				>
					Update Url
				</button>
				<div class="px-10"></div>
				<button class="btn-primary" onclick={() => linkApplication.showModal()}>
					Link Application
				</button>
				<button
					class:btn-primary={drag}
					class:btn-danger={!drag}
					onclick={() => (drag = !drag)}
				>
					👋
				</button>
				<button
					class:btn-primary={!showExtraData}
					class:btn-confirm={showExtraData}
					onclick={() => (showExtraData = !showExtraData)}
				>
					🔬
				</button>
			</div>
			<Timeline application={derivedItem} showAll={showExtraData} />
		</div>
		<AutoDropZone bind:index={activeItem} />
	{:else}
		<div
			class="p-2 h-full w-full gap-2 flex-grow card grid place-items-center min-h-[50vh]"
			ondragover={(e) => {
				e.preventDefault();
			}}
			ondragenter={preventDefault(() => {})}
			ondrop={() => {
				activate(applicationStore.dragging);
			}}
			role="none"
		>
			<div class="text-center relative">
				<span
					class="bi bi-layers-fill text-7xl text-white absolute"
					class:animate-bounce={applicationStore.dragging}
				></span>
				<span class="bi bi-layers-fill text-7xl text-white opacity-0"></span>
				<div class="text-xl">Drop Application To Manage</div>
			</div>
		</div>
	{/if}
</div>

<ExtractTextDialog
	id={derivedItem?.id ?? ''}
	bind:dialog={extractTokens}
	onreload={() => activate(derivedItem, false)}
/>

{#if derivedItem}
	<NewUrlDialog
		id={derivedItem?.id ?? ''}
		bind:dialog={changeUrl}
		index={activeItem}
		onreload={async (item) => {
			activate(item, false);
		}}
	/>
{/if}

{#if derivedItem}
	<LinkApplication
		application={derivedItem}
		bind:dialog={linkApplication}
		onreload={(item) => activate(item, false)}
	/>
{/if}

<SearchApplication
	application={derivedItem}
	onreload={async (item) => {
		activate(item);
	}}
/>

<NewApplication onreload={activate} />
