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

	import { put, preventDefault, post, get, deleteR } from '$lib/utils';
	import { onMount } from 'svelte';
	import ExtractTextDialog from './ExtractTextDialog.svelte';
	import Flair from '../flair/Flair.svelte';
	import NewUrlDialog from './NewUrlDialog.svelte';
	import DropZone from './DropZone.svelte';
	import { userStore } from '$lib/UserStore.svelte';
	import LinkApplication from './LinkApplication.svelte';
	import SearchApplication from './SearchApplication.svelte';
	import NewApplication from './NewApplication.svelte';

	let activeItem: Application | undefined = $state();

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

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

	let showExtraData = $state(false);

	async function activate(item?: Application) {
		if (!item) {
			return;
		}
		if (activeItem && activeItem.id !== item.id && activeItem.status === 1) {
			// Deactivate active item
			try {
				await put('application/status', {
					id: activeItem.id,
					status: 0
				});
			} catch (e) {
				// Show User
				console.log('info data', e);
				return;
			}
		}

		if (item.status === 0) {
			openWindow(item.url);
			openCV(item.id);
		}

		try {
			await put('application/status', {
				id: item.id,
				status: ApplicationStatus.WorkingOnIt
			});
			activeItem = await get('application/active');
			if (!activeItem?.unique_url) {
				window.requestAnimationFrame(() => {
					changeUrl.showModal();
				});
			}
		} catch (e) {
			// Show User
			console.log('info data', e);
		}
		applicationStore.loadApplications(true);

		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 ?? activeItem!.id}`,
			'cv viwer',
			`location,height=${window.screen.height},width=${window.screen.width},scrollbars,status,toolbar,menubar,popup`
		);
	}

	async function loadActive() {
		try {
			activeItem = await get('application/active');
			if (activeItem?.unique_url === null) {
				changeUrl.showModal();
			}
		} catch (e) {
			// Show User
			console.log('info data', e);
		}
	}

	// 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) return;
		activeItem.title = lastExtData.jobTitle;
		activeItem.company = lastExtData.company;
		activeItem.payrange = lastExtData.money;
		window.requestAnimationFrame(() => {
			save().then(async () => {
				if (!lastExtData.description) {
					lastExtData = undefined;
					return;
				}
				await post('application/text/flair', {
					id: activeItem?.id ?? '',
					text: lastExtData.description
				});
				loadActive();
				lastExtData = undefined;
			});
		});
	}

	onMount(() => {
		userStore.checkLogin();
		loadActive();
	});

	$effect(() => {
		if (!applicationStore.loadItem) {
			return;
		}
		activeItem = applicationStore.loadItem;
		applicationStore.loadItem = undefined;
	});

	async function moveStatus(status: AsEnum<typeof ApplicationStatus>, moveOut = true) {
		if (!activeItem) return;
		// Deactivate active item
		try {
			await put('application/status', {
				id: activeItem.id,
				status: status
			});
		} catch (e) {
			// Show User
			console.log('info data', e);
			return;
		}
		applicationStore.loadApplications(true);
		applicationStore.loadAplyed(true);
		if (moveOut) {
			activeItem = undefined;
		} else {
			activeItem.status = status;
		}
		//openedWindow?.close();
		//openedWindow = undefined;
	}

	async function remove() {
		if (!activeItem) return;
		// Deactivate active item
		try {
			await deleteR(`application/${activeItem.id}`);
		} catch (e) {
			// Show User
			console.log('info data', e);
			return;
		}
		applicationStore.loadApplications(true);
		activeItem = undefined;
		//openedWindow?.close();
		//openedWindow = undefined;
	}

	async function save() {
		try {
			await put('application/update', activeItem);
		} catch (e) {
			// Show User
			console.log('info data', e);
		}
	}

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

	let drag = $state(true);

	const statusMapping: string = $derived(
		(ApplicationStatusMaping[
			activeItem?.status as (typeof ApplicationStatus)[keyof typeof ApplicationStatus]
		] as string) ?? ''
	);
</script>

<div class="flex flex-col w-full gap-2 min-w-0 relative" role="none">
	{#if activeItem && (!applicationStore.dragging || applicationStore.dragging?.id === activeItem.id)}
		<div
			draggable={drag}
			ondrag={() => {
				applicationStore.dragStart(activeItem);
			}}
			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">
				{#if activeItem.status != 1}
					<div class="bg-danger text-white p-2 rounded-lg text-lg font-bold">
						{statusMapping}
					</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">
							{activeItem.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">
							{activeItem.create_time}
						</div>
					</fieldset>
				{/if}
				<div class="flex gap-2">
					<fieldset class="grow">
						<label class="flabel" for="title">Company</label>
						<input
							class="finput"
							id="title"
							bind:value={activeItem.company}
							onchange={save}
						/>
					</fieldset>
					<fieldset class="grow">
						<label class="flabel" for="title">Recruiter</label>
						<input
							class="finput"
							id="title"
							bind:value={activeItem.recruiter}
							onchange={save}
						/>
					</fieldset>
				</div>
				<fieldset>
					<label class="flabel" for="title">Title</label>
					<input
						class="finput"
						id="title"
						bind:value={activeItem.title}
						onchange={save}
					/>
				</fieldset>
				<fieldset>
					<label class="flabel" for="payrange">Pay Range</label>
					<input
						class="finput"
						id="payrange"
						bind:value={activeItem.payrange}
						onchange={save}
					/>
				</fieldset>
				<fieldset draggable="false" class="max-w-full min-w-0 overflow-hidden">
					<div class="flabel">Url</div>
					<div class="finput bg-white w-full break-keep">
						{activeItem.url}
					</div>
				</fieldset>
				{#if activeItem.unique_url && activeItem.unique_url !== activeItem.url}
					<fieldset draggable="false">
						<div class="flabel">Unique Url</div>
						<div class="finput bg-white">
							{activeItem.unique_url}
						</div>
					</fieldset>
				{/if}
				{#if activeItem.linked_application}
					<fieldset draggable="false">
						<div class="flabel">Linked Application</div>
						<div class="finput bg-white">
							{activeItem.linked_application}
						</div>
					</fieldset>
				{/if}
				{#if activeItem.application_time}
					<fieldset draggable="false">
						<div class="flabel">Application Time</div>
						<div class="finput bg-white">
							{activeItem.application_time}
						</div>
					</fieldset>
				{/if}
				<div>
					<div class="flabel">Tags</div>
					<div class="flex gap-2 flex-wrap">
						{#each activeItem.flairs as item}
							<Flair
								{item}
								allowDelete
								application={activeItem}
								updateApplication={(item) => (activeItem = item)}
							/>
						{/each}
					</div>
				</div>
				<fieldset>
					<label class="flabel" for="extra">Extra Info</label>
					<textarea
						class="finput"
						id="extra"
						bind:value={activeItem.extra_data}
						onchange={save}
					></textarea>
				</fieldset>
				<fieldset>
					<label class="flabel" for="extra">Message</label>
					<textarea
						draggable={false}
						class="finput"
						id="extra"
						bind:value={activeItem.message}
						onchange={save}
					></textarea>
				</fieldset>
				{#if activeItem.views.length > 0}
					<h1 class="text-sm">Non Loggedin Views Time ({activeItem.views.length})</h1>
					{#each activeItem.views as view}
						<div>
							{view.time}
						</div>
					{/each}
				{/if}
			</div>
			<div class="flex btns">
				<button
					class="btn-confirm"
					onclick={() => {
						openWindow(activeItem!.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}
				{#if activeItem.original_url == null}
					<button class="btn-primary" onclick={() => changeUrl.showModal()}>
						Update Url
					</button>
				{/if}
				<div class="px-10"></div>
				<button class="btn-primary" onclick={() => linkApplication.showModal()}>
					Link Application
				</button>
				{#if activeItem.original_url != null}
					<button class="btn-danger" onclick={resetUrl}> Reset Url </button>
				{/if}
				<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>
		</div>
		{#if applicationStore.dragging}
			<div
				class="flex w-full flex-grow rounded-lg p-3 gap-2 absolute bottom-0 left-0 right-0 bg-white"
			>
				<!-- Do nothing -->
				<DropZone
					icon="box-arrow-down"
					ondrop={() => {
						moveStatus(ApplicationStatus.ToApply);
						applicationStore.loadAplyed(true);
						applicationStore.loadTasksToDo(true);
					}}
				>
					To apply
				</DropZone>

				{#if activeItem.status === ApplicationStatus.WorkingOnIt}
					<!-- Ignore -->
					<DropZone
						icon="trash-fill"
						ondrop={() => {
							moveStatus(ApplicationStatus.Ignore);
						}}
					>
						Ignore it
					</DropZone>
				{/if}

				{#if [ApplicationStatus.WorkingOnIt, ApplicationStatus.Expired].includes(activeItem.status)}
					<!-- Expired -->
					<DropZone
						icon="clock-fill text-orange-500"
						ondrop={() => {
							if (activeItem && activeItem.status === ApplicationStatus.Expired) {
								moveStatus(ApplicationStatus.ToApply, false);
							} else {
								moveStatus(ApplicationStatus.Expired);
							}
						}}
					>
						Mark as expired
					</DropZone>
				{/if}

				{#if activeItem.status === ApplicationStatus.WorkingOnIt}
					<!-- Repeated -->
					<DropZone icon="trash-fill text-danger" ondrop={() => remove()}
						>Delete it</DropZone
					>
				{/if}

				{#if [ApplicationStatus.WorkingOnIt, ApplicationStatus.TasksToDo].includes(activeItem.status)}
					<!-- Applyed -->
					<DropZone
						icon="server text-confirm"
						ondrop={async () => {
							await moveStatus(ApplicationStatus.Applyed);
							applicationStore.loadAplyed(true);
							applicationStore.loadTasksToDo(true);
						}}
					>
						Apply
					</DropZone>
				{/if}

				{#if activeItem.status === ApplicationStatus.Applyed}
					<!-- Tasks to do -->
					<DropZone
						icon="server text-confirm"
						ondrop={async () => {
							await moveStatus(ApplicationStatus.TasksToDo);
							applicationStore.loadTasksToDo(true);
							applicationStore.loadAplyed(true);
						}}
					>
						Tasks To Do
					</DropZone>
				{/if}

				<!-- Rejected -->
				<DropZone
					icon="fire text-danger"
					ondrop={() => moveStatus(ApplicationStatus.ApplyedButSaidNo)}
				>
					I was rejeted :(
				</DropZone>
			</div>
		{/if}
	{: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={activeItem?.id ?? ''} bind:dialog={extractTokens} onreload={loadActive} />

{#if !activeItem?.original_url}
	<NewUrlDialog
		id={activeItem?.id ?? ''}
		bind:dialog={changeUrl}
		onreload={(item) => (activeItem = item)}
	/>
{/if}

{#if activeItem}
	<LinkApplication
		application={activeItem}
		bind:dialog={linkApplication}
		onreload={(item) => (activeItem = item)}
	/>
{/if}

<SearchApplication application={activeItem} onreload={(item) => (activeItem = item)} />

<NewApplication
	onreload={(item) => {
		activate(item);
	}}
/>
