<template>
	<Dialog
		v-model="show"
		:options="{
			title: '在您的站点上安装应用',
			size: '4xl'
		}"
	>
		<template #body-content>
			<ObjectList :options="listOptions" />
		</template>
	</Dialog>
</template>

<script>
import { getCachedDocumentResource, createResource } from 'jingrow-ui';
import { defineAsyncComponent, h } from 'vue';
import { toast } from 'vue-sonner';
import { renderDialog } from '../../utils/components';
import router from '../../router';
import ObjectList from '../ObjectList.vue';
import { getToastErrorMessage } from '../../utils/toast';

export default {
	props: {
		site: {
			type: String,
			required: true
		}
	},
	emits: ['installed'],
	components: {
		ObjectList
	},
	data() {
		return {
			show: true,
			installPending: false
		};
	},
	computed: {
		$site() {
			return getCachedDocumentResource('Site', this.site);
		},
		listOptions() {
			const handleInstall = async row => {
				// 防止重复点击或正在处理中
				if (this.$site.installApp.loading || this.installPending) return;
				
				// 确保有有效的app
				if (!row || !row.app) {
					toast.error('无效的应用信息');
					return;
				}
				
				// 标记为处理中，防止重复点击
				this.installPending = true;
				
				try {
					// 直接创建一个资源进行应用安装权限检查
					const checkResource = createResource({
						url: 'jcloud.api.site.check_app_installable',
						params: {
							name: this.site,
							app: row.app
						},
						auto: true
					});
					
					// 等待资源加载完成
					await new Promise(resolve => {
						const unwatch = this.$watch(
							() => !checkResource.loading,
							isNotLoading => {
								if (isNotLoading) {
									unwatch();
									resolve();
								}
							},
							{ immediate: true }
						);
					});
					
					// 获取检查结果
					const checkResult = checkResource.data;
					
					// 如果API返回错误或结果无效，取消安装
					if (!checkResult) {
						toast.error('应用安装权限验证失败，安装已取消');
						this.installPending = false;
						return;
					}
					
					// 如果应用不可安装，显示对应提示
					if (!checkResult.installable) {
						const subscriptionTypeMap = {
							2: '299元/月',
							3: '399元/月',
							4: '499元/月', 
							5: '599元/月'
						};
						
						const requiredPlan = subscriptionTypeMap[checkResult.required_plan_level] || 
							`Level ${checkResult.required_plan_level}`;
						
						toast.error(`无法安装此应用，需要${requiredPlan}或更高级别的站点计划。请先升级您的站点计划。`);
						this.installPending = false;
						return;
					}
					
					// 应用可安装，执行安装流程
					await toast.promise(
						this.$site.installApp.submit({ app: row.app })
							.then(jobId => {
								this.$emit('installed');
								this.show = false;
								return jobId;
							}),
						{
							loading: '正在创建安装任务...',
							success: () => '应用安装任务已创建',
							error: e => {
								// 尝试从错误对象中提取消息
								const errorMessage = e?.message || e?.messages?.[0] || e?.exc_info?.exception || '安装任务创建失败';
								
								// 返回用户友好的错误消息
								return typeof errorMessage === 'string' ? errorMessage : '安装任务创建失败，请稍后重试';
							}
						}
					);
					
				} catch (error) {
					toast.error('无法验证安装权限，安装已取消');
				} finally {
					// 无论成功失败，都清除处理标记
					this.installPending = false;
				}
			};
			
			return {
				label: '应用',
				fieldname: 'app',
				fieldtype: 'ListSelection',
				emptyStateMessage:
					'未找到应用' +
					(!this.$site.pg?.group_public
						? '。请从您的工作台添加它们。'
						: ''),
				columns: [
					{
						label: '标题',
						fieldname: 'title',
						class: 'font-medium',
						width: 2,
						format: (value, row) => value || row.app_title
					},
					{
						label: '仓库',
						fieldname: 'repository_owner',
						class: 'text-gray-600',
						width: '10rem'
					},
					{
						label: '版本',
						fieldname: 'branch',
						class: 'text-gray-600',
						width: '20rem'
					},
					{
						label: '',
						fieldname: '',
						align: 'right',
						type: 'Button',
						width: '5rem',
						Button: function({ row }) {
							return {
								label: '安装',
								onClick: () => handleInstall(row)
							};
						}
					}
				],
				resource: () => {
					return {
						url: 'jcloud.api.site.available_apps',
						params: {
							name: this.site
						},
						auto: true
					};
				}
			};
		}
	}
};
</script>