<template>
	<view class="fe-bottom-sheet fe-bottom-sheet--task-publish" :class="{ 'fe-bottom-sheet--active': active }">
		<view class="fe-sheet-handle" />
		<view class="fe-sheet-header">
			<view class="fe-sheet-title">✈ 任务发布</view>
			<view class="fe-sheet-close" @tap="onClose">✕</view>
		</view>
		<view v-if="sourceTitle" class="fe-sheet-source tp-source">🔗 {{ sourceTitle }}</view>

		<view v-if="loading" class="tp-empty">
			<text class="tp-empty__text">加载任务信息中...</text>
		</view>
		<view v-else-if="loadError" class="tp-empty">
			<text class="tp-empty__text">{{ loadError }}</text>
			<view class="fe-btn fe-btn--primary fe-btn--sm" @tap="loadData">重试</view>
		</view>
		<template v-else>
			<scroll-view scroll-y class="fe-sheet-body tp-body" :show-scrollbar="false">
				<view class="fe-sheet-body__inner">
					<view class="tp-hero">
						<view class="tp-hero__icon">
							<text class="tp-hero__icon-text">✈</text>
						</view>
						<text class="tp-hero__title">{{ heroTitle }}</text>
						<text class="tp-hero__desc">{{ statusDesc }}</text>
					</view>

					<!-- 任务信息：按工种多组 -->
					<view class="tp-section">
						<text class="tp-section__title">任务信息</text>
						<view
							v-for="(g, gi) in groups"
							:key="g.rowKey"
							class="tp-card"
						>
							<text v-if="groups.length > 1" class="tp-card__badge">工种 {{ gi + 1 }} · {{ g.workType }}</text>
							<view class="tp-grid">
								<view class="tp-grid__cell">
									<text class="tp-grid__label">岗位类型</text>
									<text class="tp-grid__value">{{ g.workType || '—' }}</text>
								</view>
								<view class="tp-grid__cell">
									<text class="tp-grid__label">用工人数</text>
									<text class="tp-grid__value">{{ g.workerCountText }}</text>
								</view>
								<view class="tp-grid__cell">
									<text class="tp-grid__label">工作地点</text>
									<text class="tp-grid__value">{{ g.workLocation || '—' }}</text>
								</view>
								<view class="tp-grid__cell">
									<text class="tp-grid__label">{{ g.durationLabel }}</text>
									<text class="tp-grid__value">{{ g.durationText }}</text>
								</view>
							</view>
						</view>
						<view v-if="!groups.length" class="tp-card">
							<text class="tp-empty__text">暂无工种信息</text>
						</view>
					</view>

					<!-- 工作时间：按工种多组 -->
					<view class="tp-section">
						<text class="tp-section__title">工作时间</text>
						<view
							v-for="(g, gi) in groups"
							:key="g.timeKey"
							class="tp-card"
						>
							<text v-if="groups.length > 1" class="tp-card__badge">{{ g.workType || ('工种 ' + (gi + 1)) }}</text>
							<view class="tp-field">
								<text class="tp-field__label">开始时间 <text v-if="!readonly" class="tp-required">*</text></text>
								<view class="tp-datetime-row">
									<picker
										v-if="!readonly"
										class="tp-datetime-row__item"
										mode="date"
										:value="g.startDate"
										@change="onStartDateByIndex(gi, $event)"
									>
										<view class="tp-input" :class="{ 'tp-input--placeholder': !g.startDate }">
											<text class="tp-input__icon">📅</text>
											<text class="tp-input__text">{{ g.startDateDisplay }}</text>
										</view>
									</picker>
									<view v-else class="tp-datetime-row__item">
										<view class="tp-input tp-input--readonly">
											<text class="tp-input__icon">📅</text>
											<text class="tp-input__text">{{ g.startDateDisplay }}</text>
										</view>
									</view>
									<picker
										v-if="!readonly"
										class="tp-datetime-row__item"
										mode="time"
										:value="g.startTime || '08:00'"
										@change="onStartTimeByIndex(gi, $event)"
									>
										<view class="tp-input" :class="{ 'tp-input--placeholder': !g.startTime }">
											<text class="tp-input__icon">⏱</text>
											<text class="tp-input__text">{{ g.startTimeDisplay }}</text>
										</view>
									</picker>
									<view v-else class="tp-datetime-row__item">
										<view class="tp-input tp-input--readonly">
											<text class="tp-input__icon">⏱</text>
											<text class="tp-input__text">{{ g.startTimeDisplay }}</text>
										</view>
									</view>
								</view>
							</view>
							<view class="tp-field">
								<text class="tp-field__label">结束时间 <text v-if="!readonly" class="tp-required">*</text></text>
								<view class="tp-datetime-row">
									<picker
										v-if="!readonly"
										class="tp-datetime-row__item"
										mode="date"
										:value="g.endDate"
										@change="onEndDateByIndex(gi, $event)"
									>
										<view class="tp-input" :class="{ 'tp-input--placeholder': !g.endDate }">
											<text class="tp-input__icon">📅</text>
											<text class="tp-input__text">{{ g.endDateDisplay }}</text>
										</view>
									</picker>
									<view v-else class="tp-datetime-row__item">
										<view class="tp-input tp-input--readonly">
											<text class="tp-input__icon">📅</text>
											<text class="tp-input__text">{{ g.endDateDisplay }}</text>
										</view>
									</view>
									<picker
										v-if="!readonly"
										class="tp-datetime-row__item"
										mode="time"
										:value="g.endTime || '18:00'"
										@change="onEndTimeByIndex(gi, $event)"
									>
										<view class="tp-input" :class="{ 'tp-input--placeholder': !g.endTime }">
											<text class="tp-input__icon">⏱</text>
											<text class="tp-input__text">{{ g.endTimeDisplay }}</text>
										</view>
									</picker>
									<view v-else class="tp-datetime-row__item">
										<view class="tp-input tp-input--readonly">
											<text class="tp-input__icon">⏱</text>
											<text class="tp-input__text">{{ g.endTimeDisplay }}</text>
										</view>
									</view>
								</view>
							</view>
						</view>
					</view>

					<view v-if="readonly" class="tp-gate-tip tp-gate-tip--ok">
						<text class="tp-gate-tip__text tp-gate-tip__text--ok">任务已发布，当前仅可查看</text>
					</view>
					<view v-else-if="!canPublish" class="tp-gate-tip">
						<text class="tp-gate-tip__text">{{ gateTip }}</text>
					</view>
					<view v-else-if="!scheduleComplete" class="tp-gate-tip">
						<text class="tp-gate-tip__text">请为每个工种选择开始/结束的日期与时间</text>
					</view>
				</view>
			</scroll-view>

			<view class="fe-sheet-footer">
				<template v-if="readonly">
					<view class="fe-btn fe-btn--primary fe-btn--lg fe-btn--full" @tap="onClose">关闭</view>
				</template>
				<template v-else>
					<view class="fe-btn fe-btn--secondary fe-btn--lg" @tap="onClose">取消</view>
					<view
						v-if="confirmDisabled"
						class="fe-btn fe-btn--primary fe-btn--lg fe-btn--disabled-look"
					>{{ confirmLabel }}</view>
					<view
						v-else
						class="fe-btn fe-btn--primary fe-btn--lg"
						@tap="onConfirm"
					>{{ confirmLabel }}</view>
				</template>
			</view>
		</template>
	</view>
</template>

<script>
import store from '@/common/store.js'
import { showToast } from '@/common/chat-data.js'
import { getDraftDetail, getDraftWorkflowProgress } from '@/api/draft.js'
import { getOrderPublishTask, publishOrderTask } from '@/api/order.js'
import {
	normalizeWorkerGroups,
	formatWorkDurationUnit,
	splitDateTimeParts,
	formatDateTimeDisplay,
	normalizeDateYmd,
	mapDraftDetailToCard
} from '@/utils/draft.js'
import { isStaffingStep, isEnterpriseCertSkipped } from '@/utils/process-card.js'
import { mapRegistrationBatchDetail } from '@/utils/registration-batch.js'

/** 规范化 HH:mm */
function normalizeTimeHm(timeStr) {
	if (timeStr == null || timeStr === '') return ''
	const m = String(timeStr).trim().match(/^(\d{1,2}):(\d{2})/)
	if (!m) return ''
	const hh = String(Math.min(23, Math.max(0, Number(m[1])))).padStart(2, '0')
	return `${hh}:${m[2]}`
}

/** 拼成接口常用日期时间：YYYY-MM-DD HH:mm:ss（日期、时间均必填） */
function joinDateTimePayload(dateStr, timeStr) {
	const d = normalizeDateYmd(dateStr)
	const t = normalizeTimeHm(timeStr)
	if (!d || !t) return ''
	return `${d} ${t}:00`
}

function pad2(n) {
	return String(n).padStart(2, '0')
}

function formatLocalYmd(d) {
	if (!d || Number.isNaN(d.getTime())) return ''
	return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`
}

function parseLocalYmd(ymd) {
	const s = normalizeDateYmd(ymd)
	if (!s) return null
	const d = new Date(`${s.replace(/-/g, '/')} 00:00:00`)
	return Number.isNaN(d.getTime()) ? null : d
}

/** 默认开始日期：明天 */
function tomorrowYmd() {
	const d = new Date()
	d.setHours(0, 0, 0, 0)
	d.setDate(d.getDate() + 1)
	return formatLocalYmd(d)
}

/**
 * 按工期算结束日期（含首日）：
 * - 天：开始日 + (工期天数 - 1)
 * - 月：开始日加工期月数后再减 1 天
 */
function calcEndDateByDuration(startYmd, workDays, settlementMode) {
	const start = parseLocalYmd(startYmd)
	if (!start) return ''
	const n = Number(workDays)
	const count = !Number.isNaN(n) && n > 0 ? Math.floor(n) : 1
	const unit = formatWorkDurationUnit(settlementMode)
	const end = new Date(start.getTime())
	if (unit === '月') {
		end.setMonth(end.getMonth() + count)
		end.setDate(end.getDate() - 1)
	} else {
		end.setDate(end.getDate() + (count - 1))
	}
	return formatLocalYmd(end)
}

function modalConfirm(title, content) {
	return new Promise((resolve) => {
		uni.showModal({
			title: title || '提示',
			content: content || '',
			success: (res) => resolve(!!(res && res.confirm)),
			fail: () => resolve(false)
		})
	})
}

export default {
	name: 'FeTaskPublishSheet',
	props: {
		active: { type: Boolean, default: false },
		draftId: { type: [Number, String], default: null },
		orderId: { type: [Number, String], default: null },
		/** 流程已完成：仅查看，禁止发布 */
		readonly: { type: Boolean, default: false }
	},
	data() {
		return {
			loading: false,
			loadError: '',
			publishing: false,
			sourceTitle: '',
			groups: [],
			statusDesc: '请确认任务信息后发布',
			orderIdInner: null,
			registrationDone: false,
			/** 已登记 < 计划人数，发布时需 allow_understaffed */
			understaffed: false,
			registeredCount: 0,
			plannedCount: 0
		}
	},
	computed: {
		heroTitle() {
			return this.readonly ? '任务发布详情' : '确认发布任务'
		},
		enterpriseOk() {
			return store.isEnterpriseRegistered() === true
		},
		canPublish() {
			return this.enterpriseOk && this.registrationDone
		},
		scheduleComplete() {
			const list = this.groups || []
			if (!list.length) return false
			for (let i = 0; i < list.length; i++) {
				const g = list[i]
				if (!normalizeDateYmd(g.startDate) || !normalizeTimeHm(g.startTime)) return false
				if (!normalizeDateYmd(g.endDate) || !normalizeTimeHm(g.endTime)) return false
			}
			return true
		},
		gateTip() {
			if (!this.enterpriseOk && !this.registrationDone) {
				return '请先完成企业认证与人员登记后，再确认发布'
			}
			if (!this.enterpriseOk) return '请先完成企业认证后，再确认发布'
			if (!this.registrationDone) return '请先完成人员登记后，再确认发布'
			return ''
		},
		confirmDisabled() {
			return this.readonly || !this.canPublish || !this.scheduleComplete || this.publishing || this.loading
		},
		confirmLabel() {
			if (this.readonly) return '已发布'
			if (this.publishing) return '发布中...'
			return '确认发布'
		}
	},
	watch: {
		active(val) {
			if (val) this.loadData()
		},
		draftId() {
			if (this.active) this.loadData()
		},
		orderId() {
			if (this.active) this.loadData()
		},
		readonly() {
			if (this.active) this.loadData()
		}
	},
	methods: {
		onClose() {
			this.$emit('close')
		},
		pickField(raw, camel, snake) {
			if (!raw || typeof raw !== 'object') return null
			if (raw[camel] != null && raw[camel] !== '') return raw[camel]
			if (raw[snake] != null && raw[snake] !== '') return raw[snake]
			return null
		},
		/** GET publish-task → 工种行 */
		mapPublishDetailWorkItems(raw) {
			const items = (raw && (raw.workItems || raw.work_items)) || []
			const list = Array.isArray(items) ? items : []
			const groups = list.map((item, idx) => ({
				id: item.id != null ? item.id : null,
				groupId: this.pickField(item, 'groupNo', 'group_no') || `g_${idx}`,
				workType: this.pickField(item, 'jobType', 'job_type') || '待确认',
				workLocation: this.pickField(item, 'workLocation', 'work_location') || '待确认',
				workerCount: this.pickField(item, 'workerCount', 'worker_count'),
				workDays: this.pickField(item, 'workDays', 'work_days'),
				settlementMode: this.pickField(item, 'settlementCycle', 'settlement_cycle') || '',
				workStartDate: this.pickField(item, 'workStartDate', 'work_start_date') || '',
				workEndDate: this.pickField(item, 'workEndDate', 'work_end_date') || ''
			}))
			return this.buildGroupRows(groups, { viewMode: true })
		},
		buildGroupRows(groups, options = {}) {
			const viewMode = options.viewMode === true
			const emptyDate = viewMode ? '—' : '选择日期'
			const emptyTime = viewMode ? '—' : '选择时间'
			const list = Array.isArray(groups) ? groups : []
			const rawHasTime = (raw) => raw != null && raw !== '' && /\d{1,2}:\d{2}/.test(String(raw))
			return list.map((g, idx) => {
				const startParts = splitDateTimeParts(g.workStartDate)
				const endParts = splitDateTimeParts(g.workEndDate)
				const unit = formatWorkDurationUnit(g.settlementMode)
				const days = g.workDays
				let startDate = normalizeDateYmd(startParts.date)
				let endDate = normalizeDateYmd(endParts.date)
				let startTime = startDate && rawHasTime(g.workStartDate) ? normalizeTimeHm(startParts.time) : ''
				let endTime = endDate && rawHasTime(g.workEndDate) ? normalizeTimeHm(endParts.time) : ''
				// 可编辑发布：默认开始=明天 08:00，结束=按工期、18:00
				if (!viewMode) {
					if (!startDate) startDate = tomorrowYmd()
					if (!startTime) startTime = '08:00'
					if (!endTime) endTime = '18:00'
					if (!endDate) endDate = calcEndDateByDuration(startDate, days, g.settlementMode)
				}
				return {
					rowKey: g.groupId || `info_${idx}`,
					timeKey: `time_${g.groupId || idx}`,
					workItemId: g.id != null ? g.id : null,
					groupId: g.groupId || `g_${idx}`,
					workType: g.workType || '待确认',
					workLocation: g.workLocation || '待确认',
					workerCount: g.workerCount,
					workerCountText: g.workerCount != null ? `${g.workerCount}人` : '—',
					durationLabel: unit === '月' ? '工作月数' : '工作天数',
					durationText: days != null ? `${days}${unit}` : '—',
					workDays: days,
					settlementMode: g.settlementMode || '',
					startDate,
					startTime,
					endDate,
					endTime,
					startDateDisplay: startDate || emptyDate,
					endDateDisplay: endDate || emptyDate,
					startTimeDisplay: startTime || emptyTime,
					endTimeDisplay: endTime || emptyTime,
					startDisplay: formatDateTimeDisplay(startDate, startTime),
					endDisplay: formatDateTimeDisplay(endDate, endTime)
				}
			})
		},
		async resolveOrderIdFromDraft() {
			if (this.orderId != null && this.orderId !== '') return this.orderId
			if (this.draftId == null || this.draftId === '') return null
			try {
				const draftRaw = await getDraftDetail(this.draftId, { showError: false })
				if (!draftRaw) return null
				return draftRaw.orderId != null && draftRaw.orderId !== ''
					? draftRaw.orderId
					: (draftRaw.order_id != null && draftRaw.order_id !== '' ? draftRaw.order_id : null)
			} catch (e) {
				return null
			}
		},
		/** 已完成「查看发布」：GET /orders/{id}/publish-task */
		async loadPublishDetail() {
			this.loading = true
			this.loadError = ''
			this.understaffed = false
			try {
				const orderId = await this.resolveOrderIdFromDraft()
				this.orderIdInner = orderId
				if (orderId == null || orderId === '') {
					this.loadError = '缺少订单信息'
					this.groups = []
					return
				}
				const raw = await getOrderPublishTask(orderId, { showError: false })
				const title = this.pickField(raw, 'title', 'title') || '用工任务'
				const orderNo = this.pickField(raw, 'orderNo', 'order_no') || ''
				this.sourceTitle = orderNo ? `${title} ${orderNo}` : title
				this.groups = this.mapPublishDetailWorkItems(raw || {})
				const planned = Number(this.pickField(raw, 'plannedCount', 'planned_count') || 0)
				const registered = Number(this.pickField(raw, 'registeredCount', 'registered_count') || 0)
				this.plannedCount = planned
				this.registeredCount = registered
				this.understaffed = planned > 0 && registered < planned
				this.registrationDone = true
				const msg = (raw && raw.message) || ''
				if (msg) {
					this.statusDesc = msg
				} else if (planned > 0) {
					this.statusDesc = `已登记 ${registered}/${planned}，任务已发布`
				} else {
					this.statusDesc = '任务已发布，当前仅可查看'
				}
			} catch (e) {
				this.loadError = (e && (e.msg || e.message)) || '任务发布详情加载失败'
				this.groups = []
				showToast(this.loadError)
			} finally {
				this.loading = false
			}
		},
		syncGroupDisplay(gi) {
			const g = this.groups[gi]
			if (!g) return
			const startDate = normalizeDateYmd(g.startDate)
			const endDate = normalizeDateYmd(g.endDate)
			const startTime = normalizeTimeHm(g.startTime)
			const endTime = normalizeTimeHm(g.endTime)
			this.$set(g, 'startDate', startDate)
			this.$set(g, 'endDate', endDate)
			this.$set(g, 'startTime', startTime)
			this.$set(g, 'endTime', endTime)
			this.$set(g, 'startDateDisplay', startDate || '选择日期')
			this.$set(g, 'endDateDisplay', endDate || '选择日期')
			this.$set(g, 'startTimeDisplay', startTime || '选择时间')
			this.$set(g, 'endTimeDisplay', endTime || '选择时间')
			this.$set(g, 'startDisplay', formatDateTimeDisplay(startDate, startTime))
			this.$set(g, 'endDisplay', formatDateTimeDisplay(endDate, endTime))
		},
		onStartDateByIndex(gi, e) {
			if (this.readonly) return
			const v = normalizeDateYmd(e && e.detail ? e.detail.value : '')
			const g = this.groups[gi]
			if (!g) return
			this.$set(g, 'startDate', v)
			// 改开始日时，按工期重算结束日
			const end = calcEndDateByDuration(v, g.workDays, g.settlementMode)
			if (end) this.$set(g, 'endDate', end)
			if (!normalizeTimeHm(g.startTime)) this.$set(g, 'startTime', '08:00')
			if (!normalizeTimeHm(g.endTime)) this.$set(g, 'endTime', '18:00')
			this.syncGroupDisplay(gi)
		},
		onStartTimeByIndex(gi, e) {
			if (this.readonly) return
			const v = normalizeTimeHm(e && e.detail ? e.detail.value : '')
			const g = this.groups[gi]
			if (!g) return
			this.$set(g, 'startTime', v)
			this.syncGroupDisplay(gi)
		},
		onEndDateByIndex(gi, e) {
			if (this.readonly) return
			const v = normalizeDateYmd(e && e.detail ? e.detail.value : '')
			const g = this.groups[gi]
			if (!g) return
			this.$set(g, 'endDate', v)
			this.syncGroupDisplay(gi)
		},
		onEndTimeByIndex(gi, e) {
			if (this.readonly) return
			const v = normalizeTimeHm(e && e.detail ? e.detail.value : '')
			const g = this.groups[gi]
			if (!g) return
			this.$set(g, 'endTime', v)
			this.syncGroupDisplay(gi)
		},
		validateSchedule() {
			const list = this.groups || []
			if (!list.length) return '暂无工种信息，无法发布'
			for (let i = 0; i < list.length; i++) {
				const g = list[i]
				const prefix = list.length > 1 ? `「${g.workType || ('工种' + (i + 1))}」` : ''
				if (!normalizeDateYmd(g.startDate)) return `${prefix}请选择开始日期`
				if (!normalizeTimeHm(g.startTime)) return `${prefix}请选择开始时间`
				if (!normalizeDateYmd(g.endDate)) return `${prefix}请选择结束日期`
				if (!normalizeTimeHm(g.endTime)) return `${prefix}请选择结束时间`
				const start = joinDateTimePayload(g.startDate, g.startTime)
				const end = joinDateTimePayload(g.endDate, g.endTime)
				if (start && end && start > end) return `${prefix}结束时间不能早于开始时间`
			}
			return ''
		},
		resolveRegistrationDone(workflowRaw) {
			const detail = mapRegistrationBatchDetail(workflowRaw || {})
			const steps = detail.steps || []
			const regDone = steps.some((s) => isStaffingStep(s) && s.status === 'done')
			if (regDone) return true
			const progress = detail.progress || {}
			if (progress.total > 0 && progress.current >= progress.total) return true
			return false
		},
		buildStatusDesc(workflowRaw) {
			const detail = mapRegistrationBatchDetail(workflowRaw || {})
			const current = (detail.progress && detail.progress.current) || 0
			const total = (detail.progress && detail.progress.total) || 0
			if (this.canPublish) {
				if (total > 0 && current >= total) return `${total}人已全部登记，可发布任务`
				if (total > 0 && current < total) {
					return `已登记 ${current}/${total}，未招满发布需确认缺编`
				}
				return '企业认证与人员登记已完成，可发布任务'
			}
			if (total > 0) return `已登记 ${current}/${total}，完成认证与登记后方可发布`
			return '请先完成企业认证与人员登记'
		},
		syncStaffingFromWorkflow(workflowRaw) {
			const detail = mapRegistrationBatchDetail(workflowRaw || {})
			const current = (detail.progress && detail.progress.current) || 0
			const total = (detail.progress && detail.progress.total) || 0
			this.registeredCount = current
			this.plannedCount = total
			this.understaffed = total > 0 && current < total
		},
		/**
		 * TaskPublishRequest：
		 * { work_items: [{ id?, group_no?, job_type?, work_start_date, work_end_date }], allow_understaffed? }
		 */
		buildPublishPayload(allowUnderstaffed = false) {
			const workItems = (this.groups || []).map((g) => {
				const start = normalizeDateYmd(g.startDate)
				const end = normalizeDateYmd(g.endDate)
				const item = {
					work_start_date: start,
					work_end_date: end
				}
				if (g.workItemId != null && g.workItemId !== '') {
					item.id = Number(g.workItemId)
				}
				if (g.groupId) {
					item.group_no = String(g.groupId)
				}
				if (g.workType && g.workType !== '待确认') {
					item.job_type = String(g.workType)
				}
				return item
			})
			return {
				work_items: workItems,
				allow_understaffed: !!allowUnderstaffed
			}
		},
		async loadData() {
			// 已完成「查看发布」走任务发布详情接口
			if (this.readonly) {
				await this.loadPublishDetail()
				return
			}
			if (this.draftId == null || this.draftId === '') {
				this.loadError = '缺少草稿信息'
				this.groups = []
				return
			}
			this.loading = true
			this.loadError = ''
			this.understaffed = false
			this.registeredCount = 0
			this.plannedCount = 0
			try {
				const draftRaw = await getDraftDetail(this.draftId, { showError: false })
				const card = mapDraftDetailToCard(draftRaw || {})
				const groups = normalizeWorkerGroups(draftRaw || {})
				this.groups = this.buildGroupRows(groups.length ? groups : (card.workerGroups || []))
				const batchNo = (draftRaw && (draftRaw.draftNo || draftRaw.draft_no)) || card.draftNo || ''
				const title = (card && card.title) || (draftRaw && draftRaw.title) || '用工任务'
				this.sourceTitle = batchNo ? `${title} ${batchNo}` : title

				// 订单 ID 仅从草稿详情 order_id / orderId 取值
				const orderId = draftRaw && (draftRaw.orderId != null && draftRaw.orderId !== ''
					? draftRaw.orderId
					: (draftRaw.order_id != null && draftRaw.order_id !== '' ? draftRaw.order_id : null))
				this.orderIdInner = orderId

				let workflowRaw = null
				try {
					workflowRaw = await getDraftWorkflowProgress(this.draftId, { showError: false })
				} catch (e) {
					workflowRaw = null
				}

				this.syncStaffingFromWorkflow(workflowRaw)
				this.registrationDone = this.resolveRegistrationDone(workflowRaw)
				this.statusDesc = this.buildStatusDesc(workflowRaw)
			} catch (e) {
				this.loadError = (e && (e.msg || e.message)) || '任务信息加载失败'
				this.groups = []
				showToast(this.loadError)
			} finally {
				this.loading = false
			}
		},
		async onConfirm() {
			if (this.readonly) {
				showToast('任务已发布，仅可查看')
				return
			}
			if (this.confirmDisabled) return
			if (!this.canPublish) {
				showToast(this.gateTip || '暂不可发布')
				return
			}
			// 跳过认证不算「认证完」
			if (!this.enterpriseOk) {
				showToast('请先完成企业认证')
				return
			}
			if (isEnterpriseCertSkipped() && !store.isEnterpriseRegistered()) {
				showToast('请先完成企业认证')
				return
			}
			const orderId = this.orderIdInner
			if (orderId == null || orderId === '') {
				showToast('缺少订单信息，暂无法发布')
				return
			}
			const scheduleErr = this.validateSchedule()
			if (scheduleErr) {
				showToast(scheduleErr)
				return
			}

			let allowUnderstaffed = false
			if (this.understaffed) {
				const tip = `已登记 ${this.registeredCount}/${this.plannedCount}，未招满。是否缺编发布？`
				const ok = await modalConfirm('确认缺编发布', tip)
				if (!ok) return
				allowUnderstaffed = true
			} else {
				const ok = await modalConfirm('确认发布', '确认后将发布用工任务，是否继续？')
				if (!ok) return
			}

			this.publishing = true
			try {
				const res = await publishOrderTask(
					orderId,
					this.buildPublishPayload(allowUnderstaffed),
					{ showError: true }
				)
				showToast((res && (res.message || res.msg)) || '任务已发布')
				const nextOrderId = (res && (res.orderId != null ? res.orderId : res.order_id)) || orderId
				this.$emit('success', {
					orderId: nextOrderId,
					draftId: this.draftId,
					result: res
				})
				this.onClose()
			} catch (e) {
				if (e && e.__handled) return
			} finally {
				this.publishing = false
			}
		}
	}
}
</script>

<style lang="scss" scoped>
.fe-bottom-sheet--task-publish {
	max-height: 88vh;
}

.fe-sheet-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.fe-sheet-close {
	width: 56rpx;
	height: 56rpx;
	border-radius: 50%;
	background: $fe-gray-100;
	color: $fe-muted;
	font-size: 28rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}

.tp-source {
	padding: 0 40rpx 8rpx;
}

.tp-body {
	max-height: 58vh;
}

.tp-empty {
	padding: 80rpx 32rpx;
	text-align: center;
}

.tp-empty__text {
	display: block;
	font-size: 28rpx;
	color: #94A3B8;
	margin-bottom: 24rpx;
}

.tp-hero {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 12rpx 0 28rpx;
}

.tp-hero__icon {
	width: 112rpx;
	height: 112rpx;
	border-radius: 50%;
	background: #FEF3C7;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 20rpx;
}

.tp-hero__icon-text {
	font-size: 52rpx;
	line-height: 1;
}

.tp-hero__title {
	font-size: 34rpx;
	font-weight: 700;
	color: $fe-foreground;
	margin-bottom: 8rpx;
}

.tp-hero__desc {
	font-size: 24rpx;
	color: $fe-muted;
	text-align: center;
	line-height: 1.5;
	padding: 0 24rpx;
}

.tp-section {
	margin-bottom: 28rpx;
}

.tp-section__title {
	display: block;
	font-size: 28rpx;
	font-weight: 700;
	color: $fe-foreground;
	margin-bottom: 16rpx;
}

.tp-card {
	background: $fe-gray-50;
	border-radius: $fe-radius-md;
	padding: 24rpx;
	margin-bottom: 16rpx;
	border: 1rpx solid $fe-border-light;
	box-sizing: border-box;
}

.tp-card__badge {
	display: block;
	font-size: 22rpx;
	font-weight: 600;
	color: $fe-primary;
	margin-bottom: 16rpx;
}

.tp-grid {
	display: flex;
	flex-wrap: wrap;
}

.tp-grid__cell {
	width: 50%;
	box-sizing: border-box;
	padding: 10rpx 12rpx 10rpx 0;
}

.tp-grid__label {
	display: block;
	font-size: 22rpx;
	color: $fe-muted;
	margin-bottom: 6rpx;
}

.tp-grid__value {
	display: block;
	font-size: 28rpx;
	font-weight: 700;
	color: $fe-foreground;
	word-break: break-all;
}

.tp-field {
	margin-bottom: 20rpx;
}

.tp-field:last-child {
	margin-bottom: 0;
}

.tp-field__label {
	display: block;
	font-size: 24rpx;
	color: $fe-muted;
	margin-bottom: 10rpx;
}

.tp-required {
	color: #EF4444;
	font-weight: 700;
}

.tp-datetime-row {
	display: flex;
	align-items: stretch;
	gap: 16rpx;
	width: 100%;
	box-sizing: border-box;
}

.tp-datetime-row__item {
	flex: 1;
	min-width: 0;
	width: 0;
}

.tp-input {
	display: flex;
	align-items: center;
	gap: 8rpx;
	min-height: 80rpx;
	padding: 0 16rpx;
	background: $fe-surface;
	border: 1rpx solid $fe-border;
	border-radius: $fe-radius-md;
	box-sizing: border-box;
}

.tp-input__icon {
	font-size: 28rpx;
	line-height: 1;
	flex-shrink: 0;
}

.tp-input__text {
	flex: 1;
	min-width: 0;
	font-size: 26rpx;
	font-weight: 600;
	color: $fe-foreground;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tp-input--placeholder .tp-input__text {
	color: #94A3B8;
	font-weight: 500;
}

.tp-gate-tip {
	padding: 16rpx 20rpx;
	background: rgba(245, 158, 11, 0.1);
	border-radius: $fe-radius-md;
	margin-bottom: 12rpx;
}

.tp-gate-tip--ok {
	background: rgba(16, 185, 129, 0.1);
}

.tp-gate-tip__text {
	font-size: 24rpx;
	color: #B45309;
	line-height: 1.5;
}

.tp-gate-tip__text--ok {
	color: #047857;
}

.tp-input--readonly {
	background: $fe-gray-100;
}

.fe-btn--disabled-look {
	opacity: 0.42;
	pointer-events: none;
}
</style>
