<script lang="ts">
	import { m } from '$lib/paraglide/messages';
	import { CardContainer, Alert } from '$lib/components';
	import { getFirmwareBinaryName, getWebUiBinaryName } from '$lib/utils';
	import { status, settings, firmwareRelease } from '$lib/stores';
	import { onMount } from 'svelte';
	import { uploadFirmwareFile, uploadWebUiFile, autoUpdate } from '$lib/clockControl';

	// Format date to a more readable format
	function formatDate(dateString: string): string {
		if (!dateString) return '';
		const date = new Date(dateString);
		return date.toLocaleString();
	}

	// Upload status
	let firmwareUploadProgress = 0;
	let webuiUploadProgress = 0;
	let isUploading = false;
	let uploadError: string | null = null;
	let uploadSuccess = false;
	let countdownValue = 0;
	let countdownInterval: number | null = null;

	// File selection status
	let firmwareFileSelected = false;
	let webuiFileSelected = false;

	// Handle file selection change for firmware file
	function handleFirmwareFileChange(event: Event) {
		const fileInput = event.target as HTMLInputElement;
		firmwareFileSelected = !!(fileInput.files && fileInput.files.length > 0);
	}

	// Handle file selection change for WebUI file
	function handleWebUIFileChange(event: Event) {
		const fileInput = event.target as HTMLInputElement;
		webuiFileSelected = !!(fileInput.files && fileInput.files.length > 0);
	}

	// Start countdown to reload page after successful upload
	function startCountdownToReload(seconds: number) {
		countdownValue = seconds;
		if (countdownInterval) clearInterval(countdownInterval);

		countdownInterval = setInterval(() => {
			countdownValue--;
			if (countdownValue <= 0) {
				if (countdownInterval) clearInterval(countdownInterval);
				window.location.reload();
			}
		}, 1000) as unknown as number;
	}

	// Handle firmware file upload
	function handleFirmwareUpload() {
		const fileInput = document.getElementById('firmwareFile') as HTMLInputElement;
		if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
			uploadError = 'Please select a firmware file';
			return;
		}

		isUploading = true;
		uploadError = null;
		uploadSuccess = false;
		firmwareUploadProgress = 0;

		uploadFirmwareFile(fileInput.files[0], {
			onProgress: (progress) => {
				firmwareUploadProgress = progress;
			},
			onSuccess: () => {
				isUploading = false;
				uploadSuccess = true;
				startCountdownToReload(10);
			},
			onError: (error) => {
				isUploading = false;
				uploadError =
					typeof error === 'string' && error !== 'FAIL' ? error : 'Failed to upload firmware';
			}
		});
	}

	// Handle webUI file upload
	function handleWebUIUpload() {
		const fileInput = document.getElementById('webuiFile') as HTMLInputElement;
		if (!fileInput || !fileInput.files || fileInput.files.length === 0) {
			uploadError = 'Please select a WebUI file';
			return;
		}

		isUploading = true;
		uploadError = null;
		uploadSuccess = false;
		webuiUploadProgress = 0;

		uploadWebUiFile(fileInput.files[0], {
			onProgress: (progress) => {
				webuiUploadProgress = progress;
			},
			onSuccess: () => {
				isUploading = false;
				uploadSuccess = true;
				startCountdownToReload(10);
			},
			onError: (error) => {
				isUploading = false;
				uploadError = typeof error === 'string' ? error : 'Failed to upload WebUI';
			}
		});
	}

	const onAutoUpdate = (e: Event) => {
		e.preventDefault();
		autoUpdate({
			onSuccess: () => {
				// toast.push({
				// 	type: 'success',
				// 	message
				// });
				startCountdownToReload(10);
			},
			onError: (error) => {
				// toast.push({
				// 	type: 'error',
				// 	message: error as string
				// });
				uploadError = typeof error === 'string' ? error : 'Failed to auto-update';
			}
		});
	};

	// Fetch firmware data when component is mounted
	onMount(() => {
		firmwareRelease.fetchLatest();

		// Cleanup on component destroy
		return () => {
			if (countdownInterval) clearInterval(countdownInterval);
		};
	});
</script>

<CardContainer title={m['section.control.firmwareUpdate']()} className="">
	<div>
		{#if $firmwareRelease.isLoading}
			<div class="my-4 flex justify-center">
				<span class="loading loading-spinner"></span>
			</div>
		{:else if $firmwareRelease.error}
			<Alert type="error" className="mb-4" message={$firmwareRelease.error} />
		{:else}
			<p class="mb-2 text-sm">
				{m['section.firmwareUpdater.latestVersion']()}
				{$firmwareRelease.tag_name} - {m['section.firmwareUpdater.releaseDate']()}
				{formatDate($firmwareRelease.published_at)} -
				<a
					href={$firmwareRelease.html_url}
					target="_blank"
					rel="noopener noreferrer"
					class="link link-primary"
				>
					{m['section.firmwareUpdater.viewRelease']()}
				</a>
			</p>

			{#if !$status.isOTAUpdating && $settings.gitTag !== $firmwareRelease.tag_name}
				<Alert type="success" className="mb-4">
					{m['section.firmwareUpdater.swUpdateAvailable']()}
					{$settings.gitTag} → {$firmwareRelease.tag_name} -
					<a href="/" class="link link-primary" on:click={onAutoUpdate}
						>{m['section.firmwareUpdater.autoUpdate']()}</a
					>.
				</Alert>
			{/if}
		{/if}

		{#if !$status.isOTAUpdating}
			<div class="form-control mb-4">
				<label class="label" for="firmwareFile">
					<span class="label-text">Firmware File ({getFirmwareBinaryName($settings.hwRev)})</span>
				</label>
				<div class="flex gap-2">
					<input
						type="file"
						class="file-input file-input-bordered w-full"
						id="firmwareFile"
						accept=".bin"
						disabled={isUploading}
						on:change={handleFirmwareFileChange}
					/>
					<button
						class="btn btn-primary w-1/4"
						on:click={handleFirmwareUpload}
						disabled={isUploading || !firmwareFileSelected}
					>
						{#if isUploading && firmwareUploadProgress > 0}
							{firmwareUploadProgress}%
						{:else}
							{m['section.control.firmwareUpdate']()}
						{/if}
					</button>
				</div>
				{#if isUploading && firmwareUploadProgress > 0}
					<progress class="progress progress-primary mt-2" value={firmwareUploadProgress} max="100"
					></progress>
				{/if}
			</div>
			<div class="form-control">
				<label class="label" for="webuiFile">
					<span class="label-text">WebUI File ({getWebUiBinaryName($settings.hwRev)})</span>
				</label>
				<div class="flex gap-2">
					<input
						type="file"
						class="file-input file-input-bordered w-full"
						id="webuiFile"
						accept=".bin"
						disabled={isUploading}
						on:change={handleWebUIFileChange}
					/>
					<button
						class="btn btn-primary w-1/4"
						on:click={handleWebUIUpload}
						disabled={isUploading || !webuiFileSelected}
					>
						{#if isUploading && webuiUploadProgress > 0}
							{webuiUploadProgress}%
						{:else}
							Update WebUI
						{/if}
					</button>
				</div>
				{#if isUploading && webuiUploadProgress > 0}
					<progress class="progress progress-primary mt-2" value={webuiUploadProgress} max="100"
					></progress>
				{/if}
			</div>
		{:else}
			<Alert type="info" className="my-4">
				<span class="loading loading-spinner text-neutral"></span>
				{m['section.firmwareUpdater.autoUpdateInProgress']()}
			</Alert>
		{/if}
		{#if uploadSuccess}
			<Alert type="success" className="my-4">
				{m['section.firmwareUpdater.fileUploadSuccess']({ countdown: countdownValue })}
			</Alert>
		{:else if uploadError}
			<Alert type="error" className="my-4">
				{uploadError}
			</Alert>
		{/if}
		<Alert type="warning" className="mt-4">
			{m['section.firmwareUpdater.firmwareUpdateText']()}
		</Alert>
	</div>
</CardContainer>
