<template>
	<recycle-scroller
		class="file-explorer-list"
		:items="items"
		:item-size="44"
		key-field="path"
	>
		<template #before>
			<div aria-hidden="true" class="spacer header"></div>
		</template>
		<template #default="{ item }">
			<t-swipe-cell :disabled="!isSwipeActionVisible(item)" :left="resolveLeftActions(item)">
				<t-cell
					class="cell"
					:title="item.name"
					:arrow="item.type === 'dir'"
					@click="handleOpen(item)"
				>
					<template #note>
						<div class="health">
							<t-loading v-if="item.path === pendingPath" size="1rem" />
							<span v-if="item.type === 'file'" v-text="item.size"></span>
						</div>
					</template>
					<template #left-icon>
						<t-icon :name="item.type === 'dir' ? 'folder' : item.icon" />
					</template>
				</t-cell>
			</t-swipe-cell>
		</template>
		<template #after>
			<div aria-hidden="true" class="spacer content"></div>
		</template>
	</recycle-scroller>
</template>

<script setup lang="ts">
import { h, resolveComponent } from "vue";
import { RecycleScroller } from "vue-virtual-scroller";
import { type ExplorerItem } from "./fileExplorer.shared";
import { isBrowserSupportedAudio } from "./fileAudio.shared";

const props = defineProps<{
	items: ExplorerItem[];
	pendingPath?: string;
}>();

const emit = defineEmits(["open", "queue", "play"]);

function isSwipeActionVisible(item: ExplorerItem): boolean {
	return isBrowserSupportedAudio(item);
}

function resolveLeftActions(item: ExplorerItem) {
	if (!isSwipeActionVisible(item)) {
		return undefined;
	}

	const buttonComponent = resolveComponent("t-button");
	const iconComponent = resolveComponent("t-icon");

	return () => h("div", { class: "actions" }, [
		h(buttonComponent, {
			class: "action-btn queue-action",
			size: "small",
			shape: "square",
			theme: "primary",
			variant: "outline",
			onClick: () => handleQueue(item)
		}, {
			icon: () => h(iconComponent, { name: "queue" })
		}),
		h(buttonComponent, {
			class: "action-btn play-action",
			size: "small",
			shape: "square",
			theme: "primary",
			onClick: () => handlePlay(item)
		}, {
			icon: () => h(iconComponent, { name: "play" })
		})
	]);
}

function handleOpen(item: ExplorerItem): void {
	if (props.pendingPath) {
		return;
	}

	emit("open", item);
}

function handleQueue(item: ExplorerItem): void {
	if (props.pendingPath) {
		return;
	}

	emit("queue", item);
}

function handlePlay(item: ExplorerItem): void {
	console.log("play", item);
	if (props.pendingPath) {
		return;
	}
	emit("play", item);
}
</script>

<style scoped lang="less">
.file-explorer-list {
	--top-gap: var(--page-top-gap, 1rem);
	--bottom-gap: 5.5rem;

	flex: 1 1 auto;
	height: 100%;
	padding: 0 1rem;
	display: flex;
	overflow: hidden;
	min-height: 0;
	flex-direction: column;

	&:deep(.vue-recycle-scroller__item-view) {

		&:first-child {

			.cell {
				border-radius: var(--td-radius-large) var(--td-radius-large) 0 0;
			}
		}

		&:last-child {

			.cell {
				border-radius: 0 0 var(--td-radius-large) var(--td-radius-large);

				&:after {
					border-bottom: 0;
				}
			}
		}
	}

	.spacer {
		width: 100%;
		pointer-events: none;

		&.header {
			height: var(--top-gap);
		}

		&.content {
			height: var(--bottom-gap);
		}
	}

	.health {
		gap: .375rem;
		display: flex;
		flex: 0 0 auto;
		min-height: 1rem;
		align-items: center;
		white-space: nowrap;
		color: var(--app-sub);
	}

	&:deep(.actions) {
		gap: .5rem;
		height: 100%;
		display: flex;
		padding: 0 .75rem;
		align-items: center;
	}

	&:deep(.queue-action) {
		background: rgba(255, 255, 255, .92);
	}

	&:deep(.play-action) {
		background: var(--td-brand-color);
	}

	&:deep(.action-btn) {
		width: 2.25rem;
		height: 2.25rem;
		border-radius: .75rem;
	}

	.cell {

		&:deep(.t-cell__content) {
			flex: 1 1 auto;
			overflow: hidden;
			min-width: 0;
		}

		&:deep(.t-cell__title) {
			flex: 1 1 auto;
			overflow: hidden;
			min-width: 0;
		}

		&:deep(.t-cell__title-text) {
			width: 100%;
			display: block;
			overflow: hidden;
			white-space: nowrap;
			text-overflow: ellipsis;
		}

		&:deep(.t-cell__note) {
			flex: 0 0 auto;
			white-space: nowrap;
		}
	}
}
</style>
