<template>
	<n-modal
		v-model:show="showDialog"
		preset="card"
		:title="$t('Edit Webhook')"
		:style="modalStyle"
		:mask-closable="true"
		:close-on-esc="true"
		class="edit-webhook-modal"
	>
		<template #header>
			<span class="text-lg font-semibold">{{ $t('Edit Webhook') }}</span>
		</template>
		<n-space vertical :size="20">
			<n-form-item :label="$t('Endpoint')">
				<n-input
					v-model:value="endpoint"
					:placeholder="$t('Enter webhook endpoint URL')"
					:size="inputSize"
					class="w-full"
				/>
			</n-form-item>
			<n-alert type="info" class="mb-2">
				{{ $t('If you change the endpoint, make sure to reactivate the webhook.') }}
			</n-alert>
			<div v-if="!updateSecret">
				<p class="block text-xs text-gray-600 mb-2">{{ $t('Secret Key') }}</p>
				<div class="mt-1 flex items-center justify-between text-base text-gray-700">
					<p>{{ $t('Want to change the secret key?') }}</p>
					<n-button size="small" @click="updateSecret = true">
						{{ $t('Edit Secret') }}
					</n-button>
				</div>
			</div>
			<div v-else>
				<n-form-item :label="$t('Secret Key')">
					<n-input
						v-model:value="secret"
						:placeholder="$t('Enter secret key (optional)')"
						:size="inputSize"
						class="w-full"
					>
						<template #suffix>
							<n-icon
								class="cursor-pointer text-gray-500 hover:text-gray-700"
								@click="generateRandomSecret"
							>
								<RefreshIcon />
							</n-icon>
						</template>
					</n-input>
				</n-form-item>
				<n-alert type="info" class="mb-2">
					<template #header>
						<strong>{{ $t('Note') }}:</strong>
					</template>
					{{ $t('The secret key is optional. View') }}
					<a href="https://jingrow.com/docs/webhook-introduction" class="text-primary underline" target="_blank">
						{{ $t('documentation') }}
					</a>
					{{ $t('to learn more') }}
				</n-alert>
			</div>
			<div class="mt-4">
				<p class="text-base font-medium text-gray-900 mb-4">
					{{ $t('Select Webhook Events') }}
				</p>
				<n-spin :show="$resources.events.loading">
					<n-space vertical :size="12" v-if="!$resources.events.loading">
						<div
							v-for="event in $resources.events.data"
							:key="event.name"
							class="flex items-center justify-between p-3 rounded border border-gray-200 hover:bg-gray-50"
						>
							<div class="flex-1">
								<div class="text-sm font-medium text-gray-900">
									{{ event.name }}
								</div>
								<div v-if="event.description" class="text-xs text-gray-500 mt-1">
									{{ event.description }}
								</div>
							</div>
							<n-switch
								:value="isEventSelected(event.name)"
								@update:value="selectEvent(event.name)"
								size="medium"
							/>
						</div>
					</n-space>
				</n-spin>
			</div>
			<n-alert
				v-if="errorMessage || $resources.updateWebhook.error"
				type="error"
				:title="errorMessage || $resources.updateWebhook.error"
			/>
		</n-space>
		<template #action>
			<n-space :vertical="isMobile" :size="isMobile ? 12 : 16" class="w-full">
				<n-button @click="hide" :block="isMobile" :size="buttonSize">
					{{ $t('Cancel') }}
				</n-button>
				<n-button
					type="primary"
					:loading="$resources.updateWebhook.loading"
					@click="updateWebhook"
					:block="isMobile"
					:size="buttonSize"
				>
					{{ $t('Save Changes') }}
				</n-button>
			</n-space>
		</template>
	</n-modal>
</template>

<script>
import {
	NModal,
	NFormItem,
	NInput,
	NSpace,
	NAlert,
	NButton,
	NSwitch,
	NIcon,
	NSpin,
} from 'naive-ui';
import { toast } from 'vue-sonner';
import { getToastErrorMessage } from '../../utils/toast';
import RefreshIcon from '~icons/lucide/refresh-ccw';

export default {
	components: {
		NModal,
		NFormItem,
		NInput,
		NSpace,
		NAlert,
		NButton,
		NSwitch,
		NIcon,
		NSpin,
		RefreshIcon,
	},
	emits: ['success', 'update:modelValue'],
	props: {
		webhook: {
			type: Object,
			required: true
		},
		modelValue: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			endpoint: '',
			secret: '',
			updateSecret: false,
			selectedEvents: [],
			errorMessage: '',
			windowWidth: window.innerWidth,
		};
	},
	computed: {
		showDialog: {
			get() {
				return this.modelValue;
			},
			set(value) {
				this.$emit('update:modelValue', value);
			}
		},
		isMobile() {
			return this.windowWidth <= 768;
		},
		modalStyle() {
			return {
				width: this.isMobile ? '95vw' : '800px',
				maxWidth: this.isMobile ? '95vw' : '90vw',
			};
		},
		inputSize() {
			return this.isMobile ? 'medium' : 'large';
		},
		buttonSize() {
			return this.isMobile ? 'medium' : 'medium';
		},
	},
	mounted() {
		this.handleResize();
		window.addEventListener('resize', this.handleResize);
		if (this.selectedEvents.length) {
			this.selectedEvents = this.selectedEvents.map(event => event.name);
		}
	},
	beforeUnmount() {
		window.removeEventListener('resize', this.handleResize);
	},
	methods: {
		handleResize() {
			this.windowWidth = window.innerWidth;
		},
		generateRandomSecret() {
			this.secret = Array(30)
				.fill(0)
				.map(
					() =>
						'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'[
							Math.floor(Math.random() * 62)
						]
				)
				.join('');
		},
		selectEvent(event) {
			if (this.selectedEvents.includes(event)) {
				this.selectedEvents = this.selectedEvents.filter(e => e !== event);
			} else {
				this.selectedEvents.push(event);
			}
		},
		isEventSelected(event) {
			return this.selectedEvents.includes(event);
		},
		updateWebhook() {
			if (this.selectedEvents.length === 0) {
				this.errorMessage = this.$t('Please enable at least one event');
				return;
			}
			this.errorMessage = '';
			this.$resources.updateWebhook.submit();
		},
		hide() {
			this.showDialog = false;
			this.updateSecret = false;
			this.errorMessage = '';
		}
	},
	resources: {
		events() {
			return {
				url: 'jcloud.api.webhook.available_events',
				inititalData: [],
				auto: true
			};
		},
		fetchWebhookInfo() {
			return {
				url: 'jcloud.api.client.get',
				params: {
					pagetype: 'Jcloud Webhook',
					name: this.webhook.name
				},
				auto: true,
				onSuccess: pg => {
					this.endpoint = pg.endpoint;
					this.selectedEvents = pg.events.map(event => event.event);
				}
			};
		},
		updateWebhook() {
			return {
				url: 'jcloud.api.webhook.update',
				validate: () => {
					if (!this.selectedEvents || this.selectedEvents.length === 0) {
						return this.$t('Please enable at least one event');
					}
				},
				makeParams: () => {
					return {
						name: this.webhook.name,
						endpoint: this.endpoint,
						secret: this.updateSecret ? this.secret : '',
						events: this.selectedEvents
					};
				},
				onSuccess: () => {
					toast.success(this.$t('Webhook updated successfully'));
					const activationRequired = this.webhook.endpoint !== this.endpoint;
					this.hide();
					this.$emit('success', activationRequired);
				},
				onError: e => {
					toast.error(
						getToastErrorMessage(
							e,
							this.$t('Failed to update webhook, please try again')
						)
					);
				}
			};
		}
	}
};
</script>

<style scoped>
:deep(.edit-webhook-modal .n-card) {
	width: 800px;
	max-width: 90vw;
}

:deep(.edit-webhook-modal .n-card-body) {
	padding: 24px;
}

:deep(.edit-webhook-modal .n-form-item) {
	margin-bottom: 0;
}

:deep(.edit-webhook-modal .n-input) {
	width: 100%;
}

:deep(.edit-webhook-modal .n-card__action) {
	padding: 16px 24px;
}

@media (max-width: 768px) {
	:deep(.edit-webhook-modal .n-card) {
		width: 95vw !important;
		max-width: 95vw !important;
		margin: 20px auto;
		border-radius: 12px;
	}

	:deep(.edit-webhook-modal .n-card-body) {
		padding: 20px 16px;
	}

	:deep(.edit-webhook-modal .n-card__header) {
		padding: 16px;
		font-size: 18px;
	}

	:deep(.edit-webhook-modal .n-card__action) {
		padding: 12px 16px;
	}

	:deep(.edit-webhook-modal .n-button) {
		width: 100%;
		font-size: 16px;
		height: 44px;
	}
}
</style>
