<template>
	<view class="container">
		<uni-segmented-control :current="current" :values="items" active-color="#2979FF" @clickItem="current = (current + 1) % 2" />
		<t-gap />
		<view v-if="current === 0" class="segmented-wrapper">
			<uni-forms label-position="left" :label-width="75" label-align="right">
				<uni-forms-item label="生产工单" name="pwoCode">
					<uni-easyinput v-model="pwoCode" suffixIcon="scan" @iconClick="handleScanPwoCode" @confirm="fetchPwoJobList"
						placeholder="请输入工单编码" />
				</uni-forms-item>
				<uni-forms-item label="产线" name="proLineId">
					<uni-data-select v-model="proLineId" :localdata="proLineOptions" :disabled="!pwoCode"
						@change="handleSelectProLine" :clear="false" placeholder="请选择产线" />
				</uni-forms-item>
				<uni-forms-item label="开始作业" name="startJobCode">
					<uni-data-select v-model="startJobCode" :localdata="startJobOptions" :disabled="!pwoCode"
						@change="handleJobChange($event, 'start')" :clear="false" placeholder="请选择开始作业" />
				</uni-forms-item>
				<uni-forms-item label="结束作业" name="endJobCode">
					<uni-data-select v-model="endJobCode" :localdata="endJobOptions" :disabled="!pwoCode"
						@change="handleJobChange($event, 'end')" :clear="false" placeholder="请选择结束作业" />
				</uni-forms-item>
				<uni-forms-item label="合格数量">
					<uni-number-box v-model="mesJobReportOnceRequestDTO.pass.reportNumber" />
				</uni-forms-item>
				<uni-forms-item label="不良数量">
					<uni-number-box v-model="mesJobReportOnceRequestDTO.defect.reportNumber" />
				</uni-forms-item>
				<uni-forms-item label="不良原因" v-if="mesJobReportOnceRequestDTO.defect.reportNumber">
					<uni-data-checkbox v-model="mesJobReportOnceRequestDTO.defect.reason" :localdata="defectOptions"
						placeholder="请选择不良原因" />
				</uni-forms-item>
				<uni-forms-item label="报废数量">
					<uni-number-box v-model="mesJobReportOnceRequestDTO.scrap.reportNumber" />
				</uni-forms-item>
				<uni-forms-item label="报废原因" v-if="mesJobReportOnceRequestDTO.scrap.reportNumber">
					<uni-data-checkbox v-model="mesJobReportOnceRequestDTO.scrap.reason" :localdata="scrapOptions"
						placeholder="请选择报废原因" />
				</uni-forms-item>
			</uni-forms>
		</view>
		<view v-if="current === 1" class="segmented-wrapper">
			<uni-card v-for="(item, index) in selectedJobs" :key="index">
				<template #title>
					<view class="header">
						<view class="jobInfo">
							<uni-tag :text="String(index + 1)" />
							<text class="jobCode">
								{{ item.pwoJobCode }}
							</text>
							<uni-tag :text="item.status" :type="item.labelStyle" />
						</view>
					</view>
				</template>
				<view class="card-list">
					<view class="card-item">
						<span class="card-item__label">目标产品编码</span>
						<span class="card-item__value">{{ item.ptNoTar || '/' }}</span>
					</view>
					<view class="card-item">
						<span class="card-item__label">目标产品名称</span>
						<span class="card-item__value">{{ item.ptTitleTar || '/' }}</span>
					</view>
					<view class="card-item">
						<span class="card-item__label">制程名称</span>
						<span class="card-item__value">{{ item.opTitle || '/' }}</span>
					</view>
				</view>
				<view class="card-data">
					<view class="card-data-item">
						<span class="card-data-item__label">完成数量</span>
						<span class="card-data-item__value finish">
							{{ typeof item.finishQty === 'number' ? item.finishQty : '/' }}
						</span>
					</view>
					<view class="card-data-item">
						<span class="card-data-item__label">目标数量</span>
						<span class="card-data-item__value">
							{{ typeof item.targetNum === 'number' ? item.targetNum : '/' }}
						</span>
					</view>
				</view>
				<template #actions>
					<view class="actions">
						<uni-forms-item label="加工人员" :labelWidth="80">
							<uni-easyinput @change="validateEmpCode(index)"
								v-model="item.createByCode">
								<template #right>
									<uni-tag :text="item.createByName" />
									<uni-icons type="scan" size="30" @click="handleScanEmpCode(index)" />
								</template>
							</uni-easyinput>
						</uni-forms-item>
					</view>
				</template>
			</uni-card>
			<u-empty v-if="selectedJobs.length == 0" mode="list" />
			<view class="btns">
				<u-button v-if="startJobCode && endJobCode" type="primary" @click="submit" class="pri-btn">提交</u-button>
			</view>
		</view>
	</view>
</template>

<script>
import { getConfigKey } from '@/api/system/config';
import { listPwo } from '@/api/mes/pwo';
import {
	listPwoJob,
	addReport,
	getEquipment,
	addPipelineReport
} from "@/api/mes/jobReport";
import {
	listEmpEqpHistory,
	listEmployee,
	listConversion
} from "@/api/mes/jobIn";
import { getDicts } from "@/api/system/dict/dictData";
import { listProLine } from "@/api/basic/proLine";
import { listEmployeeInProLines } from "@/api/basic/employee";
import { setProductionLine } from '@/api/mes/pwo';

export default {
	data() {
		return {
			proLineEmployeeDataSet: 1,
			empSelectOptions: [],
			proLineMap: {},
			items: ['报工信息', '作业列表'],
			current: 0,
			dataSet: null,
			isCollapse: false,
			pwoCode: null,
			pwoId: null,
			proLineId: null,
			startJobCode: null,
			endJobCode: null,
			mesJobReportOnceRequestDTO: {
				defect: { reportNumber: 0, reason: null },
				loss: { reportNumber: 0, reason: null },
				pass: { reportNumber: 0, reason: null },
				scrap: { reportNumber: 0, reason: null }
			},
			rawList: [],
			pwoJobList: [],
			startJobOptions: [],
			endJobOptions: [],
			proLineOptions: [],
			defectOptions: [],
			scrapOptions: [],
			statusMap: {},
			selectedJobs: [],
			startIndex: null,
			endIndex: null,
		}
	},
	async mounted() {
		// 获取产线人员对应列表数据源
		await getConfigKey('mes.proline-employee-dataset').then(res => {
			this.proLineEmployeeDataSet = +res.msg;
		});
		// 获取产线列表
		this.fetchProLineOptions();
		// 获取作业状态列表
		this.fetchJobStatusList();
		// 获取不良原因列表
		this.fetchDefectOptions();
		// 获取产线人员对应列表
		this.getEmpOptions();
		console.log('PWO100022136');
	},
	methods: {
		// 获取产线列表
		fetchProLineOptions() {
			this.$modal.loading('加载产线列表...');
			listProLine().then(res => {
				this.$modal.closeLoading();

				res.rows
				.filter(item => !item.delStatus)
				.forEach(item => {
					this.proLineOptions.push({
						text: item.productLineTitle,
						value: item.id,
						proLineCode: item.productLineCode
					})
				})
			}).catch(err => {
				this.$modal.closeLoading();
				this.$modal.alert('加载产线列表失败', err.msg || err);
			})
		},
		// 获取作业状态列表
		fetchJobStatusList() {
			// this.$modal.loading('加载作业类型...');
			getDicts('mes_job_status').then(res => {
				// this.$modal.closeLoading();
				res.data.forEach(item => {
					this.statusMap[item.dictValue] = [item.dictLabel, item.listClass];
				})
			}).catch(err => {
				// this.$modal.closeLoading();
				this.$modal.alert('加载作业列表失败', err.msg || err);
			})
		},
		// 获取不良原因列表
		async fetchDefectOptions() {
			try {
				await getDicts("mes_job_report_defect").then(res => {
					this.defectOptions = res.data.map(dict => {
						return {
							text: dict.dictLabel,
							value: dict.dictValue,
							diasble: false
						}
					});
				})
				await getDicts("mes_job_report_scrap").then(res => {
					this.scrapOptions = res.data.map(dict => {
						return {
							text: dict.dictLabel,
							value: dict.dictValue,
							diasble: false
						}
					});
				})
			} catch (err) {
				this.$modal.msgError('加载不良原因列表失败');
				console.error(`加载不良原因列表失败:\n${err}`);
			}
		},
		// 获取作业列表
		async fetchPwoJobList() {
			if (!this.pwoCode) return;

			this.resetForm();
			this.$modal.loading('获取工单信息...');
			await listPwo({ pwoCode: this.pwoCode }).then(res => {
				this.$modal.closeLoading();
				if (res.total === 1) {
					this.proLineId = res.rows[0].proLineId;
				}
			}).catch(err => {
				this.$modal.closeLoading();
				this.$modal.msgError('获取工单信息失败');
				console.error(`获取工单信息失败:\n${err}`);
				return;
			})
			this.$modal.loading('获取作业列表...');
			await listPwoJob({
				pwoCode: this.pwoCode
			}).then(res => {
				this.$modal.closeLoading();
				this.rawList = res.rows;
				this.pwoId = res.rows[0].pwoId;
				res.rows.forEach((item, index) => {
					this.isCollapse = true;

					this.pwoJobList.push({
						pwoJobCode: item.code,
						status: this.statusMap[item.status][0],
						labelStyle: this.statusMap[item.status][1] || 'default',
						ptTitleTar: item.ptTitleTar,
						ptNoTar: item.ptNoTar,
						opTitle: item.opTitle,
						targetNum: item.targetNum,
						finishQty: item.finishQty,
						createByCode: null
					})

					this.startJobOptions.push({
						text: `${item.code}(${item.opTitle})`,
						value: item.code,
						disable: index === res.rows.length - 1
					})

					this.endJobOptions.push({
						text: `${item.code}(${item.opTitle})`,
						value: item.code,
						disable: index === 0
					})
				})
			}).catch(err => {
				this.$modal.closeLoading();
				console.log(err)
				this.$modal.alert('获取作业列表失败', err.msg || err);
			})
		},
		// 扫描工单编码
		handleScanPwoCode() {
			const _this = this;

			this.$modal.scanCode((res) => {
				if (!res.result) {
					_this.$modal.msg('未扫描到有效值，请重试');
					return;
				}
				_this.pwoCode = res.result;
				_this.fetchPwoJobList();
			});
		},
		// 扫描员工编码
		handleScanEmpCode(index) {
			const _this = this;

			this.$modal.scanCode((res) => {
				if (!res.result) {
					_this.$modal.msg('未扫描到有效值，请重试');
					return;
				}
				_this.selectedJobs[index].createByCode = res.result;
				_this.validateEmpCode(index);
			});
		},
		// 绑定产线
		async handleSelectProLine(e) {
			if (!e) return;

			await setProductionLine({
				pwoId: [this.pwoId],
				productionLineId: this.proLineId
			}).then((res) => {
				if (res.code == 200) {
					this.$modal.msgSuccess("绑定成功");
				}
			}).catch(err => {
				console.error(`绑定失败:${err.msg}`);
				this.proLineId = null;
			});
			
			this.renderEmpInProLine();
		},
		// 根据产线人员对应关系填写人员编码
		async renderEmpInProLine() {
			let proLineChildren = this.proLineMap[this.proLineId];
			proLineChildren = [];

			if (this.proLineEmployeeDataSet === 0) {
				console.log(this.empSelectOptions)
				this.empSelectOptions
				.find(item => item.proLineId == this.proLineId)?.children
				.forEach(item => {
					proLineChildren.push({
						name: item.empName,
						empId: item.value,
						empCode: item.empCode,
						lineNum: item.serialNum,
					});
				})
			} else {
				await listProductLineEmployee(this.proLineId).then((res) => {
					res.rows.forEach(item => {
						proLineChildren.push({
							name: item.employeeName,
							empId: item.employeeId,
							empCode: item.employeeCode,
							lineNum: item.serialNum,
						});
					});
				})
			}

			console.log(proLineChildren);
			this.selectedJobs.forEach((job, index) => {
				const emp = proLineChildren.find(item => item.lineNum == index + 1);
				const empName = emp?.name;
				const empCode = emp?.empCode;
				const empId = emp?.empId;
				this.$set(job, 'createByCode', empCode || null);
				this.$set(job, 'createByName', empName || null);
				this.$set(job, 'createById', empId || null);
				console.log(`第${index + 1}个作业的员工名称为${empName}，id为${empId}`);
			})
		},
		// 获取产线人员对应关系
		async getEmpOptions() {
			// 一人员一产线
			if (this.proLineEmployeeDataSet === 1) {
				const proLineMap = new Map(); // 用于存储产线信息
				await listProLine().then((res) => {
					res.rows.forEach(item => {
						const { id, productLineTitle } = item;

						// 如果产线不存在，初始化产线
						proLineMap.set(id, {
							proLineId: id,
							label: productLineTitle,
							children: []
						});
					})
				})
				await listEmployee().then((res) => {
					res.rows.forEach(item => {
						const { empCode, name, proLineId,id } = item;

						// 添加员工到对应产线
						if (proLineId) {
							proLineMap.get(proLineId).children.push({
								value: id,
								label: empCode + ': ' + name,
								empId: id,
								empName: name,
								empCode: empCode
							});
						}
					});
				});
				// 将Map转换为数组
				this.empSelectOptions = Array.from(proLineMap.values());
			} else {
				// 一人员多产线
				listEmployeeInProLines().then(res => {
					if (!res.data) return;

					res.data.forEach(proLine => {
						const children = proLine.employees.map(emp => {
							return {
								value: emp.id,
								label: emp.employeeCode + ': ' + emp.employeeName,
								empId: emp.id,
								empName: emp.employeeName,
								empCode: emp.employeeCode,
								serialNum: emp.serialNum
							}
						})

						this.empSelectOptions.push({
							proLineId: proLine.id,
							label: proLine.productLineTitle,
							children
						})
					})
				})
			}
		},
		// 校验员工编码
		validateEmpCode(index) {
			if (!this.selectedJobs[index].createByCode) return;
			listEmployee({
				empCode: this.selectedJobs[index].createByCode
			}).then(res => {
				if (res.total === 0) {
					this.$modal.msgError(`员工不存在，请重新输入！`);
					this.selectedJobs[index].createByCode = null;
				} else if (res.total > 1) {
					this.$modal.msgError(`员工编码异常，请联系管理员！`);
					this.selectedJobs[index].createByCode = null;
				} else {
					this.selectedJobs[index].createByName = res.rows[0].name;
					this.selectedJobs[index].createById = res.rows[0].id;
				}
			}).catch(err => {
				this.$modal.msgError(`校验失败，请重试！\n${err}`);
				this.selectedJobs[index].createByCode = null;
			})
		},
		// 重置表单
		resetForm() {
			this.isCollapse = false;
			this.proLineId = null;
			this.startJobCode = null;
			this.endJobCode = null;
			this.mesJobReportOnceRequestDTO = {
				defect: { reportNumber: 0, reason: null },
				loss: { reportNumber: 0, reason: null },
				pass: { reportNumber: 0, reason: null },
				scrap: { reportNumber: 0, reason: null }
			};
			this.pwoJobList = [];
			this.startJobOptions = [];
			this.endJobOptions = [];
			this.selectedJobs = [];
			this.startIndex = null;
			this.endIndex = null;
		},
		// 校验表单
		async validateForm() {
			try {
				if (!this.pwoCode) throw new Error("请填写工单编码");
				if (!this.startJobCode) throw new Error("请选择起始作业");
				if (!this.endJobCode) throw new Error("请选择结束作业");
				if (!this.proLineId) {
					await this.$modal.confirm('未选择产线，是否继续提交').then(res => {
						if (res.cancel) {
							throw new Error("取消提交");
						}
					})
				}

				// 校验报工数量
				let hasReport = false;
				for (const key in this.mesJobReportOnceRequestDTO) {
					const item = this.mesJobReportOnceRequestDTO[key];
					const { reportNumber, reason } = item;

					if (reportNumber !== 0) {
						hasReport = true;
					}

					// 除了 pass，数量不为0 且 原因为空时抛错
					if (key !== "pass" && reportNumber !== 0 && (reason == null || reason === "")) {
						throw new Error("请选择不良原因");
					}
				}
				if (!hasReport) {
					throw new Error("请填写报工数量");
				}

				this.selectedJobs.forEach((item, index) => {
					if (!item.createByCode) {
						throw new Error(`请填写第 ${index + 1} 条作业的加工人员`);
					}
				})

				return true;
			} catch (err) {
				this.$modal.msg(String(err).replace('Error: ', ''));
				console.error(`表单校验失败:\n${err}`);
				return false;
			}
		},
		// 切换作业
		handleJobChange(e, type) {
			if (!e) return;
			switch (type) {
				case 'start':
					this.startIndex = this.pwoJobList.findIndex(item => item.pwoJobCode === e);
					this.endJobOptions.forEach((job, i) => {
						job.disable = i <= this.startIndex;
					})
					break;
				case 'end':
					this.endIndex = this.pwoJobList.findIndex(item => item.pwoJobCode === e);
					this.startJobOptions.forEach((job, i) => {
						job.disable = i >= this.endIndex;
					})
					break;
			}
			this.selectedJobs = [];
			if (typeof this.startIndex === 'number' && typeof this.endIndex === 'number') {
				this.selectedJobs = this.pwoJobList.slice(this.startIndex, this.endIndex + 1);
			}
			
			this.renderEmpInProLine();
		},
		// 提交
		async submit() {
			const res = await this.validateForm();
			if (!res) return;
			
			const submitList = this.rawList.slice(this.startIndex, this.endIndex + 1)
			this.selectedJobs.forEach((item, index) => {
				submitList[this.startIndex + index] = Object.assign({}, submitList[this.startIndex + index], item);
			})

			const data = {
				reasonFrom: "0",
				endTime: this.$time.getTime(),
				endPwoJobId: this.rawList[this.endIndex].id,
				startPwoJobId: this.rawList[this.startIndex].id,
				productLineId: this.proLineId,
				mesJobReportList: submitList,
				mesJobReportOnceRequestDTO: this.mesJobReportOnceRequestDTO
			}

			addPipelineReport(data).then(() => {
				this.$modal.msgSuccess('提交成功');
				setTimeout(() => {
					this.$tab.switchTab("/pages/work/index");
				}, 1000);
			}).catch(err => {
				this.$modal.alert('提交失败', err.msg);
				console.error(`提交失败:\n${err}`);
			})
		}
	}
}
</script>

<style scoped lang="scss">
.container {
	/* #ifdef H5 */
	height: calc(100vh - 44px);
	/* #endif */
	/* #ifndef H5 */
	height: 100vh;
	/* #endif */
	padding: 10px;
	display: flex;
	flex-direction: column;

	.card-list__title {
		background: transparent;
		border-top: 1px solid #d9d9d9;
		margin-top: 5px;
	}

	.segmented-wrapper {
		flex: 1;
		overflow: scroll;
		
		.u-empty {
			height: 100%;
		}
	}

	.uni-card {
		margin: 0 0 10px !important;
		padding: 0 !important;
		box-shadow: none !important;
		border-radius: 11px;

		.header {
			display: flex;
			align-items: center;
			padding: 8px;
			border-bottom: 1px solid #d9d9d9;

			.jobInfo {
				display: flex;
				align-items: center;
				flex: 1;

				.jobCode {
					font-size: 16px;
					font-weight: bold;
					flex: 1;
				}

				.uni-tag {
					box-sizing: border-box;
					height: 100%;
					text-align: center;
					margin-right: 8px;
				}
			}
		}

		.card-list {
			display: grid;
			grid-template-columns: repeat(2, 1fr);
			grid-gap: 4px;

			.card-item {
				display: flex;
				flex-direction: column;
				align-items: flex-start;

				.card-item__label {
					font-size: 13px;
				}

				.card-item__value {
					font-weight: bold;
					font-size: 15px;
					color: #333;
				}
			}
		}

		.card-data {
			display: flex;
			margin-top: 10px;
			background-color: #f1f1f1;
			border-radius: 4px;
			padding: 6px 0;

			.card-data-item {
				flex: 1;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;

				.card-data-item__label {
					font-size: 13px;
				}

				.card-data-item__value {
					font-weight: bold;
					font-size: 15px;
					color: #333;

					&.finish {
						color: #059669;
					}
				}
			}
		}

		.actions {
			padding: 0 10px;
		}
	}

	.btns {
		padding-top: 5px;
	}
}

::v-deep .uni-numbox__value {
	flex: 1;
	height: 36px;
}

::v-deep .uni-forms-item.is-direction-left {
	align-items: baseline;
}
</style>