<template>
	<div class="p-5" v-if="job">
		<AlertAddressableError
			v-if="error"
			class="mb-5"
			:name="error.name"
			:title="error.title"
			@done="$resources.errors.reload()"
		/>
		<Button
			:route="{
				name:
					object.pagetype === 'Site'
						? '站点任务'
						: `${object.pagetype} 详情任务`,
			}"
		>
			<template #prefix>
				<i-lucide-arrow-left class="inline-block h-4 w-4" />
			</template>
			所有任务
		</Button>

		<div class="mt-3">
			<div>
				<div class="flex items-center">
					<h2 class="text-lg font-medium text-gray-900">{{ job.job_type }}</h2>
					<Badge class="ml-2" :label="job.status" />
					<div class="ml-auto flex items-center space-x-2">
						<Button
							@click="$resources.job.reload()"
							:loading="$resources.job.get.loading"
						>
							<template #icon>
								<i-lucide-refresh-ccw class="h-4 w-4" />
							</template>
						</Button>
						<Dropdown v-if="dropdownOptions.length" :options="dropdownOptions">
							<template v-slot="{ open }">
								<Button>
									<template #icon>
										<i-lucide-more-horizontal class="h-4 w-4" />
									</template>
								</Button>
							</template>
						</Dropdown>
					</div>
				</div>
				<div>
					<div
						class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-5"
					>
						<div>
							<div class="text-sm font-medium text-gray-500">创建时间</div>
							<div class="mt-2 text-sm text-gray-900">
								{{ $format.date(job.creation, 'lll') }}
							</div>
						</div>
						<div>
							<div class="text-sm font-medium text-gray-500">创建者</div>
							<div class="mt-2 text-sm text-gray-900">
								{{ job.owner }}
							</div>
						</div>
						<div>
							<div class="text-sm font-medium text-gray-500">持续时间</div>
							<div class="mt-2 text-sm text-gray-900">
								{{ job.end ? $format.duration(job.duration) : '-' }}
							</div>
						</div>
						<div>
							<div class="text-sm font-medium text-gray-500">开始时间</div>
							<div class="mt-2 text-sm text-gray-900">
								{{ $format.date(job.start, 'lll') }}
							</div>
						</div>
						<div>
							<div class="text-sm font-medium text-gray-500">结束时间</div>
							<div class="mt-2 text-sm text-gray-900">
								{{ job.end ? $format.date(job.end, 'lll') : '-' }}
							</div>
						</div>
					</div>
				</div>
			</div>

			<div class="mt-8 space-y-4">
				<JobStep v-for="step in job.steps" :step="step" :key="step.name" />
			</div>
		</div>
	</div>
</template>
<script>
import { FeatherIcon, Tooltip } from 'jingrow-ui';
import AlertAddressableError from '../components/AlertAddressableError.vue';
import { duration } from '../utils/format';
import { getObject } from '../objects';
import JobStep from '../components/JobStep.vue';

export default {
	name: 'JobPage',
	props: ['id', 'objectType'],
	components: { Tooltip, FeatherIcon, JobStep, AlertAddressableError },
	resources: {
		job() {
			return {
				type: 'document',
				pagetype: 'Agent Job',
				name: this.id,
				transform(job) {
					for (let step of job.steps) {
						step.title = step.step_name;
						step.duration = duration(step.duration);
						step.isOpen =
							this.job?.steps?.find((s) => s.name === step.name)?.isOpen ||
							false;
					}

					// 在交付失败时，任何步骤都不会有输出
					// 所以在第一个步骤中显示任务输出（错误）
					if (job.status === 'Delivery Failure') {
						job.steps[0].output = job.output;
					}

					return job;
},
				onSuccess() {
					this.lastLoaded = Date.now();
				},
			};
		},
		errors() {
			return {
				type: 'list',
				cache: ['通知', '错误', '代理任务', this.id],
				pagetype: 'Jcloud Notification',
				auto: true,
				fields: ['标题', '名称'],
				filters: {
					document_type: '代理任务',
					document_name: this.id,
					is_actionable: true,
					class: '错误',
				},
				limit: 1,
				orderBy: '创建时间 desc',
			};
		},
	},
	computed: {
		object() {
			return getObject(this.objectType);
		},
		job() {
			return this.$resources.job.pg;
		},
		error() {
			return this.$resources.errors?.data?.[0] ?? null;
		},
		dropdownOptions() {
			return [
				{
					label: '在桌面查看',
					icon: 'external-link',
					condition: () => this.$team?.pg?.is_desk_user,
					onClick: () => {
						window.open(
							`${window.location.protocol}//${window.location.host}/app/agent-job/${this.id}`,
							'_blank',
						);
					},
				},
			].filter((option) => option.condition?.() ?? true);
		},
	},
	mounted() {
		this.$socket.emit('pg_subscribe', '代理任务', this.id);
		this.$socket.on('agent_job_update', (data) => {
			if (data.id === this.id) {
				data.steps = data.steps.map((step) => {
					step.title = step.step_name;
					step.duration = duration(step.duration);
					step.isOpen =
						this.job?.steps?.find((s) => s.name === step.name)?.isOpen || false;
					return step;
				});

				this.$resources.job.pg = {
					...this.$resources.job.pg,
					...data,
				};
			}
		});
		// 每分钟重新加载任务，以防套接字无法工作
		this.reloadInterval = setInterval(() => {
			this.reload();
		}, 1000 * 60);
	},
	beforeUnmount() {
		this.$socket.emit('pg_unsubscribe', '代理任务', this.id);
		this.$socket.off('agent_job_update');
		clearInterval(this.reloadInterval);
	},
	methods: {
		reload() {
			if (
				!this.$resources.job.loading &&
				// 如果任务加载时间超过5秒，则重新加载
				Date.now() - this.lastLoaded > 5000
			) {
				this.$resources.job.reload();
			}
		},
	},
};
</script>