<template>
	<div>
		<div class="mt-2 space-y-2">
			<FileUploader
				v-for="file in files"
				:fileTypes="file.ext"
				:key="file.type"
				:type="file.type"
				@success="onFileUpload(file, $event)"
				:fileValidator="f => databaseBackupChecker(f, file.type)"
				:s3="true"
			>
				<template
					v-slot="{
						file: fileObj,
						uploading,
						progress,
						error,
						success,
						openFileSelector
					}"
				>
					<ListItem
						class="border-b"
						:title="fileObj ? fileObj.name : file.title"
					>
						<template #subtitle>
							<span
								class="text-base"
								:class="error ? 'text-red-500' : 'text-gray-600'"
							>
							{{
								uploading
									? $t('Uploading {progress}%', { progress })
									: success
									? formatBytes(fileObj.size)
									: error
									? error
									: file.description
							}}
							</span>
						</template>
						<template #actions>
						<Button
							:loading="uploading"
							:loadingText="$t('Uploading...')"
							@click="openFileSelector()"
							v-if="!success"
						>
							{{ $t('Upload') }}
						</Button>
							<GreenCheckIcon class="w-5" v-if="success" />
						</template>
					</ListItem>
				</template>
			</FileUploader>
		</div>
	</div>
</template>
<script>
import FileUploader from './FileUploader.vue';

export default {
	name: 'BackupFilesUploader',
	components: { FileUploader },
	emits: ['update:backupFiles'],
	props: ['backupFiles'],
	data() {
		return {
			files: [
				{
					icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.33325 9.33333V22.6667C5.33325 25.6133 10.1093 28 15.9999 28C21.8906 28 26.6666 25.6133 26.6666 22.6667V9.33333M5.33325 9.33333C5.33325 12.28 10.1093 14.6667 15.9999 14.6667C21.8906 14.6667 26.6666 12.28 26.6666 9.33333M5.33325 9.33333C5.33325 6.38667 10.1093 4 15.9999 4C21.8906 4 26.6666 6.38667 26.6666 9.33333M26.6666 16C26.6666 18.9467 21.8906 21.3333 15.9999 21.3333C10.1093 21.3333 5.33325 18.9467 5.33325 16" stroke="#1F272E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>',
					type: 'database',
					ext: 'application/x-gzip,application/sql,.sql',
					title: this.$t('Database Backup'),
					description: this.$t('Upload database backup file. Usually the filename ends with .sql.gz or .sql'),
					file: null
				},
				{
					icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.39111 6.3913H26.3476V22.2174C26.3476 25.9478 23.2955 29 19.565 29H9.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 13.1739H21.8261" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 17.6957H21.8261" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M13.9131 22.2173H19.8479" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M22.9565 6.3913V3H6V25.6087H9.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
					type: 'public',
					ext: 'application/x-tar',
					title: this.$t('Public Files'),
					description: this.$t('Upload public files backup. Usually the filename ends with -files.tar'),
					file: null
				},
				{
					icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.39111 6.3913H25.3476V22.2174C25.3476 25.9478 22.2955 29 18.565 29H8.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M21.9565 6.3913V3H5V25.6087H8.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
					type: 'private',
					ext: 'application/x-tar',
					title: this.$t('Private Files'),
					description: this.$t('Upload private files backup. Usually the filename ends with -private-files.tar'),
					file: null
				},
				{
					icon: '<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.39111 6.3913H25.3476V22.2174C25.3476 25.9478 22.2955 29 18.565 29H8.39111V6.3913Z" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/><path d="M21.9565 6.3913V3H5V25.6087H8.3913" stroke="#1F272E" stroke-width="1.5" stroke-miterlimit="10"/></svg>',
					type: 'config',
					ext: 'application/json',
					title: this.$t('Site Config (required if backup is encrypted)'),
					description: this.$t('Upload site config file. Usually the filename ends with -site_config_backup.json'),
					file: null
				}
			]
		};
	},
	methods: {
		onFileUpload(file, data) {
			let backupFiles = Object.assign({}, this.backupFiles);
			backupFiles[file.type] = data;
			this.$emit('update:backupFiles', backupFiles);
		},
		async databaseBackupChecker(file, type) {
			if (type === 'database') {
				// valid strings are "database.sql.gz", "database.sql", "database.sql (1).gz", "database.sql (2).gz"
				if (!/\.sql( \(\d\))?\.gz$|\.sql$/.test(file.name)) {
					throw new Error(
						this.$t('Database backup file should end with "database.sql.gz" or "database.sql"')
					);
				}
				if (
					![
						'application/x-gzip',
						'application/gzip',
						'application/sql'
					].includes(file.type)
				) {
					throw new Error(this.$t('Invalid database backup file'));
				}
			}
			if (['public', 'private'].includes(type)) {
				if (file.type != 'application/x-tar') {
					const fileType = type === 'public' ? this.$t('public') : this.$t('private');
					throw new Error(this.$t('Invalid {fileType} files backup file', { fileType }));
				}
			}
			if (type === 'config') {
				if (file.type != 'application/json') {
					throw new Error(this.$t('Invalid site config file'));
				}
			}
		}
	}
};
</script>
