<template>
	<Dialog
		:options="{
			title: config ? '编辑配置' : '添加配置',
			actions: [
				{
					label: config ? '编辑键' : '添加键',
					variant: 'solid',
					loading: docResource?.updateConfig?.loading,
					onClick: addConfig
				}
			]
		}"
		v-model="showDialog"
	>
		<template v-slot:body-content>
			<div class="space-y-4">
				<div :class="{ 'pointer-events-none': config }">
					<FormControl
						type="autocomplete"
						label="配置名称"
						:options="keyOptions"
						v-model="selectedConfig"
					/>
				</div>
				<FormControl
					type="text"
					label="键"
					:modelValue="
						selectedConfig?.value === '__custom_key'
							? key
							: selectedConfig?.value
					"
					@update:modelValue="
						selectedConfig?.value === '__custom_key' ? (key = $event) : null
					"
					:disabled="selectedConfig?.value !== '__custom_key'"
					autocomplete="off"
				/>
				<FormControl
					type="select"
					label="类型"
					:modelValue="selectedConfig?.type || type"
					@update:modelValue="type = $event"
					:options="[
						'String',
						'Number',
						'JSON',
						'Boolean',
						selectedConfig?.value !== '__custom_key' ? 'Password' : null
					]"
					:disabled="selectedConfig?.value !== '__custom_key'"
					autocomplete="off"
				/>
				<FormControl
					v-bind="valueInputProps"
					label="值"
					v-model="value"
					autocomplete="off"
				/>
				<ErrorMessage class="mt-2" :message="error" />
			</div>
		</template>
	</Dialog>
</template>
<script>
import {
	Autocomplete,
	ErrorMessage,
	FormControl,
	getCachedDocumentResource
} from 'jingrow-ui';

export default {
	name: 'ConfigEditorDialog',
	props: ['site', 'group', 'config'],
	components: {
		Autocomplete,
		FormControl,
		ErrorMessage
	},
	data() {
		return {
			docResource: null,
			showDialog: true,
			selectedConfig: null,
			key: null,
			type: null,
			value: null,
			error: null
		};
	},
	async mounted() {
		if (this.config) {
			await this.$resources.standardKeys.promise;
			this.selectedConfig = this.keyOptions.find(
				option => this.config.key === option.value
			);
			if (this.selectedConfig) {
				this.key = this.selectedConfig?.value;
				this.type = this.selectedConfig?.type;
			} else {
				this.selectedConfig = this.keyOptions.find(
					option => '__custom_key' === option.value
				);
				this.key = this.config.key;
				this.type = this.config.type;
			}
			this.value = this.config.type === 'Password' ? '' : this.config.value;
		}
	},
	resources: {
		standardKeys() {
			return {
				url: 'jcloud.api.site.get_site_config_standard_keys',
				cache: 'Site Config Standard Keys',
				initialData: [],
				auto: true
			};
		}
	},
	methods: {
		addConfig() {
			if (this.site) {
				this.docResource = getCachedDocumentResource('Site', this.site);
			} else if (this.group) {
				this.docResource = getCachedDocumentResource(
					'Release Group',
					this.group
				);
			}
			if (!this.docResource) return;
			let key =
				this.selectedConfig?.value == '__custom_key'
					? this.key
					: this.selectedConfig?.value;
			let type = this.selectedConfig?.type || this.type;
			let value = this.value;
			if (type === 'JSON') {
				try {
					value = JSON.parse(value);
				} catch (e) {
					this.error = '无效的JSON';
					return;
				}
			} else if (type === 'Boolean') {
				value = value === '1' ? true : false;
			} else if (type === 'Number') {
				value = Number(value);
			}

			let config = { [key]: value };

			this.docResource.updateConfig.submit(
				{ config },
				{
					onSuccess: () => {
						this.$emit('success');
						this.showDialog = false;
					},
					onError: error => {
						this.error = error;
					}
				}
			);
		}
	},
	computed: {
keyOptions() {
			let customKeyOption = {
				label: '自定义键',
				value: '__custom_key'
			};
			let standardKeyOptions = this.$resources.standardKeys.data.map(key => ({
				label: key.title,
				value: key.key,
				type: key.type
			}));
			return [customKeyOption, ...standardKeyOptions];
		},
		valueInputProps() {
			let type = {
				String: 'text',
				Number: 'number',
				JSON: 'textarea',
				Boolean: 'select'
			}[this.selectedConfig?.type || this.type];

			return {
				type,
				options: type === 'select' ? ['1', '0'] : null
			};
		}
	}
};
</script>