import { defineAsyncComponent, h } from 'vue';
import { toast } from 'vue-sonner';
import { getTeam } from '../../data/team';
import router from '../../router';
import { confirmDialog, icon, renderDialog } from '../../utils/components';
import { planTitle } from '../../utils/format';
import type {
	ColumnField,
	DialogConfig,
	FilterField,
	Tab,
	TabList
} from './types';
import { getUpsellBanner } from '.';
import { isMobile } from '../../utils/device';
import { getToastErrorMessage } from '../../utils/toast';

export function getAppsTab(forSite: boolean) {
	return {
		label: '应用',
		icon: icon('grid'),
		route: 'apps',
		type: 'list',
		condition: docResource => forSite && docResource.pg?.status !== 'Archived',
		list: getAppsTabList(forSite)
	} satisfies Tab as Tab;
}

function getAppsTabList(forSite: boolean) {
	const options = forSite ? siteAppListOptions : benchAppListOptions;
	const list: TabList = {
		pagetype: '',
		filters: () => ({}),
		...options,
		columns: getAppsTabColumns(forSite),
		searchField: !forSite ? 'title' : undefined,
		filterControls: r => {
			if (forSite) return [];
			else
				return [
					{
						type: 'select',
						label: '分支',
						class: !isMobile() ? 'w-24' : '',
						fieldname: 'branch',
						options: [
							'',
							...new Set(r.listResource.data?.map(i => String(i.branch)) || [])
						]
					},
					{
						type: 'select',
						label: '所有者',
						class: !isMobile() ? 'w-24' : '',
						fieldname: 'repository_owner',
						options: [
							'',
							...new Set(
								r.listResource.data?.map(
									i => String(i.repository_url).split('/').at(-2) || ''
								) || []
							)
						]
					}
				] satisfies FilterField[];
		}
	};

	return list;
}

function getAppsTabColumns(forSite: boolean) {
	const appTabColumns: ColumnField[] = [
		{
			label: '应用',
			fieldname: 'title',
			width: 1,
			suffix(row) {
				if (!row.is_app_patched) {
					return;
				}

				return h(
					'div',
					{
						title: '应用已打补丁',
						class: 'rounded-full bg-gray-100 p-1'
					},
					h(icon('hash', 'w-3 h-3'))
				);
			},
			format: (value, row) => value || row.app_title
		},
		{
			label: '计划',
			width: 0.75,
			class: 'text-gray-600 text-sm',
			format(_, row) {
				const planText = planTitle(row.plan_info);
				if (planText) return `${planText}/月`;
				else return '免费';
			}
		},
		{
			label: '版本',
			fieldname: 'branch',
			type: 'Badge',
			width: 1,
		}
	];

	// 为站点应用添加操作列，包含卸载按钮
	if (forSite) {
		appTabColumns.push({
			label: '操作',
			width: 0.75,
			align: 'right',
			type: 'Button',
			Button: ({ row, listResource, documentResource }) => {
				// 如果是 jingrow 应用，不显示卸载按钮
				if (row.app === 'jingrow') {
					return null;
				}

				return {
					label: '卸载',
					variant: 'ghost',
					class: 'text-red-600 hover:text-red-700 hover:bg-red-50',
					slots: {
						prefix: icon('trash-2')
					},
					onClick: () => {
						const appName = row.title || row.app_title;
						const dialogConfig: DialogConfig = {
							title: `卸载应用`,
							message: `您确定要从站点 <b>${documentResource.pg?.name}</b> 卸载应用 <b>${appName}</b> 吗？<br>
											所有与此应用相关的页面类型和模块将被移除。`,
							onSuccess({ hide }) {
								// 立即从列表中移除该应用（乐观更新）
								const currentData = listResource.data || [];
								const updatedData = currentData.filter(item => item.name !== row.name);
								listResource.data = updatedData;
								
								const promise = documentResource.uninstallApp.submit({
									app: row.app
								});
								
								toast.promise(promise, {
									loading: '正在安排应用卸载...',
									success: (jobId: string) => {
										hide();
										return '应用卸载已安排';
									},
									error: (e: Error) => {
										// 如果失败，重新加载列表恢复状态
										listResource.reload();
										return getToastErrorMessage(e);
									}
								});
							}
						};
						confirmDialog(dialogConfig);
					}
				};
			}
		});
		
		return appTabColumns;
	}
	
	return appTabColumns.filter(c => c.label !== '计划');
}

const siteAppListOptions: Partial<TabList> = {
	pagetype: 'Site App',
	filters: res => {
		return { parenttype: 'Site', parent: res.pg?.name };
	},
	primaryAction({ listResource: apps, documentResource: site }) {
		return {
			label: '安装应用',
			slots: {
				prefix: icon('plus')
			},
			onClick() {
				const InstallAppDialog = defineAsyncComponent(
					() => import('../../components/site/InstallAppDialog.vue')
				);

				renderDialog(
					h(InstallAppDialog, {
						site: site.name,
						onInstalled() {
							apps.reload();
						}
					})
				);
			}
		};
	},
	rowActions({ row, listResource: apps, documentResource: site }) {
		let $team = getTeam();

		return [
			{
				label: '在 Desk 中查看',
				condition: () => $team.pg?.is_desk_user,
				onClick() {
					window.open(`/app/app-source/${row.name}`, '_blank');
				}
			},
			{
				label: '更改计划',
				condition: () => row.plan_info && row.plans.length > 1,
				onClick() {
					let SiteAppPlanChangeDialog = defineAsyncComponent(
						() => import('../../components/site/SiteAppPlanSelectDialog.vue')
					);
					renderDialog(
						h(SiteAppPlanChangeDialog, {
							app: row,
							currentPlan: row.plans.find(
								(plan: Record<string, any>) => plan.name === row.plan_info.name
							),
							onPlanChanged() {
								apps.reload();
							}
						})
					);
				}
			},
			{
				label: '卸载',
				condition: () => row.app !== 'jingrow',
				onClick() {
					const appName = row.title || row.app_title;
					const dialogConfig: DialogConfig = {
						title: `卸载应用`,
						message: `您确定要从站点 <b>${site.pg?.name}</b> 卸载应用 <b>${appName}</b> 吗？<br>
										所有与此应用相关的页面类型和模块将被移除。`,
						onSuccess({ hide }) {
							toast.promise(
								site.uninstallApp.submit({
									app: row.app
								}),
								{
									loading: '正在安排应用卸载...',
									success: (jobId: string) => {
										hide();
										apps.reload();
										return '应用卸载已安排';
									},
									error: (e: Error) => {
										return getToastErrorMessage(e);
									}
								}
							);
						}
					};
					confirmDialog(dialogConfig);
				}
			}
		];
	}
};

const benchAppListOptions: Partial<TabList> = {
	pagetype: 'Bench App',
	filters: res => {
		return { parenttype: 'Bench', parent: res.pg?.name };
	},
	rowActions({ row }) {
		let $team = getTeam();
		return [
			{
				label: '在 Desk 中查看',
				condition: () => $team.pg?.is_desk_user,
				onClick() {
					window.open(`/app/app-release/${row.release}`, '_blank');
				}
			}
		];
	}
};