import { toast } from 'vue-sonner';
import { getTeam } from '../../data/team';
import { confirmDialog, icon, renderDialog } from '../../utils/components';
import { h } from 'vue';
import PatchAppDialog from '../../components/group/PatchAppDialog.vue';
import { ColumnField, FilterField, Tab } from './types';
import { isMobile } from '../../utils/device';

const statusTheme = {
	Applied: 'green',
	'Not Applied': 'gray',
	'In Process': 'orange',
	Failure: 'red'
};

type Status = keyof typeof statusTheme;

export function getPatchesTab(forBench: boolean) {
	return {
		label: '补丁',
		icon: icon('hash'),
		route: 'patches',
		type: 'list',
		list: {
			experimental: true, // If removing this, uncheck App Patch pagetype beta flag.
			documentation: 'https://jingrow.com/docs/benches/app-patches',
			pagetype: 'App Patch',
			filters: res => ({ [forBench ? 'bench' : 'group']: res.name }),
			searchField: 'filename',
			filterControls: r =>
				[
					{
						type: 'select',
						label: '状态',
						fieldname: 'status',
						options: ['', 'Not Applied', 'In Process', 'Failed', 'Applied']
					},
					{
						type: 'select',
						label: '应用',
						fieldname: 'app',
						class: !isMobile() ? 'w-24' : '',
						options: [
							'',
							...new Set(r.listResource.data?.map(i => String(i.app)) || [])
						]
					}
				] satisfies FilterField[],
			columns: getPatchesTabColumns(forBench),
			primaryAction({ listResource: apps, documentResource: pg }) {
				return {
					label: '应用补丁',
					slots: {
						prefix: icon('plus')
					},
					onClick() {
						const group = pg.pagetype === 'Bench' ? pg.pg.group : pg.name;

						renderDialog(h(PatchAppDialog, { group: group, app: '' }));
					}
				};
			},
			rowActions({ row, listResource }) {
				let team = getTeam();
				return [
					{
						label: '在桌面查看',
						condition: () => team.pg?.is_desk_user,
						onClick() {
							window.open(
								`${window.location.protocol}//${window.location.host}/app/app-patch/${row.name}`,
								'_blank'
							);
						}
					},
					{
						label: '应用补丁',
						condition: () => row.status !== 'In Process',
						onClick: () => {
							toast.promise(
								listResource.runDocMethod.submit({
									method: 'apply_patch',
									name: String(row.name)
								}),
								{
									loading: '正在创建应用补丁的任务',
									success: () => '补丁应用正在进行中',
									error: () => '应用补丁失败'
								}
							);
						}
					},
					{
						label: '回滚补丁',
						condition: () => row.status !== 'In Process',
						onClick: () => {
							toast.promise(
								listResource.runDocMethod.submit({
									method: 'revert_patch',
									name: String(row.name)
								}),
								{
									loading: '正在创建回滚补丁的任务',
									success: () => '补丁回滚正在进行中',
									error: () => '回滚补丁失败'
								}
							);
						}
					},
					{
						label: '删除',
						condition: () => row.status === 'Not Applied',
						onClick: () => {
							confirmDialog({
								title: '删除补丁',
								message: '确定要删除此补丁吗？',
								onSuccess: ({ hide }) => {
									toast.promise(
										listResource.delete.submit(row.name, {
											onSuccess: () => hide()
										}),
										{
											loading: '正在删除...',
											success: () => '补丁已删除',
											error: () => '删除补丁失败'
										}
									);
								}
							});
						}
					}
				];
			}
		}
	} satisfies Tab;
}

function getPatchesTabColumns(forBench: boolean) {
	const columns: ColumnField[] = [
		{
			label: '文件名',
			fieldname: 'filename',
			width: forBench ? '400px' : '300px'
		},
		{
			label: '应用',
			fieldname: 'app',
			width: 0.4
		},
		{
			label: '状态',
			type: 'Badge',
			fieldname: 'status',
			theme: value => statusTheme[value as Status],
			width: 0.4
		},
		{
			label: '工作台',
			fieldname: 'bench',
			width: 0.8
		},
		{
			label: '补丁链接',
			fieldname: 'url',
			width: forBench ? undefined : '300px',
			format(value) {
				if (!value) {
					return '-';
				}

				const url = new URL(value);
				return url.hostname + url.pathname;
			},
			link: value => String(value)
		}
	];

	if (forBench) return columns.filter(f => f.fieldname !== 'bench');
	return columns;
}