<template>
	<div>
		<el-form ref="inputForm" :model="inputForm" v-loading="loading" :class="isViewMode ? 'readonly' : ''"
			:disabled="isDisabled" label-width="110px" @submit.native.prevent>
			<template v-if="showComparePanel">
				<el-alert title="当前展示正式数据与修改稿的对比，高亮项表示发生了变更。" type="info" :closable="false" show-icon
					style="margin-bottom: 16px" />
				<el-divider content-position="left">
					<i class="el-icon-data-analysis"></i> 变更对比
				</el-divider>
				<el-table border size="small" :data="compareBaseRows" class="compare-table" style="margin-bottom: 18px">
					<el-table-column prop="label" label="字段" width="140" />
					<el-table-column label="旧数据">
						<template #default="scope">
							<div class="compare-line old" :class="{ changed: scope.row.changed }">
								{{ scope.row.oldValue }}
							</div>
						</template>
					</el-table-column>
					<el-table-column label="新数据">
						<template #default="scope">
							<div class="compare-line new" :class="{ changed: scope.row.changed }">
								{{ scope.row.newValue }}
							</div>
						</template>
					</el-table-column>
					<el-table-column label="变化" width="110" align="center">
						<template #default="scope">
							<el-tag :type="scope.row.changed ? 'warning' : 'info'" size="small" effect="plain">
								{{ scope.row.changed ? "已变更" : "无变化" }}
							</el-tag>
						</template>
					</el-table-column>
				</el-table>

				<div class="compare-table-wrapper">
					<el-table border size="small" :fit="false" :data="compareDetailRows"
						class="compare-table compare-detail-table">
						<el-table-column type="index" label="序号" width="70" />
						<el-table-column label="变更类型" width="100" align="center">
							<template #default="scope">
								<el-tag size="small" effect="plain" :type="getCompareTagType(scope.row.compareType)">
									{{ getCompareTypeLabel(scope.row.compareType) }}
								</el-tag>
							</template>
						</el-table-column>
						<el-table-column label="采购食材名称" min-width="170">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'goodsName') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "goodsName") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'goodsName') }">
										新：{{ getFieldDisplay(scope.row.newRow, "goodsName") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="食材分类" min-width="140">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'foodType') }">
										旧：{{ getFoodTypeLabel(scope.row.oldRow) }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'foodType') }">
										新：{{ getFoodTypeLabel(scope.row.newRow) }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="采购数量" min-width="120">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'purchaseNumber') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "purchaseNumber") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'purchaseNumber') }">
										新：{{ getFieldDisplay(scope.row.newRow, "purchaseNumber") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="单价" min-width="120">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'unitPrice') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "unitPrice") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'unitPrice') }">
										新：{{ getFieldDisplay(scope.row.newRow, "unitPrice") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="总价" min-width="120">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'totalPrice') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "totalPrice") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'totalPrice') }">
										新：{{ getFieldDisplay(scope.row.newRow, "totalPrice") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="存储区域" min-width="160">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'storageArea') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "storageArea") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'storageArea') }">
										新：{{ getFieldDisplay(scope.row.newRow, "storageArea") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="保质期" min-width="160">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'shelfLife') || isFieldChanged(scope.row, 'shelfLifeUnit') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "shelfLife") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'shelfLife') || isFieldChanged(scope.row, 'shelfLifeUnit') }">
										新：{{ getFieldDisplay(scope.row.newRow, "shelfLife") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="到期日期" min-width="160">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'expiryDate') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "expiryDate") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'expiryDate') }">
										新：{{ getFieldDisplay(scope.row.newRow, "expiryDate") }}
									</div>
								</div>
							</template>
						</el-table-column>
						<el-table-column label="备注" min-width="160">
							<template #default="scope">
								<div class="compare-cell">
									<div class="compare-line old"
										:class="{ changed: isFieldChanged(scope.row, 'remarks') }">
										旧：{{ getFieldDisplay(scope.row.oldRow, "remarks") }}
									</div>
									<div class="compare-line new"
										:class="{ changed: isFieldChanged(scope.row, 'remarks') }">
										新：{{ getFieldDisplay(scope.row.newRow, "remarks") }}
									</div>
								</div>
							</template>
						</el-table-column>
					</el-table>
				</div>
			</template>

			<el-divider content-position="left">
				<i class="el-icon-document"></i> 基础信息
			</el-divider>
			<el-row :gutter="20">
				<el-col :span="12">
					<el-form-item label="采购编号" prop="purchaseNo">
						<el-input v-model="inputForm.purchaseNo" disabled placeholder="自动生成" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="采购人" prop="handledBy">
						<el-input v-model="inputForm.handledBy" disabled />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="采购部门" prop="handledByOffice">
						<SelectTree ref="officeTree" :disabled="true" :props="{
							value: 'id',
							label: 'name',
							children: 'children',
						}" :url="`/system-server/sys/office/treeData?type=2`" :value="inputForm.handledByOffice" :accordion="true"
							size="default" @getValue="(value) => (inputForm.handledByOffice = value)" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="采购时间" prop="purchaseTime" :rules="[
						{
							required: true,
							message: '请选择采购时间',
							trigger: 'blur',
						},
					]">
						<el-date-picker v-model="inputForm.purchaseTime" type="datetime"
							value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" placeholder="请选择采购时间" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="备注" prop="remarks">
						<el-input v-model="inputForm.remarks" type="textarea" :rows="4" maxlength="500" show-word-limit
							placeholder="请输入备注信息" />
					</el-form-item>
				</el-col>
			</el-row>

			<el-divider content-position="left">
				<i class="el-icon-document"></i> 采购明细
				<el-button style="margin-left: 20px" type="primary" plain :disabled="isDisabled" @click="insertEvent">
					新增
				</el-button>
			</el-divider>

			<el-row :gutter="15">
				<el-col :span="24">
					<vxe-table ref="detailTable" border show-footer show-overflow class="vxe-table-element"
						:data="inputForm.detailInfos" style="margin-left: 5em" :key="clientTableKey"
						highlight-current-row :footer-method="footerMethod" :edit-config="{
							trigger: 'click',
							mode: 'row',
							showStatus: false,
							autoClear: !produceDateSelectVisible && !shelfLifeUnitSelectVisible,
							icon: '-',
						}" :edit-rules="validRules">
						<vxe-table-column field="goodsName" title="采购食材名称" min-width="170" :edit-render="{}" :rules="[
							{
								required: true,
								message: '请填写采购食材名称',
								trigger: 'blur',
							},
						]">
							<template #edit="scope">
								<el-input v-model="scope.row.goodsName" maxlength="100" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="foodType" title="食材分类" min-width="140" :edit-render="{}">
							<template #edit="scope">
								<el-select v-model="scope.row.foodType" clearable placeholder="请选择" style="width: 100%"
									@visible-change="handleProduceDateVisibleChange">
									<el-option v-for="item in $dictUtils.getDictList('food_type')" :key="item.value"
										:label="item.label" :value="item.value" />
								</el-select>
							</template>
							<template #default="scope">
								{{ $dictUtils.getDictLabel("food_type", scope.row.foodType, '-') }}
							</template>
						</vxe-table-column>
						<vxe-table-column field="purchaseNumber" title="采购数量" min-width="120" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.purchaseNumber" maxlength="10"
									@blur="handleNumberBlur(scope.row, 'purchaseNumber')" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="unit" title="单位" min-width="100" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.unit" maxlength="20" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="unitPrice" title="单价" min-width="120" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.unitPrice" maxlength="15"
									@blur="handleNumberBlur(scope.row, 'unitPrice')" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="totalPrice" title="总价" min-width="120" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.totalPrice" maxlength="15"
									@blur="handleTotalPriceBlur(scope.row)" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="storageArea" title="存储区域" min-width="140" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.storageArea" maxlength="100" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="shelfLife" title="保质期" min-width="160" :edit-render="{}">
							<template #default="scope">
								<span>{{ formatShelfLifeDisplay(scope.row) }}</span>
							</template>
							<template #edit="scope">
								<el-input v-model="scope.row.shelfLife" maxlength="64">
									<template #append>
										<el-select v-model="scope.row.shelfLifeUnit" style="width: 70px"
											@visible-change="handleShelfLifeUnitVisibleChange">
											<el-option label="年" value="年" />
											<el-option label="月" value="月" />
											<el-option label="天" value="天" />
										</el-select>
									</template>
								</el-input>
							</template>
						</vxe-table-column>
						<vxe-table-column field="expiryDate" title="到期日期" min-width="150" :edit-render="{}">
							<template #edit="scope">
								<el-date-picker v-model="scope.row.expiryDate" type="date" value-format="YYYY-MM-DD"
									style="width: 100%" placeholder="请选择日期" />
							</template>
						</vxe-table-column>
						<vxe-table-column field="remarks" title="备注" min-width="140" :edit-render="{}">
							<template #edit="scope">
								<el-input v-model="scope.row.remarks" maxlength="255" />
							</template>
						</vxe-table-column>
						<vxe-table-column title="操作" width="100" align="center">
							<template #default="scope">
								<vxe-button size="small" status="danger" :disabled="isDisabled"
									@click="removeEvent(scope.row, scope.$rowIndex)">
									删除
								</vxe-button>
							</template>
						</vxe-table-column>
					</vxe-table>
				</el-col>
			</el-row>
		</el-form>
		<UpLoadComponent v-show="false" ref="uploadComponent" />
	</div>
</template>

<script>
import SelectTree from "@/components/treeSelect/treeSelect.vue";
import FoodPurchaseService from "@/api/psi/FoodPurchaseService";
import UpLoadComponent from "@/views/common/UpLoadComponent";

export default {
	components: {
		SelectTree,
		UpLoadComponent,
	},
	props: {
		businessId: {
			type: String,
			default: "",
		},
		formReadOnly: {
			type: Boolean,
			default: false,
		},
		status: {
			type: String,
			default: "",
		},
	},
	data() {
		return {
			produceDateSelectVisible: false,
			shelfLifeUnitSelectVisible: false,
			method: "",
			loading: false,
			keyWatch: "",
			clientTableKey: "",
			validRules: {
				goodsName: [
					{ required: true, message: "采购食材名称不能为空" },
				],
			},
			resolvedBusinessTable: "",
			inputForm: this.createDefaultForm(),
			originalForm: this.createDefaultForm(true),
			compareBaseRows: [],
			compareDetailRows: [],
		};
	},
	created() {
		this.foodPurchaseService = new FoodPurchaseService();
	},
	computed: {
		bus: {
			get() {
				return this.businessId;
			},
			set(val) {
				this.businessId = val;
			},
		},
		isViewMode() {
			return this.method === "view";
		},
		isDisabled() {

			return (
				this.method === "view" ||
				this.status === "audit" ||
				this.status === "taskFormDetail" ||
				this.formReadOnly
			);
		},
		showComparePanel() {
			const changeStatus = this.inputForm?.status || "";
			return (
				this.isChangeBusiness() &&
				changeStatus !== "4" &&
				(
					this.formReadOnly ||
					this.status === "taskFormDetail" ||
					this.method === "view" ||
					this.commonJS.isNotEmpty(this.$route.query.taskId)
				)
			);
		},
	},
	watch: {
		keyWatch() {
			if (this.commonJS.isNotEmpty(this.bus)) {
				this.init("", this.bus);
			}
		},
		loading(newVal) {
			this.$emit("changeLoading", newVal);
			if (this.$refs.uploadComponent) {
				this.$refs.uploadComponent.changeLoading(newVal);
			}
		},
	},
	methods: {
		getBasicBusinessTable() {
			return "psi_management_food_purchase_basic";
		},
		getChangeBusinessTable() {
			return "psi_management_food_purchase_change";
		},
		getCurrentBusinessTable() {
			return this.resolvedBusinessTable || this.$route.query.businessTable || "";
		},
		isChangeBusiness() {
			return this.getCurrentBusinessTable() === this.getChangeBusinessTable();
		},
		detectBusinessTable(id) {
			const routeBusinessTable = this.$route.query.businessTable;
			if (this.commonJS.isNotEmpty(routeBusinessTable)) {
				this.resolvedBusinessTable = routeBusinessTable;
				return Promise.resolve(routeBusinessTable);
			}
			if (this.commonJS.isEmpty(id) || id === "false") {
				this.resolvedBusinessTable = "";
				return Promise.resolve("");
			}
			return this.foodPurchaseService.findChangeById(id).then((data) => {
				if (this.commonJS.isNotEmpty(data?.id)) {
					this.resolvedBusinessTable = this.getChangeBusinessTable();
				} else {
					this.resolvedBusinessTable = this.getBasicBusinessTable();
				}
				return this.resolvedBusinessTable;
			}).catch(() => {
				this.resolvedBusinessTable = this.getBasicBusinessTable();
				return this.resolvedBusinessTable;
			});
		},
		findCurrentForm(id) {
			return this.isChangeBusiness()
				? this.foodPurchaseService.findChangeById(id)
				: this.foodPurchaseService.findById(id);
		},
		saveCurrentForm() {
			return this.isChangeBusiness()
				? this.foodPurchaseService.saveChange(this.inputForm)
				: this.foodPurchaseService.save(this.inputForm);
		},
		getKeyWatch(keyWatch) {
			this.keyWatch = keyWatch;
		},
		createDefaultForm(forCompare = false) {
			return {
				id: "",
				sourceBasicId: "",
				purchaseNo: "",
				purchaseTime: forCompare
					? ""
					: this.moment(new Date()).format("YYYY-MM-DD HH:mm:ss"),
				totalPrice: forCompare ? "" : "0.00",
				handledBy: forCompare ? "" : this.$store.state.user.name,
				handledById: forCompare ? "" : this.$store.state.user.id,
				handledByOffice: forCompare
					? ""
					: this.$store.state.user.office.id,
				handledByOfficeName: "",
				remarks: "",
				status: "",
				detailInfos: [],
				files: [],
			};
		},
		hydrateForm(data, forCompare = false) {
			const form = this.recover(this.createDefaultForm(forCompare), data);
			form.id = data?.id || "";
			form.sourceBasicId = data?.sourceBasicId || "";
			form.handledById = data?.handledById || data?.handledBy || "";
			form.handledBy = data?.handledBy || "";
			form.handledByOffice = data?.handledByOffice || "";
			form.handledByOfficeName = data?.handledByOfficeName || "";
			form.detailInfos = (data?.detailInfos || []).map((item) => ({
				...item,
				purchaseNumber: this.formatNumber(item.purchaseNumber),
				unitPrice: this.formatNumber(item.unitPrice),
				totalPrice: this.formatNumber(item.totalPrice),
				shelfLifeUnit: item.shelfLifeUnit || "",
				expiryDate: item.expiryDate || "",
			}));
			form.totalPrice = this.formatNumber(data?.totalPrice);
			form.files = data?.files || [];
			return JSON.parse(JSON.stringify(form));
		},
		rebuildCompareRows() {
			this.compareBaseRows = [
				this.buildCompareBaseRow("采购编号", this.originalForm.purchaseNo, this.inputForm.purchaseNo),
				this.buildCompareBaseRow("采购人", this.originalForm.handledBy, this.inputForm.handledBy),
				this.buildCompareBaseRow(
					"采购部门",
					this.originalForm.handledByOfficeName,
					this.inputForm.handledByOfficeName
				),
				this.buildCompareBaseRow("采购时间", this.originalForm.purchaseTime, this.inputForm.purchaseTime),
				this.buildCompareBaseRow("采购金额", this.originalForm.totalPrice, this.inputForm.totalPrice),
				this.buildCompareBaseRow("备注", this.originalForm.remarks, this.inputForm.remarks),
			];
			this.compareDetailRows = this.buildDetailCompareRows();
		},
		buildCompareBaseRow(label, oldValue, newValue) {
			const oldDisplay = this.formatCompareText(oldValue);
			const newDisplay = this.formatCompareText(newValue);
			return {
				label,
				oldValue: oldDisplay,
				newValue: newDisplay,
				changed: !this.isSameCompareValue(oldDisplay, newDisplay),
			};
		},
		loadCompareSource() {
			if (!this.showComparePanel || this.commonJS.isEmpty(this.inputForm.sourceBasicId)) {
				this.originalForm = this.createDefaultForm(true);
				this.compareBaseRows = [];
				this.compareDetailRows = [];
				return Promise.resolve();
			}
			return this.foodPurchaseService
				.findById(this.inputForm.sourceBasicId)
				.then((data) => {
					this.originalForm = this.hydrateForm(data, true);
					this.rebuildCompareRows();
				});
		},
		init(method, id) {
			if (this.status === 'audit' || this.status === 'taskFormDetail') {
				method = 'view'
			} else {
				method = 'edit'

			}
			this.method = method;
			this.resolvedBusinessTable = this.$route.query.businessTable || "";
			this.inputForm = this.createDefaultForm();
			this.originalForm = this.createDefaultForm(true);
			this.compareBaseRows = [];
			this.compareDetailRows = [];
			this.inputForm.id = id;
			if (this.$refs.uploadComponent) {
				this.$refs.uploadComponent.clearUpload();
			}
			this.$nextTick(() => {
				if (this.$refs.inputForm) {
					this.$refs.inputForm.resetFields();
				}
				if (id && id !== "false") {
					this.loading = true;
					this.detectBusinessTable(id)
						.then(() => this.findCurrentForm(id))
						.then((data) => {
							this.inputForm = this.hydrateForm(data);


							if (this.$refs.uploadComponent) {
								this.$refs.uploadComponent.newUpload(
									this.method ? this.method : "view",
									this.inputForm.files || [],
									"psi"
								);
							}
							return this.loadCompareSource();
						})
						.finally(() => {
							this.loading = false;
						});
				} else if (this.$refs.uploadComponent) {
					this.$refs.uploadComponent.newUpload(
						this.method ? this.method : "view",
						[],
						"psi"
					);
				}
			});
		},
		insertEvent() {
			this.$refs.detailTable.insert().then((row) => {
				row.goodsName = "";
				row.foodType = "";
				row.purchaseNumber = "";
				row.unit = "";
				row.unitPrice = "";
				row.totalPrice = "";
				row.storageArea = "";
				row.shelfLife = "";
				row.shelfLifeUnit = "月";
				row.expiryDate = "";
				row.remarks = "";
				this.inputForm.detailInfos.push(row);
				this.clientTableKey = Math.random();
			});
		},
		removeEvent(row, rowIndex) {
			this.$refs.detailTable.remove(row);
			this.inputForm.detailInfos.splice(rowIndex, 1);
			this.updateBasicTotal();
		},
		handleNumberBlur(row, field) {
			row[field] = this.normalizeNumber(row[field]);
			this.calculateRowTotal(row);
		},
		handleTotalPriceBlur(row) {
			row.totalPrice = this.normalizeNumber(row.totalPrice);
			this.updateBasicTotal();
		},
		calculateRowTotal(row) {
			if (
				this.commonJS.isNotEmpty(row.purchaseNumber) &&
				this.commonJS.isNotEmpty(row.unitPrice)
			) {
				row.totalPrice = (
					parseFloat(row.purchaseNumber || 0) *
					parseFloat(row.unitPrice || 0)
				).toFixed(2);
			}
			this.updateBasicTotal();
		},
		updateBasicTotal() {
			const total = (this.inputForm.detailInfos || []).reduce(
				(sum, item) => sum + Number(item.totalPrice || 0),
				0
			);
			this.inputForm.totalPrice = Number.isNaN(total)
				? "0.00"
				: total.toFixed(2);
			this.clientTableKey = Math.random();
		},
		footerMethod({ columns, data }) {
			const total = data.reduce(
				(sum, item) => sum + Number(item.totalPrice || 0),
				0
			);
			this.inputForm.totalPrice = Number.isNaN(total)
				? "0.00"
				: total.toFixed(2);
			return [
				columns.map((column, columnIndex) => {
					if (columnIndex === 0) {
						return "采购金额";
					}
					if (column.property === "totalPrice") {
						return this.inputForm.totalPrice;
					}
					return null;
				}),
			];
		},
		normalizeNumber(num) {
			if (this.commonJS.isEmpty(num)) {
				return "";
			}
			let str = String(num).trim();
			const len1 = str.substr(0, 1);
			const len2 = str.substr(1, 1);
			if (str.length > 1 && len1 === "0" && len2 !== ".") {
				str = str.substr(1, 1);
			}
			if (len1 === ".") {
				str = "";
			}
			if (str.indexOf(".") !== -1) {
				const decimals = str.substr(str.indexOf(".") + 1);
				if (decimals.indexOf(".") !== -1) {
					str = str.substr(
						0,
						str.indexOf(".") + decimals.indexOf(".") + 1
					);
				}
				if (decimals.length > 2) {
					this.$message.warning("数值小数点后只能输入两位");
					return "";
				}
			}
			return str.replace(/[^\d^.]+/g, "");
		},
		formatNumber(value) {
			if (this.commonJS.isEmpty(value) && value !== 0) {
				return "";
			}
			const num = Number(value);
			if (Number.isNaN(num)) {
				return "";
			}
			return num.toFixed(2);
		},
		formatCompareText(value) {
			return this.commonJS.isEmpty(value) && value !== 0 ? "--" : String(value);
		},
		isSameCompareValue(oldValue, newValue) {
			return String(oldValue || "").trim() === String(newValue || "").trim();
		},
		buildDetailCompareRows() {
			const oldDetails = this.originalForm.detailInfos || [];
			const newDetails = this.inputForm.detailInfos || [];
			const maxLength = Math.max(oldDetails.length, newDetails.length);
			const rows = [];
			for (let index = 0; index < maxLength; index++) {
				const oldRow = oldDetails[index] || null;
				const newRow = newDetails[index] || null;
				const changedFields = this.getChangedFields(oldRow, newRow);
				let compareType = "same";
				if (oldRow && !newRow) {
					compareType = "delete";
				} else if (!oldRow && newRow) {
					compareType = "add";
				} else if (changedFields.length > 0) {
					compareType = "update";
				}
				rows.push({
					oldRow,
					newRow,
					changedFields,
					compareType,
				});
			}
			return rows;
		},
		getChangedFields(oldRow, newRow) {
			const fields = [
				"goodsName",
				"foodType",
				"purchaseNumber",
				"unit",
				"unitPrice",
				"totalPrice",
				"storageArea",
				"shelfLife",
				"shelfLifeUnit",
				"expiryDate",
				"remarks",
			];
			return fields.filter(
				(field) =>
					!this.isSameCompareValue(
						this.getFieldDisplay(oldRow, field),
						this.getFieldDisplay(newRow, field)
					)
			);
		},
		getFieldDisplay(row, field) {
			if (!row) {
				return "--";
			}
			if (field === "foodType") {
				return this.getFoodTypeLabel(row);
			}
			if (field === "shelfLife") {
				return this.formatShelfLifeDisplay(row);
			}
			if (["purchaseNumber", "unitPrice", "totalPrice"].includes(field)) {
				const numberText = this.formatNumber(row[field]);
				return this.formatCompareText(numberText);
			}
			return this.formatCompareText(row[field]);
		},
		formatShelfLifeDisplay(row) {
			if (!row || this.commonJS.isEmpty(row.shelfLife)) {
				return "--";
			}
			if (this.commonJS.isEmpty(row.shelfLifeUnit)) {
				return String(row.shelfLife);
			}
			return `${row.shelfLife} ${row.shelfLifeUnit}`;
		},
		getFoodTypeLabel(row) {
			if (!row || this.commonJS.isEmpty(row.foodType)) {
				return "--";
			}
			return this.$dictUtils.getDictLabel("food_type", row.foodType, "--");
		},
		isFieldChanged(compareRow, field) {
			return (compareRow.changedFields || []).includes(field);
		},
		getCompareTypeLabel(compareType) {
			const labelMap = {
				same: "无变化",
				update: "修改",
				add: "新增",
				delete: "删除",
			};
			return labelMap[compareType] || "修改";
		},
		getCompareTagType(compareType) {
			const typeMap = {
				same: "info",
				update: "warning",
				add: "success",
				delete: "danger",
			};
			return typeMap[compareType] || "warning";
		},
		validateForm() {
			return new Promise((resolve) => {
				this.$refs.inputForm.validate((valid) => {
					if (!valid) {
						resolve(false);
						return;
					}
					if (this.commonJS.isEmpty(this.inputForm.detailInfos)) {
						this.$message.error("请至少填写一条采购明细");
						resolve(false);
						return;
					}
					for (let i = 0; i < this.inputForm.detailInfos.length; i++) {
						const row = this.inputForm.detailInfos[i];
						if (this.commonJS.isEmpty(row.goodsName)) {
							this.$message.error(
								`采购明细第${i + 1}行请填写采购食材名称`
							);
							resolve(false);
							return;
						}
					}
					this.updateBasicTotal();
					resolve(true);
				});
			});
		},
		ensureUploadReady() {
			if (
				this.$refs.uploadComponent &&
				this.$refs.uploadComponent.checkProgress()
			) {
				return false;
			}
			this.inputForm.files = this.$refs.uploadComponent
				? this.$refs.uploadComponent.getDataList()
				: [];
			return true;
		},
		doSubmit() {
			this.validateForm().then((valid) => {
				if (!valid) {
					return;
				}
				if (!this.ensureUploadReady()) {
					return;
				}
				this.loading = true;
				this.foodPurchaseService
					.save(this.inputForm)
					.then(() => {
						this.$message.success("操作成功");
						this.$emit("refreshDataList");
					})
					.finally(() => {
						this.loading = false;
					});
			});
		},
		saveForm(callback) {
			this.validateForm().then((valid) => {
				if (!valid) {
					return;
				}
				if (!this.ensureUploadReady()) {
					return;
				}
				this.loading = true;
				this.inputForm.status = "1";
				this.saveCurrentForm()
					.then(() => {
						callback();
					})
					.finally(() => {
						this.loading = false;
					});
			});
		},
		startForm(callback) {
			this.loading = true;
			if (this.commonJS.isNotEmpty(this.inputForm.id)) {
				this.findCurrentForm(this.inputForm.id).then((data) => {
					const allowStatuses = this.isChangeBusiness()
						? ["1", "3", "4"]
						: ["0", "1", "3", "4", "5"];
					if (
						this.commonJS.isNotEmpty(data.status) &&
						!allowStatuses.includes(data.status)
					) {
						this.loading = false;
						this.$message.error(
							"任务数据已发生变化，请刷新后重试"
						);
						throw new Error("status changed");
					}
					this.startFormTrue(callback);
				});
				return;
			}
			this.startFormTrue(callback);
		},
		startFormTrue(callback) {
			this.validateForm().then((valid) => {
				if (!valid) {
					return;
				}
				if (!this.ensureUploadReady()) {
					return;
				}
				this.loading = true;
				this.inputForm.status = "2";
				this.saveCurrentForm()
					.then((data) => {
						this.inputForm.id = data.businessId;
						callback(data.businessTable, data.businessId, this.inputForm);
					})
					.finally(() => {
						this.loading = false;
					});
			});
		},
		reapplyForm(callback) {
			this.loading = true;
			this.findCurrentForm(this.inputForm.id).then((data) => {
				if (data.status !== "4") {
					this.loading = false;
					this.$message.error("任务数据已发生变化，请在待办中确认");
					throw new Error("status changed");
				}
				this.startFormTrue(callback);
			});
		},
		agreeForm(callback) {
			this.validateForm().then((valid) => {
				if (!valid) {
					return;
				}
				if (!this.ensureUploadReady()) {
					return;
				}
				this.loading = true;
				this.inputForm.status = "5";
				(
					this.isChangeBusiness()
						? this.foodPurchaseService.approveChange(this.inputForm)
						: this.foodPurchaseService.save(this.inputForm)
				)
					.then((data) => {
						callback(data.businessTable, data.businessId, this.inputForm);
					})
					.finally(() => {
						this.loading = false;
					});
			});
		},
		updateStatusById(type, callback) {
			this.loading = true;
			if (type === "reject" || type === "reback") {
				this.findCurrentForm(this.inputForm.id).then((data) => {
					if (data.status !== "2") {
						this.loading = false;
						this.$message.error("任务数据已发生变化，请刷新后重试");
						throw new Error("status changed");
					}
					const status = type === "reject" ? "4" : "3";
					(
						this.isChangeBusiness()
							? this.foodPurchaseService.updateChangeStatusById({
								status,
								id: this.inputForm.id,
							})
							: this.foodPurchaseService.updateStatusById({
								status,
								id: this.inputForm.id,
							})
					).then(() => {
						this.loading = false;
						callback();
					});
				});
				return;
			}
			if (type === "hold") {
				this.findCurrentForm(this.inputForm.id).then((data) => {
					if (data.status !== "4") {
						this.loading = false;
						this.$message.error("任务数据已发生变化，请刷新后重试");
						throw new Error("status changed");
					}
					(
						this.isChangeBusiness()
							? this.foodPurchaseService.updateChangeStatusById({
								status: "1",
								id: this.inputForm.id,
							})
							: this.foodPurchaseService.updateStatusById({
								status: "1",
								id: this.inputForm.id,
							})
					).then(() => {
						this.loading = false;
						callback();
					});
				});
			}
		},
		close() {
			if (this.$refs.inputForm) {
				this.$refs.inputForm.resetFields();
			}
			if (this.$refs.uploadComponent) {
				this.$refs.uploadComponent.clearUpload();
			}
			this.resolvedBusinessTable = "";
			this.inputForm = this.createDefaultForm();
			this.originalForm = this.createDefaultForm(true);
			this.compareBaseRows = [];
			this.compareDetailRows = [];
			this.clientTableKey = Math.random();
		},
		handleProduceDateVisibleChange(visible) {
			this.produceDateSelectVisible = visible;
		},
		handleShelfLifeUnitVisibleChange(visible) {
			this.shelfLifeUnitSelectVisible = visible;
		},
	},
};
</script>

<style scoped>
.el-divider__text {
	font-size: 16px;
	font-weight: bold;
}

.compare-table {
	margin-left: 0;
}

.compare-table-wrapper {
	width: 100%;
	overflow-x: auto;
}

.compare-detail-table {
	min-width: 1500px;
}

.compare-cell {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.compare-line {
	padding: 6px 8px;
	border-radius: 4px;
	line-height: 1.5;
	word-break: break-all;
}

.compare-line.old {
	color: #606266;
	background: #f5f7fa;
}

.compare-line.new {
	color: #0f766e;
	background: #ecfdf5;
}

.compare-line.changed {
	font-weight: 600;
	box-shadow: inset 0 0 0 1px rgba(230, 162, 60, 0.35);
}
</style>
