/**
 * 坯布出仓单（其他出货单）常量与数据工具
 *
 * 仅存放与接口无关的常量 / 状态映射 / 字段规范化 / 单位换算等纯工具，
 * 真实接口请求统一注册在 src/common/http.api.js 的 vm.$u.api.gfmOtherDeliveryOrder 下。
 */
import dayjs from 'dayjs';

// 审核状态（对应 openapi common.OrderStatus）
export const AUDIT_STATUS = {
	PENDING: 1, // 待审核
	APPROVED: 2, // 已审核
	REJECTED: 3, // 已驳回
	VOIDED: 4, // 已作废
};

/** 前端草稿态（未保存） */
export const DRAFT_AUDIT_STATUS = 0;
export const DRAFT_AUDIT_STATUS_NAME = '待保存';

export const AUDIT_STATUS_MAP = {
	1: '待审核',
	2: '已审核',
	3: '已驳回',
	4: '已作废',
};

/** 坯布资料弹窗字段 */
export const FABRIC_INFO_FIELDS = [
	{ label: '坯布编号', key: 'grey_fabric_code' },
	{ label: '名称', key: 'grey_fabric_name' },
	{ label: '客户', key: 'customer_name' },
	{ label: '幅宽', key: 'grey_fabric_width' },
	{ label: '克重', key: 'grey_fabric_gram_weight' },
	{ label: '纱批', key: 'yarn_batch' },
	{ label: '针寸数', key: 'needle_size' },
	{ label: '原料纱名称', key: 'raw_material_yarn_name' },
	{ label: '原料批号', key: 'raw_material_batch_num' },
	{ label: '原料品牌', key: 'raw_material_batch_brand' },
	{ label: '颜色', key: 'gray_fabric_color_name' },
	{ label: '等级', key: 'grey_fabric_level_name' },
	{ label: '机台号', key: 'machine_number' },
	{ label: '织造工艺', key: 'weaving_process' },
	{ label: '坯布备注', key: 'grey_fabric_remark' },
];

/** 细码表格列（不含操作列） */
export const FINE_CODE_TABLE_COLUMNS = [
	{ label: '序号', key: 'seq', width: 70 },
	{ label: '卷号', key: 'roll_no', width: 90 },
	{ label: '匹数', key: 'roll', width: 90 },
	{ label: '数量(重量)', key: 'weight', width: 120 },
	{ label: '条码', key: 'bar_code', width: 260 },
	{ label: '仓位', key: 'position', width: 110 },
];

/** 审核状态变更操作配置（apiKey 对应 gfmOtherDeliveryOrder 下的方法名） */
export const STATUS_ACTION_CONFIG = {
	approve: { status: AUDIT_STATUS.APPROVED, msg: '确认审核该单据？', apiKey: 'statusPass' },
	void: { status: AUDIT_STATUS.VOIDED, msg: '确认作废该单据？', apiKey: 'statusCancel' },
	unapprove: { status: AUDIT_STATUS.PENDING, msg: '确认消审该单据？', apiKey: 'statusWait' },
};

// 出仓类型：当前后端仅提供「坯布其他出货单」一种类型的接口
export const BILL_TYPES = [
	{ value: 'other', label: '坯布其他出货单' },
];

/** 列表分页拉取每页条数 */
export const LIST_PAGE_SIZE = 100;

/** 往来单位类型：染厂（染厂下拉筛选） */
export const BUSINESS_UNIT_TYPE_DYE_FACTORY = 12;

export function getStatusOptions() {
	return Object.keys(AUDIT_STATUS_MAP).map((value) => ({
		value,
		label: AUDIT_STATUS_MAP[value],
	}));
}

/** 将下拉/列表接口响应转为 u-select 所需的 { value, label } */
export function mapToSelectOptions(data) {
	const list = Array.isArray(data) ? data : (data && (data.list || data.items || data.records)) || [];
	return list.map((item) => ({
		value: item.id,
		label: item.name || item.label || item.code || String(item.id),
	}));
}

// 匹数：后端以 0.01 匹存储（乘以100的整数），展示需除以100
export function formatRoll(value) {
	const n = Number(value || 0) / 100;
	return Number.isInteger(n) ? n : Number(n.toFixed(2));
}

// 重量：后端整数存储（×10000），展示需除以 10000 为 KG
export function formatWeightKg(value) {
	const n = Number(value || 0) / 10000;
	return Number(n.toFixed(2));
}

/** 从详情对象取展示用总重量（优先用原始值换算） */
export function getOrderDisplayWeight(order) {
	if (!order) return 0;
	if (order._raw?.total_weight != null) return formatWeightKg(order._raw.total_weight);
	return order.total_weight ?? 0;
}

/** 从细码取展示用重量（优先用原始值换算） */
export function getFineCodeDisplayWeight(fineCode) {
	if (!fineCode) return 0;
	if (fineCode.raw_weight != null) return formatWeightKg(fineCode.raw_weight);
	return fineCode.weight || 0;
}

/**
 * 将接口详情数据规范化为页面使用的结构
 */
export function normalizeOrder(order) {
	if (!order) return null;
	const itemData = groupItemData((order.item_data || []).map((item) => normalizeItem(item)));
	return {
		id: order.id,
		order_no: order.order_no || '',
		audit_status: order.audit_status,
		audit_status_name: order.audit_status_name || AUDIT_STATUS_MAP[order.audit_status] || '',
		// 表头
		sale_system_id: order.sale_system_id || '',
		sale_system_name: order.sale_system_name || '',
		delivery_unit_id: order.delivery_unit_id || '',
		delivery_unit_name: order.delivery_unit_name || '',
		business_unit_id: order.business_unit_id || '',
		business_unit_name: order.business_unit_name || '',
		delivery_time: (order.delivery_time || '').slice(0, 10),
		remark: order.remark || '',
		// 人员/时间
		creator_name: order.creator_name || '',
		create_time: order.create_time || '',
		auditer_name: order.auditer_name || '',
		audit_time: order.audit_time || '',
		// 汇总
		total_roll: formatRoll(order.total_roll),
		total_weight: formatWeightKg(order.total_weight),
		item_data: itemData,
		_raw: order,
	};
}

/** 扫码详情区表格列 */
export const SCAN_DETAIL_TABLE_COLUMNS = [
	{ label: '坯布编号', key: 'grey_fabric_code', width: 140 },
	{ label: '坯布名称', key: 'grey_fabric_name', width: 140 },
	{ label: '纱批', key: 'yarn_batch', width: 120 },
	{ label: '机号', key: 'machine_number', width: 100 },
	{ label: '条数', key: 'roll', width: 80 },
	{ label: '重量', key: 'weight', width: 100 },
];

/** 扫码详情区可勾选锁定维度（对应 PDAScanGfmOtherDeliveryOrderParam 的 *_lock；勾选后参与表格分组并随扫码请求传给后端） */
export const SCAN_GROUP_OPTIONS = [
	{ key: 'produce_order_no', label: '合同' },
	{ key: 'grey_fabric_code', label: '布编' },
	{ key: 'yarn_batch', label: '纱批' },
	{ key: 'machine_number', label: '机号' },
	{ key: 'grey_fabric_level_name', label: '等级' },
];

/** 勾选维度对应扫码接口锁定字段名（PDAScanGfmOtherDeliveryOrderParam） */
export const SCAN_MERGE_FIELD_MAP = {
	produce_order_no: 'produce_order_no_lock',
	grey_fabric_code: 'grey_fabric_code_lock',
	yarn_batch: 'yarn_batch_lock',
	machine_number: 'machine_number_lock',
	grey_fabric_level_name: 'grey_fabric_level_id_lock',
};

/** 扫码锁定维度不匹配时的语音文案（按匹配优先级排列） */
const SCAN_MISMATCH_VOICE_RULES = [
	{ patterns: ['机台', '机号', 'machine_number'], voice: '机台不同' },
	{ patterns: ['纱批', 'yarn_batch'], voice: '纱批不同' },
	{ patterns: ['合同号', '合同', '生产通知单', 'produce_order'], voice: '合同号不同' },
	{ patterns: ['布编', 'grey_fabric_code'], voice: '布编不同' },
	{ patterns: ['等级', 'grey_fabric_level', 'level'], voice: '等级不同' },
];

/**
 * 根据后端错误信息解析锁定维度不匹配的播报文案
 * @param {string} message
 * @returns {string} 如「机台不同」；无法识别则返回空串
 */
export function resolveScanMismatchVoice(message) {
	const msg = String(message || '');
	if (!msg) return '';
	for (let i = 0; i < SCAN_MISMATCH_VOICE_RULES.length; i++) {
		const rule = SCAN_MISMATCH_VOICE_RULES[i];
		if (rule.patterns.some((p) => msg.indexOf(p) !== -1)) {
			return rule.voice;
		}
	}
	return '';
}

/** 构建扫码新增/删除请求参数（勾选锁定维度时附带当前详情区字段值） */
export function buildScanUpdateParams({ id, scanCode, scanType, groupKeys = [], detail = {} }) {
	const params = {
		id: Number(id),
		scan_code: scanCode,
		scan_type: scanType,
	};
	(groupKeys || []).forEach((key) => {
		const apiKey = SCAN_MERGE_FIELD_MAP[key];
		if (!apiKey) return;
		if (apiKey === 'grey_fabric_level_id_lock') {
			const levelIds = detail.grey_fabric_level_id;
			params.grey_fabric_level_id_lock = Array.isArray(levelIds) ? levelIds : [];
			return;
		}
		const value = detail[key];
		params[apiKey] = value != null && value !== '' ? value : '';
	});
	return params;
}

export function getEmptyScanDetail() {
	return {
		customer_id: '',
		customer_name: '',
		produce_order_no: '',
		grey_fabric_code: '',
		grey_fabric_name: '',
		yarn_batch: '',
		machine_number: '',
		volume_number: '',
		grey_fabric_level_id: [],
		grey_fabric_level_name: '',
		weight: 0,
		scanned_roll: 0,
		machine_stock: 0,
		total_roll: 0,
		total_weight: 0,
	};
}

/** 扫码接口响应是否包含条码详情字段 */
export function hasScanDetailFields(raw) {
	if (!raw) return false;
	return raw.scanned_total_roll != null
		|| raw.summary_stock_roll != null
		|| !!raw.customer_name
		|| !!raw.grey_fabric_code
		|| !!raw.produce_order_no;
}

/** 从扫码接口返回的详情构建扫码详情区数据 */
export function buildScanDetailFromOrderResponse(order) {
	const raw = order?._raw || order;
	if (!hasScanDetailFields(raw)) return null;
	const detail = {
		customer_id: raw.customer_id || '',
		customer_name: raw.customer_name || '',
		produce_order_no: raw.produce_order_no || '',
		grey_fabric_code: raw.grey_fabric_code || '',
		grey_fabric_name: raw.grey_fabric_name || '',
		yarn_batch: raw.yarn_batch || '',
		machine_number: raw.machine_number || '',
		volume_number: raw.volume_number || '',
		grey_fabric_level_id: raw.grey_fabric_level_id || [],
		grey_fabric_level_name: raw.grey_fabric_level_name || '',
		weight: 0,
		scanned_roll: formatRoll(raw.scanned_total_roll),
		machine_stock: raw.summary_stock_roll != null ? formatRoll(raw.summary_stock_roll) : 0,
		total_roll: order?.total_roll ?? 0,
		total_weight: getOrderDisplayWeight(order),
	};
	return detail;
}

/** 在单据明细中定位本次扫描的坯布行与细码 */
export function findScanContext(itemData, scanCode) {
	const code = (scanCode || '').trim();
	if (!code) return null;
	for (const item of itemData || []) {
		for (const fc of item.fine_codes || []) {
			const candidates = [
				fc.fabric_piece_code,
				fc.bar_code,
				fc.roll_no,
				fc.scan_code,
			].filter(Boolean).map(String);
			if (candidates.includes(code)) {
				return { item, fineCode: fc };
			}
		}
	}
	return null;
}

/** 根据扫码上下文构建详情区展示数据 */
export function buildScanDetailFromContext(context, order) {
	if (!context) return getEmptyScanDetail();
	const { item, fineCode } = context;
	const groupKey = getItemGroupKey(item);
	let scannedRoll = 0;
	(order.item_data || []).forEach((row) => {
		if (getItemGroupKey(row) !== groupKey) return;
		(row.fine_codes || []).forEach((fc) => {
			scannedRoll += Number(fc.roll || 0);
		});
	});
	return {
		customer_name: item.customer_name || '',
		produce_order_no: item.produce_order_no || item.contract_no || '',
		grey_fabric_code: item.grey_fabric_code || '',
		grey_fabric_name: item.grey_fabric_name || '',
		yarn_batch: item.yarn_batch || '',
		machine_number: item.machine_number || '',
		volume_number: fineCode.fabric_piece_code || fineCode.roll_no || fineCode.bar_code || '',
		grey_fabric_level_name: item.grey_fabric_level_name || '',
		weight: getFineCodeDisplayWeight(fineCode),
		scanned_roll: Number(scannedRoll.toFixed(2)),
		machine_stock: item.machine_stock ?? 0,
		total_roll: order.total_roll ?? 0,
		total_weight: getOrderDisplayWeight(order),
	};
}

function aggregateScanTableRows(rows, keys) {
	const map = new Map();
	rows.forEach((row) => {
		const groupId = keys.map((k) => row[k] || '').join('|');
		const existing = map.get(groupId);
		if (!existing) {
			map.set(groupId, { ...row, roll: 0, raw_weight: 0 });
		}
		const agg = map.get(groupId);
		agg.roll = Number((agg.roll + Number(row.roll || 0)).toFixed(2));
		agg.raw_weight = Number(agg.raw_weight || 0) + Number(row.raw_weight || 0);
	});
	return Array.from(map.values()).map((row) => ({
		...row,
		weight: formatWeightKg(row.raw_weight),
	}));
}

/** 构建扫码详情区汇总表格数据 */
export function buildScanDetailTableRows(itemData, groupKeys = []) {
	const rows = [];
	(itemData || []).forEach((item) => {
		(item.fine_codes || []).forEach((fc) => {
			rows.push({
				customer_name: item.customer_name || '',
				produce_order_no: item.produce_order_no || item.contract_no || '',
				grey_fabric_code: item.grey_fabric_code || '',
				grey_fabric_name: item.grey_fabric_name || '',
				yarn_batch: item.yarn_batch || '',
				machine_number: item.machine_number || '',
				volume_number: fc.roll_no || fc.fabric_piece_code || '',
				grey_fabric_level_name: item.grey_fabric_level_name || '',
				roll: fc.roll || 0,
				raw_weight: fc.raw_weight != null ? fc.raw_weight : 0,
			});
		});
	});
	if (!rows.length) return [];
	const keys = (groupKeys || []).filter(Boolean);
	if (!keys.length) {
		return aggregateScanTableRows(rows, ['grey_fabric_code', 'grey_fabric_name', 'yarn_batch', 'machine_number']);
	}
	return aggregateScanTableRows(rows, keys);
}

export function getScanDetailTableWidth(columns) {
	const total = (columns || []).reduce((sum, col) => sum + (col.width || 120), 0);
	return `${total}rpx`;
}

export function normalizeItem(item) {
	const machineStockRaw = item.machine_stock_roll ?? item.machine_stock ?? item.machine_inventory_roll;
	return {
		id: item.id,
		grey_fabric_id: item.grey_fabric_id || '',
		grey_fabric_code: item.grey_fabric_code || '',
		grey_fabric_name: item.grey_fabric_name || '',
		customer_name: item.customer_name || '',
		produce_order_no: item.produce_order_no || item.contract_no || item.sale_contract_no || item.grey_fabric_contract_no || '',
		machine_stock: machineStockRaw != null ? formatRoll(machineStockRaw) : 0,
		grey_fabric_width: item.grey_fabric_width_and_unit_name || item.grey_fabric_width || '',
		grey_fabric_gram_weight: item.grey_fabric_gram_weight_and_unit_name || item.grey_fabric_gram_weight || '',
		yarn_batch: item.yarn_batch || '',
		needle_size: item.needle_size || '',
		raw_material_yarn_name: item.raw_material_yarn_name || '',
		raw_material_batch_num: item.raw_material_batch_num || '',
		raw_material_batch_brand: item.raw_material_batch_brand || '',
		gray_fabric_color_name: item.gray_fabric_color_name || '',
		grey_fabric_level_name: item.grey_fabric_level_name || '',
		machine_number: item.machine_number || '',
		weaving_process: item.weaving_process || '',
		grey_fabric_remark: item.grey_fabric_remark || '',
		roll: formatRoll(item.roll),
		weight: formatWeightKg(item.total_weight),
		fine_codes: (item.item_fc_data || []).map((fc) => ({
			id: fc.id,
			roll_no: fc.volume_number || '',
			fabric_piece_code: fc.fabric_piece_code || '',
			bar_code: fc.fabric_piece_code || fc.bar_code || '',
			position: fc.position || '',
			raw_weight: fc.weight,
			weight: formatWeightKg(fc.weight),
			roll: formatRoll(fc.roll),
			// 删除细码走 scanUpdate，优先 fabric_piece_code，其次卷号
			scan_code: fc.fabric_piece_code || fc.volume_number || fc.bar_code || '',
		})),
	};
}

/** 细码扫码/删除时传给 scanUpdate 的 scan_code（fabric_piece_code 或卷号） */
export function getFineCodeScanCode(fineCode) {
	if (!fineCode) return '';
	return fineCode.fabric_piece_code
		|| fineCode.scan_code
		|| fineCode.bar_code
		|| fineCode.roll_no
		|| '';
}

/** 坯布明细归类 key：优先 grey_fabric_id，否则 code + name */
export function getItemGroupKey(item) {
	if (item.grey_fabric_id) return `id:${item.grey_fabric_id}`;
	return `code:${item.grey_fabric_code}|${item.grey_fabric_name}`;
}

/** 将相同坯布的 item_data 合并为一行，细码 item_fc_data 汇总展示 */
export function groupItemData(items) {
	const grouped = new Map();
	(items || []).forEach((item) => {
		const groupKey = getItemGroupKey(item);
		const existing = grouped.get(groupKey);
		if (!existing) {
			grouped.set(groupKey, {
				...item,
				group_key: groupKey,
				source_ids: [item.id],
				fine_codes: [...(item.fine_codes || [])],
			});
			return;
		}
		existing.source_ids.push(item.id);
		existing.fine_codes.push(...(item.fine_codes || []));
		existing.roll = Number((existing.roll + item.roll).toFixed(2));
		existing.weight = Number((existing.weight + item.weight).toFixed(2));
	});
	return Array.from(grouped.values()).map((row) => ({
		...row,
		id: row.grey_fabric_id || row.group_key,
	}));
}

// 构造审核状态变更接口的入参（id 为字符串）
export function buildStatusParam(id, auditStatus) {
	return { id: String(id), audit_status: auditStatus };
}

export function formatDisplayTime(value, format = 'YYYY-MM-DD') {
	if (!value) return '';
	const parsed = dayjs(value);
	return parsed.isValid() ? parsed.format(format) : String(value).slice(0, 10);
}

export function canScanAtStatus(status) {
	return [AUDIT_STATUS.PENDING, AUDIT_STATUS.REJECTED].includes(status);
}

export function isLockedOrderStatus(status) {
	return [AUDIT_STATUS.APPROVED, AUDIT_STATUS.VOIDED].includes(status);
}

/** 分页拉取全部列表（直至末页） */
export function fetchAllOrderList(listFn, params = {}, pageSize = LIST_PAGE_SIZE) {
	const loadPage = (page, acc) => listFn({ ...params, page, size: pageSize })
		.then((res) => {
			const batch = Array.isArray(res) ? res : (res && res.list) || [];
			const merged = acc.concat(batch);
			if (batch.length < pageSize) return merged;
			return loadPage(page + 1, merged);
		});
	return loadPage(1, []);
}

/** 新增/编辑页底部：审核、作废 */
export function getFormStatusActionButtons(headerSaved, orderId, status) {
	if (!headerSaved || !orderId || !canScanAtStatus(status)) return [];
	return [
		{ label: '审核', action: 'approve' },
		{ label: '作废', action: 'void' },
	];
}

/** 查看页底部：编辑、审核、作废 / 消审 */
export function getViewStatusActionButtons(status) {
	if (status === AUDIT_STATUS.PENDING || status === AUDIT_STATUS.REJECTED) {
		return [
			{ label: '编辑', action: 'edit' },
			{ label: '审核', action: 'approve' },
			{ label: '作废', action: 'void' },
		];
	}
	if (status === AUDIT_STATUS.APPROVED) {
		return [{ label: '消审', action: 'unapprove' }];
	}
	return [];
}

/** 将 normalizeOrder 结果映射为表单字段 */
export function orderToFormFields(order) {
	return {
		order_no: order.order_no,
		business_unit_id: order.business_unit_id,
		business_unit_name: order.business_unit_name,
		delivery_time: order.delivery_time,
		remark: order.remark,
		item_data: order.item_data,
	};
}

export function getFineCodeTableColumns(readonly) {
	const cols = [...FINE_CODE_TABLE_COLUMNS];
	if (!readonly) cols.push({ label: '操作', key: 'action', width: 90 });
	return cols;
}

export function mapFineCodeTableRows(list, readonly) {
	return (list || []).map((item, index) => ({
		seq: index + 1,
		roll_no: item.roll_no || '-',
		roll: item.roll != null && item.roll !== '' ? item.roll : '-',
		weight: item.weight != null && item.weight !== '' ? `${item.weight}` : '-',
		bar_code: item.bar_code || '-',
		position: item.position || '-',
		action: readonly ? '' : '删除',
	}));
}

export function getFineCodeTableWidth(columns) {
	const total = (columns || []).reduce((sum, col) => sum + (col.width || 120), 0);
	return `${total}rpx`;
}

/**
 * 确认并执行审核状态变更（新增/编辑/查看页共用）
 * @param {Vue} vm 页面实例，需有 $u.api 与 showError
 * @param {{ orderId: number, action: string, onSuccess?: Function }} options
 */
export function confirmOrderStatusAction(vm, { orderId, action, onSuccess }) {
	const cfg = STATUS_ACTION_CONFIG[action];
	if (!cfg || !orderId) return;
	const api = vm.$u.api.gfmOtherDeliveryOrder;
	const requestFn = api[cfg.apiKey];
	if (typeof requestFn !== 'function') return;
	uni.showModal({
		title: '提示',
		content: cfg.msg,
		success: (res) => {
			if (!res.confirm) return;
			uni.showLoading({ title: '处理中...' });
			requestFn(buildStatusParam(orderId, cfg.status))
				.then(() => {
					if (typeof onSuccess === 'function') return onSuccess();
					uni.hideLoading();
				})
				.catch((e) => {
					uni.hideLoading();
					if (vm.showError) vm.showError(e.message || '操作失败');
				});
		},
	});
}
