<template>
	<div class="file-list">
		<slot name="first"></slot>
		<file-item v-for="(asset, index) in assets" :class="{select: isSelected(index)}" :editable="editable" :data="asset"
		           :key="index" @show-file-details="showFileDetails(asset)"
		           :combinable="combinable"
		           @click="onClickItem(asset, $event)"
		           @delete="onDeleteItem(asset)"
		           @combine="onCombineAssets"
		           @to-jpg="onToJpg"
		/>
		<trans-to-jpg-option-dialog ref="transToJpgOptionDialog" @confirm="onConfirmToTransJpg"/>
	</div>
</template>

<script>
	import {mapGetters, mapMutations, mapActions} from 'vuex';
	import FileItem from "./FileItem";
	import {transPngToJpg} from "../../../utils";
	import TransToJpgOptionDialog from "./TransToJpgOptionDialog";

	export default {
		name: "AssetList",
		components: {TransToJpgOptionDialog, FileItem},
		props: {
			editable: {
				type: Boolean,
				default: false,
			},
			selectable: {
				type: Boolean,
				default: true,
			},
			assetsSource: {
				type: Array,
			},
			explicitDepAssets: {
				type: Array,
			},
			implicitDepAssets: {
				type: Array,
			},
		},
		data() {
			return {
				selectedIndices: []
			}
		},
		computed: {
			selectedAssets() {
				let assets = [];
				for (let index of this.selectedIndices) {
					assets.push(this.assets[index]);
				}
				return assets;
			},
			combinable() {
				return this.selectedIndices.length > 1
			},
			assets() {
				return this.assetsSource ? this.assetsSource : this.$store.getters.assets;
			},
			...mapGetters(['assetDepFlag'])
		},
		methods: {
			showFileDetails(asset) {
				this.$emit('show-file-details', asset);
			},
			onClickItem(asset, event) {
				this.$emit('click-item', asset);
				if (!this.selectable) {
					return;
				}
				if (event.altKey) {
					if (this.isSelected(asset)) {
						this.unselectItem(asset);
					} else {
						this.selectItem(asset, false);
					}
				} else {
					this.selectItem(asset);
				}
			},
			onDeleteItem(asset) {
				if (this.isSelected(asset)) {
					this.selectItem();
					this.$emit('click-item', null);
				}
			},
			onCombineAssets(targetAsset) {
				if (this.selectedIndices.length <= 1) {
					return;
				}

				this.$confirm(this.$t('Are you sure to combine those assets?'), this.$t('Alert'), {
					showClose: false,
					closeOnClickModal: false,
					closeOnPressEscape: false,
					confirmButtonText: this.$t('Confirm'),
					cancelButtonText: this.$t('Cancel'),
					type: 'warning'
				}).then(() => {
					this.combineAssets({
						targetAsset,
						selectedAssets: this.selectedAssets
					});

					this.selectItem(targetAsset);
				}).catch((e) => {
				});
			},
			async onToJpg(asset) {
				this.lastAsset = asset;
				this.$refs.transToJpgOptionDialog.show();
			},
			async onConfirmToTransJpg(option){
				let asset = this.lastAsset;
				let blob = await transPngToJpg(asset.url, 'blob', option);
				this.replaceAsset({
					uuid: asset.uuid,
					file: new File([blob], asset.name + '.jpg'),
				});
			},
			selectItem(asset, unselectAll = true) {
				if (unselectAll) {
					this.selectedIndices.splice(0);
				}
				if (asset) {
					this.selectedIndices.push(this.assets.indexOf(asset));
				}
			},
			unselectItem(asset) {
				let sIndex = this.assets.indexOf(asset);
				this.selectedIndices.splice(this.selectedIndices.indexOf(sIndex), 1);
			},
			isSelected(item) {
				let index;
				if (typeof item === 'object') {
					index = this.assets.indexOf(item);
				} else {
					index = item;
				}
				return this.selectedIndices.includes(index);
			},
			getDepFlag(uuid) {
				let flag = -1;
				const {explicitDepAssets, implicitDepAssets} = this;
				if (explicitDepAssets || implicitDepAssets) {
					flag = explicitDepAssets.includes(uuid) ? 1 : -1;
					if (flag < 0) {
						flag = implicitDepAssets.includes(uuid) ? 2 : -1;
					}
				} else {
					flag = this.assetDepFlag(uuid);
				}
				return flag;
			},
			...mapMutations(['combineAssets']),
			...mapActions(['replaceAsset']),
		}
	}
</script>

<style scoped>

</style>