<script lang="ts">
	import {
		ArrowRight,
		Ban,
		FileIcon,
		Folder,
		Play,
		RefreshCcwDot,
		TriangleAlert
	} from 'lucide-svelte';
	import {
		current_height,
		get_selectable_color_classes,
		get_shifted_color
	} from '../ts/stores/ui_behavior';
	import Button from './Button.svelte';
	import { supported_file_type_icon, type FolderElement, type SupportedFileType } from '../ts/types';
	
	import {
		is_selected,
		select,
		selected_display_ids,
		selected_file_ids
	} from '../ts/stores/select';
	import {
		all_files,
		change_file_path,
		current_file_path,
		get_display_ids_where_file_is_missing
	} from '../ts/stores/files';
	import RefreshPlay from './RefreshPlay.svelte';
	import { get_file_size_display_string, get_file_type } from '../ts/utils';
	import { open_file } from '../ts/api_handler';
	import {
		displays,
		get_display_by_id,
		run_on_all_selected_displays,
		update_screenshot
	} from '../ts/stores/displays';
	import { get_thumbnail_url } from '../ts/stores/thumbnails';
	import { db } from '../ts/indexdb/file_thumbnails.db';
	import { onDestroy, onMount } from 'svelte';
	import { liveQuery } from 'dexie';

	let { file } = $props<{ file: FolderElement }>();

	let thumbnail_url: string | null = $state(null);
	// Update thumbnail_url automatically if data is available
	const subscription = liveQuery(() => db.thumbnail_blobs.get(file.hash)).subscribe({
		next: async () => {
			thumbnail_url = await get_thumbnail_url(file.hash);
		},
		error: (err) => console.error('Dexie subscription error:', err)
	});
	onDestroy(() => subscription.unsubscribe());

	const is_folder = file.type === 'inode/directory';

	function get_created_string(date_object: Date, full_string = false) {
		if (full_string) {
			return (
				get_formated_date_string(date_object, true) + ' ' + get_formated_time_string(date_object)
			);
		} else if (date_object.toDateString() === new Date().toDateString()) {
			return get_formated_time_string(date_object);
		} else {
			return get_formated_date_string(date_object);
		}
	}

	function get_formated_time_string(date_object: Date) {
		return `${date_object.getHours().toString().padStart(2, '0')}:${date_object.getMinutes().toString().padStart(2, '0')}`;
	}

	function get_formated_date_string(date_object: Date, full_year = false) {
		return `${date_object.getDate().toString().padStart(2, '0')}.${(date_object.getMonth() + 1).toString().padStart(2, '0')}.${date_object
			.getFullYear()
			.toString()
			.slice(full_year ? 0 : 2)}`;
	}

	function get_grayed_out_text_color_strings(is_selected: boolean): string {
		const color = is_selected ? 'text-stone-600' : 'text-stone-400';
		const factor = is_selected ? -1 : 1;
		return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
	}

	function get_grayed_out_border_color_strings(is_selected: boolean): string {
		const color = is_selected ? 'border-stone-450' : 'border-stone-550';
		const factor = is_selected ? 1 : 1;
		return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
	}

	function onclick(e: Event) {
		select(selected_file_ids, file.id);
		e.stopPropagation();
	}

	async function open() {
		if (is_folder) {
			change_file_path($current_file_path + file.name + '/');
		} else {
			const path_to_file = $current_file_path + file.name;
			await run_on_all_selected_displays(open_file, true, path_to_file);
		}
	}
</script>

<div class="flex flex-row h-{$current_height.file} w-full">
	<div class="h-{$current_height.file} aspect-square max-w-15 flex">
		<Button
			disabled={!is_folder && get_file_type(file) === null}
			title={!is_folder && get_file_type(file) === null ? 'Dateityp nicht unterstützt' : ''}
			className="flex rounded-l-lg rounded-r-none {is_folder
				? 'text-stone-450'
				: 'text-stone-800'} w-full"
			div_class="w-full"
			bg={get_selectable_color_classes(
				!is_folder && get_file_type(file) !== null,
				{
					bg: true
				},
				-50
			)}
			hover_bg={get_selectable_color_classes(
				!is_folder,
				{
					bg: true
				},
				50
			)}
			active_bg={get_selectable_color_classes(
				!is_folder,
				{
					bg: true
				},
				100
			)}
			click_function={(e) => {
				open();
				e.stopPropagation();
			}}
		>
			{#if is_folder}
				<ArrowRight class="size-full" strokeWidth="3" />
			{:else if get_display_ids_where_file_is_missing($current_file_path, file, $selected_display_ids, $all_files)[0].length !== 0}
				<RefreshPlay className="size-full" />
			{:else if get_file_type(file) !== null}
				<Play class="size-full" strokeWidth="3" />
			{:else}
				<Ban class="size-full" strokeWidth="3" />
			{/if}
		</Button>
	</div>
	<div
		role="button"
		tabindex="0"
		onkeydown={(e) => {
			if (e.key === 'Enter' || e.key === ' ') onclick(e);
		}}
		{onclick}
		class="{get_selectable_color_classes(is_selected(file.id, $selected_file_ids), {
			bg: true,
			hover: true,
			active: true,
			text: true
		})} rounded-r-lg transition-colors duration-200 gap-4 flex flex-row justify-between cursor-pointer group w-full min-w-0"
	>
		<div class="flex flex-row gap-2 min-w-0 w-full">
			<div
				class="aspect-square rounded-md flex justify-center items-center"
			>
				{#if is_folder}
					<Folder class="size-full p-2" />
				{:else if thumbnail_url}
					<img
						src={thumbnail_url}
						alt="file_thumbnail"
						class="object-contain size-full select-none block p-1"
						draggable="false"
					/>
				{:else if supported_file_type_icon[get_file_type(file)?.display_name || '']}
					{@const Icon = supported_file_type_icon[get_file_type(file)?.display_name || '']}
					<Icon class="size-full p-2" />
				{:else}
					<FileIcon class="size-full p-2" />
				{/if}
			</div>
			<div class="content-center truncate select-none w-full" title={file.name}>
				{file.name.includes('.') && !is_folder && get_file_type(file) ? file.name.slice(0, file.name.lastIndexOf('.')) : file.name}
			</div>
		</div>
		<div
			class=" p-1 flex flex-row items-center gap-1 pr-1 {get_grayed_out_text_color_strings(
				is_selected(file.id, $selected_file_ids)
			)} duration-200 transition-colors"
		>
			{#if get_display_ids_where_file_is_missing($current_file_path, file, $selected_display_ids, $all_files)[1].length !== 0}
				<Button
					className="h-8 aspect-square transition-colors duration-200 !p-1.5 text-stone-100"
					bg="bg-red-500"
					click_function={(e) => {
						e.stopPropagation();
					}}
				>
					<TriangleAlert class="size-full" />
				</Button>
			{:else if get_display_ids_where_file_is_missing($current_file_path, file, $selected_display_ids, $all_files)[0].length !== 0}
				<Button
					className="h-8 aspect-square transition-colors duration-200 !p-1.5"
					bg="bg-transparent"
					hover_bg={get_selectable_color_classes(false, {
						bg: true
					})}
					active_bg={get_selectable_color_classes(false, {
						bg: true
					})}
					click_function={(e) => {
						e.stopPropagation();
					}}
				>
					<RefreshCcwDot class="size-full" />
				</Button>
			{/if}
			<div
				class="w-14 content-center text-center select-none text-xs whitespace-nowrap"
				title={get_created_string(file.date_created, true)}
			>
				{get_created_string(file.date_created)}
			</div>
			<div
				class="h-[70%] border {get_grayed_out_border_color_strings(
					is_selected(file.id, $selected_file_ids)
				)} duration-200 transition-colors my-1"
			></div>
			<div
				class="w-12 content-center text-center select-none text-xs whitespace-nowrap truncate"
				title={file.type}
			>
				{is_folder ? 'Ordner' : (get_file_type(file)?.display_name ?? '?')}
			</div>
			<div
				class="h-[70%] border {get_grayed_out_border_color_strings(
					is_selected(file.id, $selected_file_ids)
				)} duration-200 transition-colors"
			></div>
			<div
				class="w-12 content-center text-center select-none text-xs whitespace-nowrap"
				title={get_file_size_display_string(file.size, 3)}
			>
				{get_file_size_display_string(file.size)}
			</div>
		</div>
	</div>
</div>
