import {
	isEnterpriseAuthStep,
	isEnterpriseCertSkipped,
	isRegistrationStep,
	isWorkerRecruitmentStep,
	isStaffingStep,
	buildWorkerRecruitmentProcessPanel,
	isTaskPublishStep,
	isSettlementStep,
	isInvoiceArchiveStep,
	buildEnterpriseCertProcessPanel,
	buildRegistrationQrProcessPanel,
	buildTaskPublishProcessPanel,
	buildSettlementProcessPanel,
	buildInvoiceArchiveProcessPanel
} from '@/utils/process-card.js'
import { resolveApiAssetUrl } from '@/common/config.js'

/**
 * 登记批次详情 → 进度弹层展示结构
 * 兼容后端 snake_case（@JsonProperty）与小驼峰
 */
export function mapRegistrationBatchDetail(raw = {}) {
	const stats = raw.stats || {}
	const progress = raw.progress || {}
	const steps = Array.isArray(raw.steps) ? raw.steps : []
	const workers = Array.isArray(raw.workers) ? raw.workers : []

	const pending = num(stats.pendingCount, stats.pending_count, 0)
	const inProgress = num(stats.inProgressCount, stats.in_progress_count, 0)
	const completed = num(stats.completedCount, stats.completed_count, 0)
	const expected = num(stats.expectedCount, stats.expected_count, 0)
	const registered = num(stats.registeredCount, stats.registered_count, progress.current)

	const current = num(progress.current, null, registered)
	const total = num(progress.total, null, expected)
	const percent = num(progress.percent, null, total > 0 ? Math.round((current / total) * 100) : 0)

	const mappedWorkers = workers.map((w, i) => {
		const name = w.realName || w.real_name || '—'
		const registrationId = w.registrationId != null
			? w.registrationId
			: (w.registration_id != null ? w.registration_id : null)
		const regStatus = w.regStatus || w.reg_status || ''
		const status = mapWorkerStatusTag(w.statusTag || w.status_tag || regStatus)
		const submittedAt = w.submittedAt || w.submitted_at || ''
		return {
			msgKey: registrationId != null ? registrationId : i,
			registrationId,
			workerId: w.workerId != null ? w.workerId : w.worker_id,
			name,
			avatarText: String(name).charAt(0) || '工',
			phone: w.mobileMask || w.mobile_mask || '',
			workType: w.confirmedWorkType || w.confirmed_work_type || '',
			regStatus,
			status,
			statusText: w.statusText || w.status_text || '',
			failReason: w.failReason || w.fail_reason || '',
			submittedAt,
			submittedAtText: formatSubmittedAt(submittedAt),
			canReview: status === 'review' || regStatus === 'under_review'
		}
	})

	return {
		draftId: raw.draftId != null ? raw.draftId : (raw.draft_id != null ? raw.draft_id : null),
		batchId: raw.batchId != null ? raw.batchId : raw.batch_id,
		batchNo: raw.batchNo || raw.batch_no || '',
		title: raw.title || '用工批次',
		subtitle: raw.subtitle || '',
		orderId: raw.orderId != null ? raw.orderId : raw.order_id,
		orderNo: raw.orderNo || raw.order_no || '',
		currentStepCode: raw.currentStepCode || raw.current_step_code || '',
		status: raw.status || '',
		qrToken: raw.qrToken || raw.qr_token || '',
		qrCodeUrl: raw.qrCodeUrl || raw.qr_code_url || '',
		stats: {
			pending,
			inProgress,
			completed,
			expected,
			registered
		},
		progress: {
			current,
			total,
			percent: Math.max(0, Math.min(100, percent)),
			text: `${current}/${total}`
		},
		steps: steps.map((s, i) => ({
			key: s.stepCode || s.step_code || `step-${i}`,
			title: s.title || '',
			status: s.status || 'pending',
			time: s.time || '',
			highlight: s.highlight || ''
		})),
		workers: mappedWorkers,
		workerGroups: groupWorkersByWorkType(mappedWorkers)
	}
}

/**
 * 人员列表按工种分组（保持首次出现顺序）
 * @param {Array} workers
 * @returns {{ msgKey: string, workType: string, count: number, workers: Array }[]}
 */
export function groupWorkersByWorkType(workers = []) {
	const order = []
	const map = Object.create(null)
	;(workers || []).forEach((w) => {
		const type = w && w.workType != null ? String(w.workType).trim() : ''
		const key = type || '__unknown__'
		if (!map[key]) {
			map[key] = {
				msgKey: key === '__unknown__' ? 'wt-unknown' : ('wt-' + key),
				workType: type || '未填写工种',
				count: 0,
				workers: []
			}
			order.push(key)
		}
		map[key].workers.push(w)
		map[key].count = map[key].workers.length
	})
	return order.map((k) => map[k])
}

function num(a, b, fallback) {
	if (a != null && a !== '' && !Number.isNaN(Number(a))) return Number(a)
	if (b != null && b !== '' && !Number.isNaN(Number(b))) return Number(b)
	if (fallback != null && fallback !== '' && !Number.isNaN(Number(fallback))) return Number(fallback)
	return 0
}

function mapWorkerStatusTag(tag) {
	const t = tag == null ? '' : String(tag)
	if (t === 'done' || t === 'completed') return 'done'
	if (t === 'fail' || t === 'verify_failed' || t === 'rejected') return 'fail'
	if (t === 'review' || t === 'under_review') return 'review'
	if (t === 'contract' || t === 'contract_signing') return 'pending'
	if (t === 'registering' || t === 'in_progress') return 'pending'
	return 'pending'
}

function formatSubmittedAt(value) {
	if (value == null || value === '') return ''
	const s = String(value).replace('T', ' ')
	return s.length >= 16 ? s.slice(0, 16) : s
}

const STEP_STATUS_LABEL = {
	done: '已完成',
	active: '进行中',
	pending: '未开始'
}

function isDraftWorkflowStep(step) {
	if (!step) return true
	const key = String(step.key || step.stepCode || step.step_code || '').toLowerCase()
	const title = String(step.title || '')
	if (key === 'draft_created' || key === 'draft' || key.indexOf('draft_') === 0) return true
	if (title.indexOf('草稿') >= 0) return true
	return false
}

/** 步骤标题拆成每行 2 字（最多 3 行） */
function formatStepLabelLines(title) {
	const t = String(title || '').replace(/\s+/g, '')
	if (!t) return ['—']
	const lines = []
	for (let i = 0; i < t.length && lines.length < 3; i += 2) {
		lines.push(t.slice(i, i + 2))
	}
	return lines
}

/**
 * 进度卡缺企业认证节点时，插在方案确认后（前端展示用，不改后端）
 * @param {Array} steps
 * @param {{ enterpriseRegistered?: boolean }} [options]
 */
function ensureEnterpriseAuthStep(steps, options = {}) {
	const list = Array.isArray(steps) ? steps.slice() : []
	if (list.some(isEnterpriseAuthStep)) return list

	const registered = options.enterpriseRegistered === true
	const skipped = !registered && isEnterpriseCertSkipped()
	let status = 'pending'
	if (registered) status = 'done'
	else if (skipped) status = 'pending'
	else {
		const planIdx = list.findIndex((s) => {
			const key = String((s && s.key) || '').toLowerCase()
			const title = String((s && s.title) || '')
			return key === 'plan_confirmed' || key === 'plan' || title.indexOf('方案确认') >= 0
		})
		const prevDone = planIdx < 0
			? true
			: list.slice(0, planIdx + 1).every((s) => (s.status || 'pending') === 'done')
		status = prevDone ? 'active' : 'pending'
	}

	const authStep = {
		key: 'enterprise_auth',
		title: '企业认证',
		status,
		time: '',
		highlight: ''
	}
	const planIdx = list.findIndex((s) => {
		const key = String((s && s.key) || '').toLowerCase()
		const title = String((s && s.title) || '')
		return key === 'plan_confirmed' || key === 'plan' || title.indexOf('方案确认') >= 0
	})
	const insertAt = planIdx >= 0 ? planIdx + 1 : 0
	list.splice(insertAt, 0, authStep)
	// 企业认证与人员登记可并行，不再把其它 active 降为 pending
	return list
}

function isPlanConfirmedStep(step) {
	if (!step) return false
	const key = String(step.key || '').toLowerCase()
	const title = String(step.title || '')
	return key === 'plan_confirmed' || key === 'plan' || title.indexOf('方案确认') >= 0
}

/** 方案已确认（或无方案节点）时，登记与认证之间的连线可视为已接通 */
function planConfirmedOrParallelReady(steps) {
	const list = Array.isArray(steps) ? steps : []
	const hasPlan = list.some(isPlanConfirmedStep)
	if (!hasPlan) return true
	return list.some((s) => isPlanConfirmedStep(s) && s.status === 'done')
}

/**
 * 流程门禁：
 * - 企业认证 / 人员登记|招聘：可并行（方案确认后可操作；登记/招聘 status 以接口为准）
 * - 任务发布 → 结算打款 → 开票归档：须上一环节完成
 */
function applyParallelAndSequentialGates(steps, options = {}) {
	const list = (Array.isArray(steps) ? steps : []).map((s) => Object.assign({}, s))
	const registered = options.enterpriseRegistered === true
	const certSkipped = options.certSkipped === true

	const hasPlan = list.some(isPlanConfirmedStep)
	const planDone = !hasPlan || list.some((s) => isPlanConfirmedStep(s) && s.status === 'done')

	// 1) 并行段：认证 + 登记（接口已给 active/done 时以接口为准，勿用本地认证态覆盖）
	for (let i = 0; i < list.length; i++) {
		const s = list[i]
		if (isEnterpriseAuthStep(s)) {
			if (registered && s.status === 'pending') {
				// 本地已认证且接口仍 pending（偶发滞后）时抬升
				s.status = 'done'
			} else if (!registered && certSkipped) {
				s.status = 'pending'
			} else if (!registered && planDone && s.status === 'pending') {
				s.status = 'active'
			}
		} else if (isStaffingStep(s)) {
			// 状态以接口为准（pending 保持灰色「未开始」）；方案确认后仅解锁操作
			if (s.status === 'done') {
				s._actionLocked = false
			} else if (!planDone) {
				s._actionLocked = true
			} else {
				s._actionLocked = false
			}
		}
	}

	const authOk = registered
		|| certSkipped
		|| list.some((s) => isEnterpriseAuthStep(s) && s.status === 'done')
	// 有登记/招聘节点时必须 done；无该节点才视为不需要登记
	const hasRegStep = list.some(isStaffingStep)
	const regOk = hasRegStep
		? list.some((s) => isStaffingStep(s) && s.status === 'done')
		: false
	const parallelReady = authOk && regOk

	const taskDone = list.some((x) => isTaskPublishStep(x) && x.status === 'done')
	const settleDone = list.some((x) => isSettlementStep(x) && x.status === 'done')
		|| list.some((x) => {
			const key = String((x && x.key) || '').toLowerCase()
			const title = String((x && x.title) || '')
			return (key === 'settlement_paid' || title.indexOf('已支付') >= 0) && x.status === 'done'
		})

	// 2) 串行段：任务发布 → 结算 → 开票（强制：未满足前置一律 pending + 锁定）
	for (let i = 0; i < list.length; i++) {
		const s = list[i]
		if (isTaskPublishStep(s)) {
			s._actionLocked = !parallelReady
			if (s.status === 'done') {
				s._actionLocked = false
			} else if (!parallelReady) {
				s.status = 'pending'
			} else if (s.status !== 'active') {
				// 前置已齐：仅允许 active 可点，其它保持 pending（等后端推进）
				s.status = 'pending'
				s._actionLocked = true
			}
		} else if (isSettlementStep(s)) {
			s._actionLocked = !taskDone
			if (s.status === 'done') {
				s._actionLocked = false
			} else if (!taskDone || s.status !== 'active') {
				s.status = 'pending'
				s._actionLocked = true
			}
		} else if (isInvoiceArchiveStep(s)) {
			s._actionLocked = !settleDone
			if (s.status === 'done') {
				s._actionLocked = false
			} else if (!settleDone || s.status !== 'active') {
				s.status = 'pending'
				s._actionLocked = true
			}
		}
	}

	return list
}

/**
 * workflow-progress / registration-batch 详情 → 聊天气泡进度卡片
 * 总进度按办理步骤（排除草稿节点）计算；不展示登记人数进度
 * @param {object} raw API 原始响应或已 map 的 detail
 * @param {number|string} msgKey
 * @param {{ enterpriseRegistered?: boolean }} [options]
 */
export function buildWorkflowChatCardMessage(raw, msgKey, options = {}) {
	const detail = mapRegistrationBatchDetail(raw || {})
	let filtered = (detail.steps || []).filter((s) => !isDraftWorkflowStep(s))
	filtered = ensureEnterpriseAuthStep(filtered, options)
	const registered = options.enterpriseRegistered === true
	const certSkipped = !registered && isEnterpriseCertSkipped()

	// 先归一化各步 status，再套并行/串行门禁，最后算连线与面板
	let normalized = filtered.map((s) => {
		const status = (s && s.status) || 'pending'
		return Object.assign({}, s, { status })
	})
	// 已支付完成时，待结算引导卡同步为 done
	const paidDone = normalized.some((s) => {
		const key = String((s && s.key) || '').toLowerCase()
		const title = String((s && s.title) || '')
		return (key === 'settlement_paid' || title.indexOf('已支付') >= 0)
			&& (s.status === 'done' || s.status === 'active')
	})
	if (paidDone) {
		for (let i = 0; i < normalized.length; i++) {
			if (isSettlementStep(normalized[i])) {
				normalized[i] = Object.assign({}, normalized[i], { status: 'done' })
			}
		}
	}
	normalized = applyParallelAndSequentialGates(normalized, {
		enterpriseRegistered: registered,
		certSkipped
	})

	const qrCodeUrl = detail.qrCodeUrl || ''
	const qrToken = detail.qrToken || ''
	const qrImageUrl = resolveApiAssetUrl(qrCodeUrl)
	const batchSubtitle = detail.subtitle
		|| (detail.batchNo ? `${detail.title || ''} ${detail.batchNo}`.trim() : (detail.title || ''))
	const progressCurrent = (detail.progress && detail.progress.current) || 0
	const progressTotal = (detail.progress && detail.progress.total) || 0

	const steps = normalized.map((s, i) => {
		const status = s.status || 'pending'
		const isAuth = isEnterpriseAuthStep(s)
		const isReg = isRegistrationStep(s)
		const isRecruit = isWorkerRecruitmentStep(s)
		const isStaffing = isReg || isRecruit
		const isTask = isTaskPublishStep(s)
		const isSettle = isSettlementStep(s)
		const isInvoice = isInvoiceArchiveStep(s)
		const actionLocked = s._actionLocked === true
		// 步骤条展示名统一
		let title = s.title || `步骤${i + 1}`
		if (isReg) title = '人员登记'
		else if (isRecruit) title = '临时工招聘'
		else if (isTask) title = '任务发布'
		else if (isSettle) title = '结算打款'
		else if (isInvoice) title = '开票归档'
		const labelLines = formatStepLabelLines(title)
		// 并行段：登记/招聘节点连线不依赖认证完成
		let prevDone = false
		if (i > 0) {
			const prev = normalized[i - 1]
			if (isStaffing && isEnterpriseAuthStep(prev)) {
				prevDone = planConfirmedOrParallelReady(normalized)
			} else {
				prevDone = (prev.status || 'pending') === 'done'
			}
		}
		const isLast = i >= normalized.length - 1
		let nodeIcon = String(i + 1)
		if (status === 'done') nodeIcon = '✓'
		else if (status === 'active') nodeIcon = '⏱'

		let processPanel = null
		if (isAuth) {
			processPanel = buildEnterpriseCertProcessPanel(status, { skipped: certSkipped })
		} else if (isReg) {
			processPanel = buildRegistrationQrProcessPanel(status, {
				subtitle: batchSubtitle,
				hint: '分享给临时工扫码即可登记',
				qrCodeUrl,
				qrImageUrl,
				qrToken,
				registered: progressCurrent,
				total: progressTotal,
				highlight: s.highlight || '',
				actionLocked
			})
		} else if (isRecruit) {
			processPanel = buildWorkerRecruitmentProcessPanel(status, {
				registered: progressCurrent,
				total: progressTotal,
				highlight: s.highlight || '',
				actionLocked
			})
		} else if (isTask) {
			processPanel = buildTaskPublishProcessPanel(status, { actionLocked })
		} else if (isSettle) {
			processPanel = buildSettlementProcessPanel(status, { actionLocked })
		} else if (isInvoice) {
			processPanel = buildInvoiceArchiveProcessPanel(status, { actionLocked })
		}

		let processMod = ''
		if (processPanel) {
			if (processPanel.cardType === 'registration_qr') {
				processMod = 'fe-workflow-step--process fe-workflow-step--qr'
			} else if (processPanel.cardType === 'worker_recruitment') {
				processMod = 'fe-workflow-step--process fe-workflow-step--recruit'
			} else if (processPanel.cardType === 'task_publish') {
				processMod = 'fe-workflow-step--process fe-workflow-step--task'
			} else if (processPanel.cardType === 'settlement') {
				processMod = 'fe-workflow-step--process fe-workflow-step--settle'
			} else if (processPanel.cardType === 'invoice_archive') {
				processMod = 'fe-workflow-step--process fe-workflow-step--invoice'
			} else {
				processMod = 'fe-workflow-step--process'
			}
		}

		return {
			key: s.key || `step-${i}`,
			title,
			labelLines,
			status,
			statusLabel: STEP_STATUS_LABEL[status] || status,
			time: s.time || '',
			highlight: s.highlight || '',
			nodeIcon,
			showNodeIcon: true,
			hasProcessPanel: !!processPanel,
			processPanel,
			rootClass: processPanel
				? `fe-workflow-step ${processMod} fe-workflow-step--${status}`
				: `fe-workflow-step fe-workflow-step--${status}`,
			statusClass: `fe-workflow-step__status fe-workflow-step__status--${status}`,
			dotClass: `fe-workflow-step__dot fe-workflow-step__dot--${status}`,
			colClass: `fe-stepper__col fe-stepper__col--${status}`,
			nodeClass: `fe-stepper__node fe-stepper__node--${status}`,
			labelClass: `fe-stepper__label fe-stepper__label--${status}`,
			leftRailClass: i === 0
				? 'fe-stepper__rail fe-stepper__rail--ghost'
				: (prevDone ? 'fe-stepper__rail fe-stepper__rail--on' : 'fe-stepper__rail'),
			rightRailClass: isLast
				? 'fe-stepper__rail fe-stepper__rail--ghost'
				: (status === 'done' ? 'fe-stepper__rail fe-stepper__rail--on' : 'fe-stepper__rail')
		}
	})
	let stepIndex = steps.findIndex((s) => s.status === 'active')
	if (stepIndex < 0) {
		stepIndex = steps.findIndex((s) => s.hasProcessPanel
			&& s.processPanel
			&& s.processPanel.processStatus === 'current')
	}
	if (stepIndex < 0) stepIndex = steps.findIndex((s) => s.status === 'pending')
	if (stepIndex < 0) stepIndex = Math.max(0, steps.length - 1)

	const draftTitle = String(detail.title || '').trim()
	const cardTitle = draftTitle ? `办理进度 · ${draftTitle}` : '办理进度'
	const hasProcessPanel = steps.some((s) => s.hasProcessPanel)

	return {
		type: 'workflow',
		role: 'ai',
		msgKey,
		draftId: detail.draftId,
		workflow: {
			draftId: detail.draftId,
			title: cardTitle,
			draftTitle,
			stepIndex,
			steps,
			detail,
			hasProcessPanel,
			swiperClass: hasProcessPanel
				? 'fe-workflow-swiper fe-workflow-swiper--process'
				: 'fe-workflow-swiper'
		}
	}
}

/**
 * 会话内草稿进度合集（接口未就绪时的 mock）
 * @param {Array<{ draftId?: number|string, title?: string, batchNo?: string }>} [seeds]
 */
export function buildMockConversationProgressList(seeds = []) {
	const list = Array.isArray(seeds) && seeds.length
		? seeds
		: [
			{ draftId: 101, title: '浦东仓库搬运', batchNo: 'bat_1' },
			{ draftId: 102, title: '商场促销推广', batchNo: 'bat_2' },
			{ draftId: 103, title: '展会驻场接待', batchNo: 'bat_3' }
		]

	return list.map((seed, idx) => {
		const total = 8 + (idx % 3) * 2
		const current = Math.min(total, 3 + idx * 2)
		const pending = Math.max(0, total - current)
		const inProgress = Math.min(current, 2 + (idx % 2))
		const completed = Math.max(0, current - inProgress)
		const title = seed.title || `用工批次 ${idx + 1}`
		const batchNo = seed.batchNo || `bat_${idx + 1}`
		const draftId = seed.draftId != null ? seed.draftId : (100 + idx)
		return mapRegistrationBatchDetail({
			draft_id: draftId,
			batch_id: draftId,
			batch_no: batchNo,
			title,
			subtitle: `${title} ${batchNo}`,
			order_no: `ord_${draftId}`,
			status: 'active',
			stats: {
				pending_count: pending,
				in_progress_count: inProgress,
				completed_count: completed,
				expected_count: total,
				registered_count: current
			},
			progress: {
				current,
				total,
				percent: Math.round((current / total) * 100)
			},
			steps: [
				{ step_code: 'draft', title: '草稿创建', status: 'done', time: '01-15 14:30' },
				{ step_code: 'plan', title: '方案确认', status: 'done', time: '01-15 14:35' },
				{
					step_code: 'registration',
					title: '扫码登记',
					status: 'active',
					highlight: `进行中 ${current}/${total}`
				},
				{ step_code: 'review', title: '企业审核', status: 'pending' },
				{ step_code: 'work', title: '开始用工', status: 'pending' }
			],
			workers: [
				{ registration_id: idx * 10 + 1, real_name: '张三', mobile_mask: '138****1234', status_tag: 'done', status_text: '已完成' },
				{ registration_id: idx * 10 + 2, real_name: '李四', mobile_mask: '139****5678', status_tag: 'done', status_text: '已完成' },
				{ registration_id: idx * 10 + 3, real_name: '王五', mobile_mask: '137****9012', status_tag: 'fail', status_text: '核验失败' },
				{ registration_id: idx * 10 + 4, real_name: '赵六', mobile_mask: '136****3456', status_tag: 'pending', status_text: '待登记' },
				{ registration_id: idx * 10 + 5, real_name: '钱七', mobile_mask: '135****7890', status_tag: 'review', status_text: '审核中' }
			]
		})
	})
}
