import { defineAsyncComponent, h } from 'vue';
import LucideAppWindow from '~icons/lucide/app-window';
import ServerActions from '../components/server/ServerActions.vue';
import { getTeam } from '../data/team';
import router from '../router';
import { icon } from '../utils/components';
import { duration, planTitle, userCurrency } from '../utils/format';
import { trialDays } from '../utils/site';
import { getJobsTab } from './common/jobs';
import { tagTab } from './common/tags';
import { t } from '../utils/i18n';

export default {
	pagetype: 'Server',
	whitelistedMethods: {
		increaseDiskSize: 'increase_disk_size_for_server',
		configureAutoAddStorage: 'configure_auto_add_storage',
		changePlan: 'change_plan',
		reboot: 'reboot',
		rename: 'rename',
		dropServer: 'drop_server',
		addTag: 'add_resource_tag',
		removeTag: 'remove_resource_tag'
	},
	list: {
		route: '/servers',
		title: t('Servers'),
		fields: [
			'title',
			'database_server',
			'plan.title as plan_title',
			'plan.price_usd as price_usd',
			'plan.price_cny as price_cny',
			'cluster.image as cluster_image',
			'cluster.title as cluster_title'
		],
		filterControls() {
			return [
				{
					type: 'select',
					label: t('Status'),
					fieldname: 'status',
					options: [
						{ label: '', value: '' },
						{ label: t('Active'), value: 'Active' },
						{ label: t('Pending'), value: 'Pending' }
					]
				},
				{
					type: 'select',
					label: t('Region'),
					fieldname: 'cluster',
					options: [
						'',
						t('China'),
						t('Hong Kong'),
						t('US - Los Angeles'),
						t('Singapore'),
						t('UK - London'),
						t('Germany - Frankfurt'),
						t('UAE - Dubai'),
					]
				}
			];
		},
		orderBy: 'creation desc',
		columns: [
			{
				label: t('Servers'),
				fieldname: 'name',
				width: 1.5,
				class: 'font-medium',
				format(value, row) {
					return row.title || value;
				}
			},
			{ label: t('Status'), fieldname: 'status', type: 'Badge', width: 0.8 },
			{
				label: t('Application Server Plan'),
				format(value, row) {
					return planTitle(row);
				}
			},
			{
				label: t('Database Server Plan'),
				fieldname: 'db_plan',
				format(value) {
					if (!value) return '';
					return planTitle(value);
				}
			},
			{
				label: t('Region'),
				fieldname: 'cluster',
				format(value, row) {
					return row.cluster_title || value;
				},
				prefix(row) {
					return h('img', {
						src: row.cluster_image,
						class: 'w-4 h-4',
						alt: row.cluster_title
					});
				}
			}
		],
		primaryAction({ listResource: servers }) {
			return {
				label: t('New Server'),
				variant: 'outline',
				slots: {
					prefix: icon('plus')
				},
				onClick() {
					router.push({ name: 'New Server' });
				}
			};
		}
	},
	detail: {
		titleField: 'name',
		route: '/servers/:name',
		statusBadge({ documentResource: server }) {
			return {
				label: server.pg.status
			};
		},
		breadcrumbs({ documentResource: server }) {
			return [
				{
					label: t('Servers'),
					route: '/servers'
				},
				{
					label: server.pg.title || server.pg.name,
					route: `/servers/${server.pg.name}`
				}
			];
		},
		actions({ documentResource: server }) {
			let $team = getTeam();

			return [
				{
					label: t('Impersonate Server Owner'),
					title: t('Impersonate Server Owner'), // for label to pop-up on hover
					slots: {
						icon: defineAsyncComponent(() =>
							import('~icons/lucide/venetian-mask')
						)
					},
					condition: () =>
						$team.pg?.is_desk_user && server.pg.team !== $team.name,
					onClick() {
						switchToTeam(server.pg.team);
					}
				},
				{
					label: t('Options'),
					button: {
						label: t('Options'),
						slots: {
							icon: icon('more-horizontal')
						}
					},
					options: [
						{
							label: t('View in Desk'),
							icon: icon('external-link'),
							condition: () => $team.pg?.is_desk_user,
							onClick() {
								window.open(
									`${window.location.protocol}//${
										window.location.host
									}/app/${server.pagetype.replace(' ', '-').toLowerCase()}/${
										server.pg.name
									}`,
									'_blank'
								);
							}
						},
						{
							label: t('Access Server'),
							icon: icon('external-link'),
							condition: () =>
								server.pg.status === 'Active' && $team.pg?.is_desk_user,
							onClick() {
								window.open(`https://${server.pg.name}`, '_blank');
							}
						}
					]
				}
			];
		},
		tabs: [
			{
				label: t('Overview'),
				icon: icon('home'),
				route: 'overview',
				type: 'Component',
				component: defineAsyncComponent(() =>
					import('../components/server/ServerOverview.vue')
				),
				props: server => {
					return { server: server.pg.name };
				}
			},
			{
				label: t('Analytics'),
				icon: icon('bar-chart-2'),
				route: 'analytics',
				type: 'Component',
				component: defineAsyncComponent(() =>
					import('../components/server/ServerCharts.vue')
				),
				props: server => {
					return {
						serverName: server.pg.name
					};
				}
			},
			{
				label: t('Sites'),
				icon: icon(LucideAppWindow),
				route: 'sites',
				type: 'list',
				list: {
					pagetype: 'Site',
					filters: server => {
						return { server: server.pg.name };
					},
					fields: [
						'plan.plan_title as plan_title',
						'plan.price_usd as price_usd',
						'plan.price_cny as price_cny',
						'group.title as group_title',
						'group.public as group_public',
						'group.team as group_team',
						'group.version as version',
						'trial_end_date'
					],
					orderBy: 'creation desc',
					searchField: 'host_name',
					route(row) {
						return { name: 'Site Detail', params: { name: row.name } };
					},
					filterControls() {
						return [
							{
								type: 'select',
								label: t('Status'),
								fieldname: 'status',
								options: [
									{ label: '', value: '' },
									{ label: t('Active'), value: 'Active' },
									{ label: t('Inactive'), value: 'Inactive' },
									{ label: t('Suspended'), value: 'Suspended' },
									{ label: t('Broken'), value: 'Broken' }
								]
							},
							{
								type: 'link',
								label: t('Version'),
								fieldname: 'group.version',
								options: {
									pagetype: 'Jingrow Version'
								}
							},
							{
								type: 'link',
								label: t('Release Group'),
								fieldname: 'group',
								options: {
									pagetype: 'Release Group'
								}
							},
							{
								type: 'link',
								label: t('Tag'),
								fieldname: 'tags.tag',
								options: {
									pagetype: 'Jcloud Tag',
									filters: {
										pagetype_name: 'Site'
									}
								}
							}
						];
					},
					columns: [
						{
							label: t('Sites'),
							fieldname: 'host_name',
							width: 1.5,
							class: 'font-medium',
							format(value, row) {
								return value || row.name;
							}
						},
						{ label: t('Status'), fieldname: 'status', type: 'Badge', width: 0.6 },
						{
							label: t('Plan Type'),
							fieldname: 'plan',
							width: 0.85,
							format(value, row) {
								if (row.trial_end_date) {
									return trialDays(row.trial_end_date);
								}
								let $team = getTeam();
								if (row.price_usd > 0) {
									let china = $team.pg.country == 'china';
									let formattedValue = userCurrency(
										china ? row.price_cny : row.price_usd,
										0
									);
									return `${formattedValue}/${t('Monthly')}`;
								}
								return row.plan_title;
							}
						},
						{
							label: t('Release Group'),
							fieldname: 'group_title',
							width: '15rem'
						},
						{
							label: t('Version'),
							fieldname: 'version',
							width: 0.5
						}
					]
				}
			},
			{
				label: t('Release Group'),
				icon: icon('package'),
				route: 'groups',
				type: 'list',
				list: {
					pagetype: 'Release Group',
					filters: server => {
						return { server: server.pg.name };
					},
					fields: [{ apps: ['app'] }, { servers: ['server'] }],
					columns: [
						{ label: t('Title'), fieldname: 'title' },
						{
							label: t('Status'),
							fieldname: 'active_benches',
							type: 'Badge',
							width: 0.5,
							format: (value, row) => {
								if (!value) return t('Waiting for Deployment');
								else return t('Active');
							}
						},
						{
							label: t('Version'),
							fieldname: 'version',
							width: 0.5
						},
						{
							label: t('App'),
							fieldname: 'app',
							format: (value, row) => {
								return (row.apps || []).map(d => d.app).join(', ');
							},
							width: '25rem'
						},
						{
							label: t('Sites'),
							fieldname: 'site_count',
							width: 0.25
						}
					],
					filterControls() {
						return [
							{
								type: 'link',
								label: t('Version'),
								fieldname: 'version',
								options: {
									pagetype: 'Jingrow Version'
								}
							},
							{
								type: 'link',
								label: t('Tag'),
								fieldname: 'tags.tag',
								options: {
									pagetype: 'Jcloud Tag',
									filters: {
										pagetype_name: 'Release Group'
									}
								}
							}
						];
					},
					route(row) {
						return {
							name: 'Release Group Detail',
							params: { name: row.name }
						};
					},
					primaryAction({ listResource: benches, documentResource: server }) {
						return {
							label: t('New Release Group'),
							slots: {
								prefix: icon('plus')
							},
							onClick() {
								router.push({
									name: 'Server New Release Group',
									params: { server: server.pg.name }
								});
							}
						};
					}
				}
			},
			getJobsTab('Server'),
			{
				label: t('Execute'),
				icon: icon('play'),
				childrenRoutes: ['Server Play'],
				route: 'plays',
				type: 'list',
				list: {
					pagetype: 'Ansible Play',
					filterControls({ documentResource: server }) {
						return [
							{
								type: 'select',
								label: t('Servers'),
								fieldname: 'server',
								options: [
									server.pg.name,
									server.pg.database_server,
									server.pg.replication_server
								].filter(Boolean)
							}
						];
					},
					filters: server => {
						return {
							server: [
								'in',
								[
									server.pg.name,
									server.pg.database_server,
									server.pg.replication_server
								].filter(Boolean)
							]
						};
					},
					route(row) {
						return {
							name: 'Server Play',
							params: { id: row.name }
						};
					},
					orderBy: 'creation desc',
					fields: ['server', 'end'],
					columns: [
						{
							label: t('Execute'),
							fieldname: 'play',
							width: 2
						},
						{
							label: t('Status'),
							fieldname: 'status',
							type: 'Badge',
							width: 0.5
						},
						{
							label: t('Servers'),
							fieldname: 'server',
							width: 2
						},
						{
							label: t('Duration'),
							fieldname: 'duration',
							width: 0.5,
							format(value, row) {
								if (row.job_id === 0 || !row.end) return;
								return duration(value);
							}
						},
						{
							label: '',
							fieldname: 'creation',
							type: 'Timestamp',
							align: 'right'
						}
					]
				}
			},
			{
				label: t('Actions'),
				icon: icon('sliders'),
				route: 'actions',
				type: 'Component',
				component: ServerActions,
				props: server => {
					return { server: server.pg.name };
				}
			},
			tagTab()
		]
	},
	routes: [
		{
			name: 'Server Job',
			path: 'jobs/:id',
			component: () => import('../pages/JobPage.vue')
		},
		{
			name: 'Server Play',
			path: 'plays/:id',
component: () => import('../pages/PlayPage.vue')
		}
	]
};