<template>
	<view class="page">
		<view v-if="loading" class="empty-tip text-gray text-center padding">加载中...</view>

		<view v-else-if="!checkItemList.length" class="empty-tip text-gray text-center padding">
			暂无检查项
		</view>

		<template v-else>
			<!-- 吸顶进度导航条：紧贴页面内容区顶部，滚动时始终可见 -->
			<view class="float-nav">
				<view class="float-nav-body">
					<view class="float-nav-main">
						<view class="progress-text">
							<text class="current-index">共 {{ checkItemList.length }} 项检查</text>
							<text class="total-count">，已提交 {{ submittedCount }} 项</text>
							<text class="total-count">，待提交 {{ pendingSubmitCount }} 项</text>
							<text class="total-count">，待检查 {{ uncheckedCount }} 项</text>
						</view>
						<view class="progress-line">
							<view class="progress-inner" :style="{ width: progressPercent + '%' }"></view>
						</view>
					</view>
					<view class="sheet-nav-btn" @click="openCheckSheet">
						<up-icon name="grid" size="22" color="#2667E9"></up-icon>
					</view>
				</view>
			</view>

			<view class="page-content padding">
			<view
				v-if="showRestoreBanner"
				class="draft-banner margin-bottom"
			>
				<view class="draft-banner-left">
					<text class="cuIcon-info draft-banner-icon"></text>
					<text>已自动恢复您上次未提交的检查内容</text>
				</view>
				<text class="draft-banner-action" @click="clearDraft(true)">清空草稿</text>
			</view>

			<!-- <view class="sheet-header bg-white radius padding margin-bottom">
				<view class="text-bold">{{ sheetTitle }}</view>
				<view class="text-gray text-sm margin-top-xs" v-if="industryName">
					行业类型：{{ industryName }}
				</view>
			</view> -->

			<view
				v-for="(item, index) in checkItemList"
				:key="'check-item-' + index"
				:id="'check-item-' + index"
				class="question-card padding bg-white radius margin-bottom"
				:class="{ 'question-card--submitted': isItemSubmitted(item) }"
			>
				<view class="question-header-row">
					<view class="question-index">第 {{ index + 1 }} 项</view>
					<view v-if="isItemSubmitted(item)" class="submitted-tag">已提交</view>
					<view v-else-if="isItemPendingSubmit(index)" class="pending-tag">待提交</view>
				</view>
				<view class="text-bold margin-top-xs">{{ item.name }}</view>
				<view class="margin-top-sm">
					<rich-text :nodes="item.point || ''"></rich-text>
				</view>

				<!-- 已提交：只读展示 -->
				<block v-if="isItemSubmitted(item)">
					<view class="answer-panel margin-top">
						<view class="readonly-row">
							<text class="readonly-label">检查结果</text>
							<view :class="['result-tag', getResultTagClass(item.result)]">
								{{ getResultLabel(item.result) }}
							</view>
						</view>
						<view v-if="item.remark" class="readonly-row">
							<text class="readonly-label">备注</text>
							<text class="readonly-value">{{ item.remark }}</text>
						</view>
						<view v-if="item.result === 2" class="hazard-summary">
							<view v-if="item.hazardName" class="readonly-row readonly-row--stack">
								<text class="readonly-label">隐患标题</text>
								<text class="readonly-value">{{ item.hazardName }}</text>
							</view>
							<view v-if="item.source" class="readonly-row readonly-row--stack">
								<text class="readonly-label">检查形式</text>
								<text class="readonly-value">{{ item.source }}</text>
							</view>
							<view v-if="item.hazardAddress" class="readonly-row readonly-row--stack">
								<text class="readonly-label">隐患位置</text>
								<text class="readonly-value">{{ item.hazardAddress }}</text>
							</view>
							<view v-if="item.hazardDesc" class="readonly-row readonly-row--stack">
								<text class="readonly-label">隐患描述</text>
								<text class="readonly-value">{{ item.hazardDesc }}</text>
							</view>
						</view>
						<button
							v-if="item.result === 2 && item.hazardId"
							class="view-hazard-btn"
							@click="viewHazardDetail(item)"
						>
							查看隐患
						</button>
					</view>
				</block>

				<!-- 未提交：可编辑 -->
				<block v-else>
				<view class="margin-top">
					<view class="text-gray margin-bottom-xs">检查结果</view>
					<u-radio-group
						v-model="answerList[index].resultLabel"
						placement="row"
						@change="(label) => onResultChange(index, label)"
					>
						<u-radio
							v-for="(opt, optIndex) in resultOptions"
							:key="optIndex"
							:customStyle="{ marginBottom: '8px', marginRight: '24rpx' }"
							:label="opt.name"
							:name="opt.name"
						></u-radio>
					</u-radio-group>
				</view>

				<view v-if="answerList[index].resultLabel === '异常'" class="hazard-section margin-top">
					<view class="hazard-tip">
						<text class="cuIcon-warn text-yellow margin-right-xs"></text>
						<text class="text-orange">检查结果为异常，需填写隐患信息</text>
					</view>

					<view
						v-if="!hasHazardData(index)"
						class="hazard-btn"
						@click="openHazardPopup(index)"
					>
						<text class="text-blue">填写隐患信息</text>
					</view>

					<view v-else class="hazard-card">
						<view class="card-header">
							<view class="text-bold text-black">{{ answerList[index].hazardPayload.formData.title }}</view>
							<view
								class="level-tag"
								:class="{
									'level-minor': answerList[index].hazardPayload.formData.level === 0,
									'level-normal': answerList[index].hazardPayload.formData.level === 1,
									'level-major': answerList[index].hazardPayload.formData.level === 2
								}"
							>
								{{ LEVEL_OPTIONS[answerList[index].hazardPayload.formData.level]?.title }}
							</view>
						</view>
						<view class="card-body">
							<view class="info-row">
								<text class="text-gray">检查形式：</text>
								<text>{{ SOURCE_OPTIONS[answerList[index].hazardPayload.formData.source]?.title || '-' }}</text>
							</view>
							<view class="info-row">
								<text class="text-gray">隐患位置：</text>
								<text>{{ answerList[index].hazardPayload.address || '-' }}</text>
							</view>
							<view class="info-row">
								<text class="text-gray">隐患描述：</text>
								<text class="description-text">{{ answerList[index].hazardPayload.formData.description || '-' }}</text>
							</view>
							<view class="info-row" v-if="answerList[index].hazardPayload.fileList.length > 0">
								<text class="text-gray">附件：</text>
								<text>{{ answerList[index].hazardPayload.fileList.length }}个文件</text>
							</view>
						</view>
						<view class="card-footer">
							<button class="btn-edit" @click="openHazardPopup(index)">修改</button>
							<button class="btn-clear" @click="clearHazard(index)">清除</button>
						</view>
					</view>
				</view>

				<view class="margin-top">
					<up-textarea
						v-model="answerList[index].remark"
						placeholder="请输入备注信息"
					></up-textarea>
				</view>
				</block>
			</view>

			<button
				v-if="pendingSubmitCount > 0"
				class="bg-blue round margin-top-xl submit-btn"
				@click="handleSubmitAll"
			>
				提交已填写项（{{ pendingSubmitCount }}项）
			</button>
			</view>
		</template>

		<HazardFormPopup
			v-if="activeHazardIndex >= 0"
			ref="hazardFormRef"
			v-model:show="showHazardPopup"
			v-model="editingHazardPayload"
			title="填写隐患信息"
			mode="collect"
			body-height="60vh"
			:extra-params="hazardFormExtraParams"
			@confirm="onHazardConfirm"
		/>

		<u-popup
			:show="showCheckSheet"
			mode="bottom"
			round="20"
			:safe-area-inset-bottom="true"
			@close="closeCheckSheet"
		>
			<view class="check-sheet-popup">
				<view class="check-sheet-header">
					<view class="check-sheet-title">检查项导航</view>
					<view class="check-sheet-subtitle">
						共 {{ checkItemList.length }} 个检查项
					</view>
				</view>

				<scroll-view class="check-sheet-grid-wrap" scroll-y>
					<view class="check-sheet-grid">
						<view
							v-for="(item, index) in checkItemList"
							:key="'sheet-nav-' + index"
							class="check-sheet-cell"
							:class="getSheetCellClass(index)"
							@click="scrollToItem(index)"
						>
							{{ index + 1 }}
						</view>
					</view>
				</scroll-view>

				<view class="check-sheet-footer">
					<view class="check-sheet-legend">
						<view class="legend-item">
							<view class="legend-dot legend-dot--submitted"></view>
							<text>已提交 {{ submittedCount }}</text>
						</view>
						<view class="legend-item">
							<view class="legend-dot legend-dot--pending"></view>
							<text>待提交 {{ pendingSubmitCount }}</text>
						</view>
						<view class="legend-item">
							<view class="legend-dot legend-dot--todo"></view>
							<text>待检查 {{ uncheckedCount }}</text>
						</view>
					</view>
					<button
						v-if="pendingSubmitCount > 0"
						class="check-sheet-submit-btn"
						@click="handleSheetSubmit"
					>
						立即提交
					</button>
				</view>
			</view>
		</u-popup>
	</view>
</template>

<script setup>
import { ref, computed, nextTick } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { getAllTask, submitAllTask } from '@/request/api.js';
import HazardFormPopup from '@/components/hazard/HazardFormPopup.vue';
import { buildDraftKey, DRAFT_NS, loadDraftWithFallback, saveDraftToStorage, removeDraft } from '@/utils/draftCache.js';
import { useDraftCache } from '@/utils/useDraftCache.js';
import {
	LEVEL_OPTIONS,
	SOURCE_OPTIONS,
	createEmptyHazardPayload,
	buildHiddenDangerParams,
	hasValidHazardPayload
} from '@/components/hazard';

const oneTableId = ref('');
const tableId = ref('');
const taskDate = ref('');
const planName = ref('');
const loading = ref(true);
const checkItemList = ref([]);
const answerList = ref([]);
const sessionSubmittedTaskIds = ref(new Set());

const showHazardPopup = ref(false);
const showCheckSheet = ref(false);
const activeHazardIndex = ref(-1);
const hazardFormRef = ref(null);
const editingHazardPayload = ref(createEmptyHazardPayload());

const resultOptions = [
	{ name: '正常', value: 1 },
	{ name: '异常', value: 2 },
	{ name: '不涉及', value: 3 }
];

const TASK_STATUS_SUBMITTED = 2;

const syncSubmittedTaskIds = (list) => {
	const next = new Set(sessionSubmittedTaskIds.value);
	(list || []).forEach((item) => {
		if (item?.status === TASK_STATUS_SUBMITTED && item.taskId != null) {
			next.add(item.taskId);
		}
	});
	sessionSubmittedTaskIds.value = next;
};

const isItemSubmitted = (item) => {
	if (!item) return false;
	if (item.status === TASK_STATUS_SUBMITTED) return true;
	if (item.taskId != null && sessionSubmittedTaskIds.value.has(item.taskId)) return true;
	return false;
};

const getResultLabel = (result) => {
	const opt = resultOptions.find((o) => o.value === result);
	return opt?.name || '-';
};

const getResultTagClass = (result) => {
	if (result === 1) return 'result-tag--normal';
	if (result === 2) return 'result-tag--abnormal';
	if (result === 3) return 'result-tag--na';
	return '';
};

const viewHazardDetail = (item) => {
	if (!item?.hazardId) {
		uni.showToast({ title: '暂无隐患信息', icon: 'none' });
		return;
	}
	uni.navigateTo({
		url: `/pages/hiddendanger/view?hazardId=${item.hazardId}`
	});
};

const sheetTitle = computed(() => {
	return planName.value || checkItemList.value[0]?.itemName || '检查表';
});

const industryName = computed(() => checkItemList.value[0]?.industryName || '');

const createEmptyAnswer = () => ({
	resultLabel: '',
	result: null,
	remark: '',
	hazardPayload: createEmptyHazardPayload()
});

const normalizeSheetAnswer = (answer) => {
	if (!answer) return createEmptyAnswer();

	const hazardPayload = answer.hazardPayload || createEmptyHazardPayload();
	const empty = createEmptyHazardPayload();

	return {
		resultLabel: answer.resultLabel || '',
		result: answer.result ?? null,
		remark: answer.remark || '',
		hazardPayload: {
			formData: {
				...empty.formData,
				...(hazardPayload.formData || {})
			},
			address: hazardPayload.address || '',
			lng: hazardPayload.lng || 0,
			lat: hazardPayload.lat || 0,
			areaId: hazardPayload.areaId || '',
			areaName: hazardPayload.areaName || '',
			fileList: Array.isArray(hazardPayload.fileList) ? [...hazardPayload.fileList] : [],
			tagOptions: Array.isArray(hazardPayload.tagOptions) ? [...hazardPayload.tagOptions] : []
		}
	};
};

const syncAnswerFields = (answer) => {
	const normalized = normalizeSheetAnswer(answer);
	if (!normalized.resultLabel && normalized.result != null) {
		const opt = resultOptions.find((o) => o.value === normalized.result);
		if (opt) normalized.resultLabel = opt.name;
	} else if (normalized.resultLabel && normalized.result == null) {
		const opt = resultOptions.find((o) => o.name === normalized.resultLabel);
		if (opt) normalized.result = opt.value;
	}
	return normalized;
};

const buildAnswerFromTask = (item) => {
	const answer = createEmptyAnswer();
	if (!isItemSubmitted(item)) {
		return answer;
	}

	answer.result = item.result;
	answer.remark = item.remark || '';
	const opt = resultOptions.find((o) => o.value === item.result);
	if (opt) {
		answer.resultLabel = opt.name;
	}

	if (item.result === 2 && item.hazardName) {
		const sourceIndex = SOURCE_OPTIONS.findIndex((o) => o.title === item.source);
		answer.hazardPayload = {
			...createEmptyHazardPayload(),
			formData: {
				...createEmptyHazardPayload().formData,
				title: item.hazardName || '',
				description: item.hazardDesc || '',
				source: sourceIndex >= 0 ? sourceIndex : 0
			},
			address: item.hazardAddress || ''
		};
	}

	return syncAnswerFields(answer);
};

const isAnswerFilled = (answer) => {
	if (!answer) return false;
	return !!(answer.resultLabel || answer.result != null);
};

const hasAnswerDraftContent = (answer) => {
	if (!answer) return false;
	const normalized = normalizeSheetAnswer(answer);
	const hazard = normalized.hazardPayload;
	return !!(
		normalized.resultLabel ||
		normalized.result != null ||
		normalized.remark ||
		hazard.formData?.title ||
		hazard.formData?.description ||
		(hazard.fileList && hazard.fileList.length > 0)
	);
};

const buildDraftAnswers = () => {
	return checkItemList.value
		.map((item, index) => {
			if (isItemSubmitted(item)) return null;
			const answer = answerList.value[index] || createEmptyAnswer();
			if (!hasAnswerDraftContent(answer)) return null;
			return {
				taskId: item.taskId,
				...JSON.parse(JSON.stringify(answer))
			};
		})
		.filter(Boolean);
};

const pruneDraftSubmitted = (taskIds = []) => {
	const key = buildDraftKey(DRAFT_NS.INSPECTION_SHEET, oneTableId.value, taskDate.value);
	const { data } = loadDraftWithFallback(key);
	if (!data?.answers?.length) return;

	const submittedSet = new Set(taskIds);
	const remainingAnswers = data.answers.filter(
		(answer) => answer?.taskId == null || !submittedSet.has(answer.taskId)
	);

	if (!remainingAnswers.length) {
		removeDraft(key);
		return;
	}

	saveDraftToStorage(key, {
		...data,
		answers: remainingAnswers
	});
};

const isItemPendingSubmit = (index) => {
	const item = checkItemList.value[index];
	return !isItemSubmitted(item) && isAnswerFilled(answerList.value[index]);
};

const submittedCount = computed(() => {
	return checkItemList.value.filter(isItemSubmitted).length;
});

const pendingSubmitCount = computed(() => {
	return checkItemList.value.filter((item, index) => isItemPendingSubmit(index)).length;
});

const uncheckedCount = computed(() => {
	return Math.max(checkItemList.value.length - submittedCount.value - pendingSubmitCount.value, 0);
});

const getSheetCellClass = (index) => {
	const item = checkItemList.value[index];
	if (isItemSubmitted(item)) return 'check-sheet-cell--submitted';
	if (isItemPendingSubmit(index)) return 'check-sheet-cell--pending';
	return '';
};

const progressPercent = computed(() => {
	if (!checkItemList.value.length) return 0;
	return Math.round((submittedCount.value / checkItemList.value.length) * 100);
});

const sheetDraftHasContent = (data) => {
	if (!data?.answers?.length) return false;

	return data.answers.some((answer) => hasAnswerDraftContent(answer));
};

const {
	showRestoreBanner,
	clear: clearDraft,
	restore: restoreDraft,
	bindAutoSave
} = useDraftCache({
	getKey: () => buildDraftKey(DRAFT_NS.INSPECTION_SHEET, oneTableId.value, taskDate.value),
	getPayload: () => ({
		oneTableId: oneTableId.value,
		taskDate: taskDate.value,
		planName: planName.value,
		answers: buildDraftAnswers()
	}),
	hasContent: sheetDraftHasContent,
	applyPayload: (data) => {
		if (!data?.answers?.length || !checkItemList.value.length) return;

		// 优先按数组下标恢复，已提交项以接口数据为准
		answerList.value = checkItemList.value.map((item, index) => {
			if (isItemSubmitted(item)) {
				return buildAnswerFromTask(item);
			}

			const savedByIndex = data.answers[index];
			if (savedByIndex && sheetDraftHasContent({ answers: [savedByIndex] })) {
				return syncAnswerFields(savedByIndex);
			}
			if (item.taskId != null && item.taskId !== '') {
				const savedByTaskId = data.answers.find((a) => a.taskId === item.taskId);
				if (savedByTaskId) {
					return syncAnswerFields(savedByTaskId);
				}
			}
			return createEmptyAnswer();
		});

		if (data.planName && !planName.value) {
			planName.value = data.planName;
		}
	},
	clearForm: () => {
		answerList.value = checkItemList.value.map((item) => (
			isItemSubmitted(item) ? buildAnswerFromTask(item) : createEmptyAnswer()
		));
	},
	canSave: () => !!oneTableId.value && !!taskDate.value && checkItemList.value.length > 0,
	requireInitialized: true
});

bindAutoSave(() => answerList.value);

const onResultChange = (index, label) => {
	const answer = answerList.value[index];
	if (!answer) return;
	answer.resultLabel = label;
	const selected = resultOptions.find((opt) => opt.name === label);
	answer.result = selected ? selected.value : null;
	if (label !== '异常') {
		answer.hazardPayload = createEmptyHazardPayload();
	}
};

const hazardFormExtraParams = computed(() => {
	const index = activeHazardIndex.value;
	const taskId = index >= 0 ? checkItemList.value[index]?.taskId : '';
	return {
		locationDraftKey: `hazard_location_${oneTableId.value}_${taskDate.value}_${taskId || index}`
	};
});

const hasHazardData = (index) => hasValidHazardPayload(answerList.value[index]?.hazardPayload);

const openHazardPopup = (index) => {
	activeHazardIndex.value = index;
	editingHazardPayload.value = JSON.parse(JSON.stringify(
		answerList.value[index]?.hazardPayload ?? createEmptyHazardPayload()
	));
	showHazardPopup.value = true;
};

const closeHazardPopup = () => {
	showHazardPopup.value = false;
	activeHazardIndex.value = -1;
	editingHazardPayload.value = createEmptyHazardPayload();
};

const onHazardConfirm = (payload) => {
	const index = activeHazardIndex.value;
	const data = payload || editingHazardPayload.value;
	if (index >= 0 && data && answerList.value[index]) {
		answerList.value[index].hazardPayload = JSON.parse(JSON.stringify(data));
	}
	closeHazardPopup();
};

const clearHazard = (index) => {
	if (answerList.value[index]) {
		answerList.value[index].hazardPayload = createEmptyHazardPayload();
	}
};

const openCheckSheet = () => {
	showCheckSheet.value = true;
};

const closeCheckSheet = () => {
	showCheckSheet.value = false;
};

const handleSheetSubmit = () => {
	closeCheckSheet();
	handleSubmitAll();
};

const scrollToItem = (index) => {
	closeCheckSheet();
	nextTick(() => {
		uni.pageScrollTo({
			selector: `#check-item-${index}`,
			duration: 300,
			offsetTop: -80
		});
	});
};

const getFilledAnswerIndices = () => {
	const indices = [];
	for (let i = 0; i < checkItemList.value.length; i++) {
		if (!isItemSubmitted(checkItemList.value[i]) && isAnswerFilled(answerList.value[i])) {
			indices.push(i);
		}
	}
	return indices;
};

const validateFilledAnswers = () => {
	const indices = getFilledAnswerIndices();
	if (!indices.length) {
		uni.showToast({ title: '请先填写待提交的检查项', icon: 'none' });
		return null;
	}

	for (const index of indices) {
		const answer = answerList.value[index];
		if (answer.resultLabel === '异常' && !hasValidHazardPayload(answer.hazardPayload)) {
			uni.showToast({ title: `第 ${index + 1} 项为异常，请填写隐患信息`, icon: 'none' });
			return null;
		}
	}

	return indices;
};

const buildSubmitPayload = (filledIndices) => {
	return filledIndices
		.filter((index) => !isItemSubmitted(checkItemList.value[index]))
		.map((index) => {
			const item = checkItemList.value[index];
			const answer = syncAnswerFields(answerList.value[index]);
			const payload = {
				taskId: item.taskId,
				result: answer.result,
				remark: answer.remark || ''
			};

			if (answer.resultLabel === '异常' && hasValidHazardPayload(answer.hazardPayload)) {
				payload.hazard = buildHiddenDangerParams(answer.hazardPayload, {
					taskId: item.taskId,
					checkPointId: item.checkPointId
				});
			}

			return payload;
		});
};

const goToListPage = () => {
	uni.navigateBack();
};

const handleSubmitAll = async () => {
	const filledIndices = validateFilledAnswers();
	if (!filledIndices) return;

	const submitList = buildSubmitPayload(filledIndices);
	if (!submitList.length) {
		uni.showToast({ title: '没有可提交的新检查项', icon: 'none' });
		return;
	}

	try {
		uni.showLoading({ title: '提交中...' });
		const res = await submitAllTask(submitList);
		uni.hideLoading();

		if (res.code === 0) {
			const nextSubmitted = new Set(sessionSubmittedTaskIds.value);
			submitList.forEach((item) => {
				if (item.taskId != null) {
					nextSubmitted.add(item.taskId);
				}
			});
			sessionSubmittedTaskIds.value = nextSubmitted;
			pruneDraftSubmitted(submitList.map((item) => item.taskId));
			uni.showToast({
				title: `已成功提交 ${submitList.length} 项`,
				icon: 'success'
			});
			setTimeout(() => {
				goToListPage();
			}, 1500);
		} else {
			uni.showToast({ title: res.msg || '提交失败', icon: 'none' });
		}
	} catch (error) {
		uni.hideLoading();
		console.error('提交失败:', error);
		uni.showToast({ title: '提交失败', icon: 'none' });
	}
};

const fetchDetail = async () => {
	if (!oneTableId.value || !taskDate.value) {
		loading.value = false;
		uni.showToast({ title: '缺少任务参数', icon: 'none' });
		return;
	}
	loading.value = true;
	try {
		const res = await getAllTask(oneTableId.value, taskDate.value);
		if (res.code === 0) {
			const list = Array.isArray(res.data) ? res.data : (res.data?.records || []);
			syncSubmittedTaskIds(list);
			checkItemList.value = list;
			answerList.value = list.map((item) => buildAnswerFromTask(item));
			restoreDraft();
		} else {
			uni.showToast({ title: res.msg || '获取检查项失败', icon: 'none' });
		}
	} catch (error) {
		console.error('获取检查项失败:', error);
		uni.showToast({ title: '获取检查项失败', icon: 'none' });
	} finally {
		loading.value = false;
	}
};

onLoad((options) => {
	if (options.oneTableId) {
		oneTableId.value = options.oneTableId;
	} else if (options.id) {
		oneTableId.value = options.id;
	}
	if (options.taskDate) {
		taskDate.value = decodeURIComponent(options.taskDate).split(' ')[0];
	}
	if (options.name) {
		planName.value = decodeURIComponent(options.name);
	}
	if (options.tableId) {
		tableId.value = options.tableId;
	}
	fetchDetail();
});
</script>

<style lang="scss" scoped>
.page {
	min-height: 100vh;
	background: #EBF2FC;
	padding-bottom: 40rpx;
}

.page-content {
	padding-bottom: 40rpx;
}

.empty-tip {
	font-size: 28rpx;
}

.sheet-header {
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}

.float-nav {
	position: sticky;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	background: #fff;
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
	padding: 20rpx 24rpx;
}

.float-nav-body {
	display: flex;
	align-items: center;
	gap: 20rpx;
}

.float-nav-main {
	flex: 1;
	min-width: 0;
}

.sheet-nav-btn {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 72rpx;
	height: 72rpx;
	background: #eef3ff;
	border-radius: 16rpx;
}

.question-card {
	box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
}

.question-card--submitted {
	background: #f8faf8;
	border: 1rpx solid #e8f5e9;
}

.question-header-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16rpx;
}

.question-index {
	display: inline-block;
	padding: 4rpx 16rpx;
	font-size: 24rpx;
	color: #2667E9;
	background: #EEF3FF;
	border-radius: 8rpx;
}

.submitted-tag {
	padding: 4rpx 16rpx;
	font-size: 22rpx;
	color: #52c41a;
	background: #f6ffed;
	border: 1rpx solid #b7eb8f;
	border-radius: 8rpx;
	white-space: nowrap;
}

.pending-tag {
	padding: 4rpx 16rpx;
	font-size: 22rpx;
	color: #2667e9;
	background: #eef3ff;
	border: 1rpx solid #adc6ff;
	border-radius: 8rpx;
	white-space: nowrap;
}

.readonly-block,
.answer-panel {
	padding: 20rpx;
	background: #f7f8fa;
	border: 1rpx solid #e8e8e8;
	border-radius: 12rpx;
}

.readonly-row {
	display: flex;
	align-items: center;
	gap: 16rpx;
	margin-bottom: 12rpx;
	font-size: 26rpx;
	line-height: 1.6;

	&:last-child {
		margin-bottom: 0;
	}
}

.readonly-row--stack {
	align-items: flex-start;
}

.hazard-summary {
	margin-top: 16rpx;
	padding-top: 16rpx;
	border-top: 1rpx dashed #e0e0e0;
}

.readonly-label {
	flex-shrink: 0;
	color: #999;
	min-width: 120rpx;
}

.readonly-value {
	flex: 1;
	color: #333;
	word-break: break-all;
}

.result-tag {
	display: inline-flex;
	align-items: center;
	padding: 4rpx 16rpx;
	border-radius: 8rpx;
	font-size: 24rpx;
	font-weight: 500;
	line-height: 1.4;
	white-space: nowrap;
}

.result-tag--normal {
	background: #f6ffed;
	border: 1rpx solid #b7eb8f;
	color: #52c41a;
}

.result-tag--abnormal {
	background: #fff1f0;
	border: 1rpx solid #ffa39e;
	color: #f5222d;
}

.result-tag--na {
	background: #f5f5f5;
	border: 1rpx solid #d9d9d9;
	color: #8c8c8c;
}

.view-hazard-btn {
	margin-top: 20rpx;
	width: 100%;
	height: 72rpx;
	line-height: 72rpx;
	font-size: 28rpx;
	color: #2667e9;
	background: #fff;
	border: 1rpx solid #adc6ff;
	border-radius: 12rpx;

	&::after {
		border: none;
	}
}

.progress-text {
	display: flex;
	align-items: baseline;
	margin-bottom: 16rpx;

	.current-index {
		font-size: 26rpx;
		font-weight: bold;
		color: #2667E9;
	}

	.total-count {
		font-size: 24rpx;
		color: #999;
	}
}

.progress-line {
	height: 12rpx;
	background: #E5E5E5;
	border-radius: 6rpx;
	overflow: hidden;
}

.progress-inner {
	height: 100%;
	background: linear-gradient(90deg, #2667E9, #5B9BFF);
	border-radius: 6rpx;
	transition: width 0.3s ease;
}

.hazard-section {
	border-top: 1rpx solid #eee;
	padding-top: 20rpx;
}

.hazard-tip {
	display: flex;
	align-items: center;
	padding: 16rpx 20rpx;
	background: #FFF7E6;
	border: 1rpx solid #FFE7BA;
	border-radius: 8rpx;
	margin-bottom: 20rpx;

	.text-orange {
		color: #FA8C16;
		font-size: 26rpx;
	}
}

.hazard-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 88rpx;
	border: 2rpx dashed #2667E9;
	border-radius: 12rpx;
	background: #F5F9FF;

	.text-blue {
		color: #2667E9;
		font-size: 28rpx;
	}
}

.hazard-card {
	background: #F5F9FF;
	border: 1rpx solid #D6E4FF;
	border-radius: 12rpx;
	overflow: hidden;

	.card-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20rpx;
		border-bottom: 1rpx solid #E8E8E8;
		background: #fff;
	}

	.card-body {
		padding: 20rpx;

		.info-row {
			display: flex;
			margin-bottom: 12rpx;
			font-size: 26rpx;

			&:last-child {
				margin-bottom: 0;
			}

			.text-gray {
				flex-shrink: 0;
				color: #999;
			}

			.description-text {
				display: -webkit-box;
				-webkit-line-clamp: 2;
				-webkit-box-orient: vertical;
				overflow: hidden;
				text-overflow: ellipsis;
			}
		}
	}

	.card-footer {
		display: flex;
		border-top: 1rpx solid #E8E8E8;
		background: #fff;

		button {
			flex: 1;
			height: 80rpx;
			line-height: 80rpx;
			font-size: 28rpx;
			border-radius: 0;

			&::after {
				border: none;
			}
		}

		.btn-edit {
			background: #fff;
			color: #2667E9;
			border-right: 1rpx solid #E8E8E8;
		}

		.btn-clear {
			background: #fff;
			color: #F56C6C;
		}
	}
}

.level-tag {
	padding: 4rpx 16rpx;
	border-radius: 8rpx;
	font-size: 24rpx;
}

.level-minor {
	background: #F6FFED;
	border: 2rpx solid #B7EB8F;
	color: #52C41A;
}

.level-normal {
	background: #FFF7E6;
	border: 2rpx solid #FFD591;
	color: #FA8C16;
}

.level-major {
	background: #FFF1F0;
	border: 2rpx solid #FFA39E;
	color: #F5222D;
}

.submit-btn {
	margin-bottom: 40rpx;
}

.draft-banner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 20rpx 24rpx;
	font-size: 24rpx;
	color: #fa8c16;
	background: #fff7eb;
	border: 1rpx solid #ffe4cc;
	border-radius: 12rpx;
}

.draft-banner-left {
	display: flex;
	align-items: center;
	flex: 1;
	min-width: 0;
}

.draft-banner-icon {
	margin-right: 10rpx;
}

.draft-banner-action {
	flex-shrink: 0;
	margin-left: 16rpx;
	color: #2667e9;
	font-weight: bold;
}

.check-sheet-popup {
	padding: 32rpx 32rpx calc(24rpx + env(safe-area-inset-bottom));
	background: #fff;
}

.check-sheet-header {
	margin-bottom: 24rpx;
}

.check-sheet-title {
	font-size: 34rpx;
	font-weight: bold;
	color: #333;
}

.check-sheet-subtitle {
	margin-top: 8rpx;
	font-size: 26rpx;
	color: #999;
}

.check-sheet-grid-wrap {
	max-height: 52vh;
}

.check-sheet-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 20rpx;
	padding-bottom: 8rpx;
}

.check-sheet-cell {
	width: calc((100% - 80rpx) / 5);
	height: 88rpx;
	line-height: 88rpx;
	text-align: center;
	font-size: 28rpx;
	color: #666;
	background: #fff;
	border: 2rpx solid #e5e5e5;
	border-radius: 12rpx;
	box-sizing: border-box;
}

.check-sheet-cell--pending {
	color: #fff;
	background: #2667e9;
	border-color: #2667e9;
}

.check-sheet-cell--submitted {
	color: #52c41a;
	background: #f6ffed;
	border-color: #b7eb8f;
}

.check-sheet-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24rpx;
	margin-top: 28rpx;
	padding-top: 24rpx;
	border-top: 1rpx solid #f0f0f0;
}

.check-sheet-legend {
	display: flex;
	align-items: center;
	gap: 32rpx;
	flex: 1;
	min-width: 0;
	font-size: 26rpx;
	color: #666;
}

.check-sheet-submit-btn {
	flex-shrink: 0;
	height: 72rpx;
	line-height: 72rpx;
	padding: 0 36rpx;
	margin: 0;
	font-size: 28rpx;
	font-weight: 500;
	color: #fff;
	background: linear-gradient(135deg, #4facfe 0%, #2668ea 100%);
	border-radius: 36rpx;
	border: none;
	box-shadow: 0 4rpx 16rpx rgba(38, 104, 234, 0.3);

	&::after {
		border: none;
	}
}

.legend-item {
	display: flex;
	align-items: center;
	gap: 12rpx;
}

.legend-dot {
	width: 28rpx;
	height: 28rpx;
	border-radius: 8rpx;
	box-sizing: border-box;
}

.legend-dot--submitted {
	background: #f6ffed;
	border: 2rpx solid #b7eb8f;
}

.legend-dot--pending {
	background: #2667e9;
	border: 2rpx solid #2667e9;
}

.legend-dot--todo {
	background: #fff;
	border: 2rpx solid #e5e5e5;
}
</style>
