import ProTable from '@ant-design/pro-table'
import numeral from 'numeral'
import './printBox.less'
import { CurrentUser } from 'umi'
import session from './session'
import moment from 'moment'
import { synchroBehaviorRecord } from '@/services/user'

export type TreeSelectModel = {
	value: number | string,
	id: number | string,
	title: string,
	pId: number | string,
	disabled?: boolean
}
export type TreeNodeDto = {
	node: any;
	children: TreeNodeDto[];
}
/**
 * @description: [{node:{},chidlren:[]}] => [{...node,children}]
 * @param {any} node 需要拼接的父节点
 * @param {any} chidlren 需要遍历的平级节点 合并节点中的
 * @return {*} 返回[node:{...,children:[]}]
 */
export function wrapTreeNode(data: TreeNodeDto[]) {

	const wrapData: any = data.map((item: TreeNodeDto) => {
		const node = { ...item.node };

		if (item.children && item.children.length > 0) {
			node.children = wrapTreeNode(item.children);
		}
		return node
	});
	return wrapData;
}

export function formatTreeForProTable(data: TreeNodeDto[]) {

	const wrapData = wrapTreeNode(data);
	return {
		data: wrapData,
		current: 1,
		pageSize: 100,
		total: 100,
		success: true,
	};
}

export function tableList(list: any) {
	return {
		data: list.List || [],
		current: list.PageIndex || 1,
		pageSize: list.pageSize || 10,
		total: list.TotalCount || 0,
		otherData: list?.OtherData || '',
		success: true,
	};
}

/**
 * @description:生产的数据仅提供 treeSelect组件treeDataSimpleMode模式使用的 数据，
 * @param fields 需要转化的数据，
 * @param treeKeys fields 与 TreeSelectModel 数据键值 如 fields as EnumItem ,treeKeys: { title: 'fieldEnumName', value: 'id', id:'id', pId:'parentId' }
 * @returns TreeSelectModel[]
 */
export const getTreeSelectOption = async (treeKeys: TreeSelectModel, fields: any[]) => {
	const option: TreeSelectModel[] = []
	const { value, title, pId, id } = treeKeys
	fields.forEach(async (item: any) => {

		option.push({ value: item[value], title: item[title], pId: item[pId], id: item[id] })
		if (item.children) {
			const children: TreeSelectModel[] = await getTreeSelectOption(treeKeys, item.children)
			option.push(...children)
		}

	})
	return option
}

// 转换数据为option格式数据
export function formateOptions(list: [], rules: { name: string; value: string; other?: string }) {
	// let options: { label: string; value: number | string; other?: string | number }[] = [];
	const { name, value, other } = rules;

	if (list && other) {
		return list.map((n) => {
			return {
				label: n[name],
				value: n[value],
				other: n[other],
			};
		});
	} if (list) {
		return list.map((n) => {
			return {
				label: n[name],
				value: n[value],
			};
		});
	}
	return [];
}

// 转换options数据value类型为 number
export function formateField(list: { label: string; value: string | number }[]) {
	const valueNumber: { label: string; value: number }[] = [];

	list.map((n: any) => {
		if (!isNaN(Number(n.value))) {
			valueNumber.push({
				label: n.label,
				value: numeral(n.value).value(),
			});
		}
	});
	return valueNumber.length > 0 ? valueNumber : list;
}

// 转换树节点的value类型为string
export function formateTreeField(list: TreeNodeDto[]) {
	const valueNumber: any[] = list.map((item: TreeNodeDto) => {
		const node = { label: item.node.label, value: item.node.value.toString(), type: item.node.type, ico: item.node.ico };
		if (item.children && item.children.length > 0) {
			node.children = formateTreeField(item.children);
		}
		return node
	});
	return valueNumber.length > 0 ? valueNumber : list;
}

// 把图片格式转化为 ui框架需要的数据格式
export const transferImg = (orgIamges: any[]) => {
	const newImages = orgIamges.map((n: any) => {
		if (typeof n === 'object') {

			return {
				uid: n.ImageId, // 注意，这个uid一定不能少，否则上传失败
				name: n.ImageName,
				status: 'done',
				url: n.ImageUrl, // url 是展示在页面上的绝对链接
				imgUrl: n.ImagePath,
			}
		}
		const [name] = [...n.split("/")].reverse()
		return {
			uid: new Date().getTime(), // 注意，这个uid一定不能少，否则上传失败
			name,
			status: 'done',
			url: n, // url 是展示在页面上的绝对链接
			imgUrl: n,
		}

	})
	return newImages
}

// 合计方法
export const handleGetSumRow = (data: any[], fieldList: string[], sumTitle: string, avgFiled?: string) => {
	// data 表格数据    fieldList 要算合计的字段 sumTitle 显示合计两个字的字段 avgFiled 要算均值的字段(这个字段也必须在算合计的字段里面)
	if (data && data.length > 0) {
		if (data.length >= 2) {
			const res: any = {}
			if (fieldList && fieldList.length > 0) {
				fieldList.forEach((item: any) => {
					res[item] = 0
				})
			}
			data.forEach((item: any) => {
				if (res) {
					for (const key in res) {
						if (item[key]) {
							res[key] += item[key]
						}

					}
				}
			})
			if (avgFiled) {
				res[avgFiled] = Number((res[avgFiled] / data.length).toFixed(2))
			}

			console.log('res', res);
			res[sumTitle] = "合计"
			data.unshift(res)
			return data
		}
		// 一个片区的时候 判断是不是一个服务区  一个服务区的话 就单单显示一个服务区就好
		if (data && data.length === 1) {
			const obj: any = data[0]
			if (obj.children && obj.children.length === 1) {
				return obj.children
			}
			return data

		}
		return data


	}
	return []
}


// 自定义打印的内容的打印方法
export const handleNewPrint = (printName: string, title: string, neckBox?: any, styles?: any, tableDom?: any, footer?: any) => {
	// printName 打印出来文件的名称
	// title 打印内容的标题
	// neckBox 标题下面可能会要求的打印的内容  数组 {label,value}格式 样式已写死
	// styles 获取页面的样式
	// tableDom 要打印显示的表格 直接dom元素拿进来(处理好的)
	// footer 打印内容底部的自定义样式 需求不一样 样式也不一样 外面写好样式和标签直接传入
	const printWindow = window.open('', '_blank', 'width=1400,height=800');
	if (printWindow) {
		printWindow.document.open();
		printWindow.document.write(`
		<html>
			<head>
			<title>${printName || ''}</title>
			<style>
				body {
					font-family: Arial, sans-serif;
					margin: 20px;
					position: relative;
              		overflow: hidden;
				}
				${styles}
				.handlePrintBox{
					width: 100%;
					height: 100%;
					position: relative;
					z-index: 0;
					box-sizing: border-box;
					padding: 20px 0 0 0;
				}
				.handlePrintBox .custom-header {
					font-size: 24px;
					text-align: center;
					margin-bottom: 20px;
					font-weight: 600;
				}
				.handlePrintBox .neckBox{
					width: 100%;
					box-sizing: border-box;
					padding: 12px 12px 12px 20px;
					display: flex;
					flex-wrap: wrap;
					justify-content: space-between;
				}
				.handlePrintBox .neckBox .neckBoxItem{
					width: calc(100% / 3);
					display: flex;
					align-items: center;
					box-sizing: border-box;
					padding-left: 5%;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem{
					width: calc((100% / 3) * 2);
					display: flex;
					align-items: center;
					box-sizing: border-box;
					padding-left: 5%;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem .itemLabel{
					font-size: 14px;
					font-weight: 600;
					margin-right: 2px;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem .itemValue{
					font-size: 12px;
				}
				.handlePrintBox .neckBox .neckBoxItem .itemLabel{
					font-size: 14px;
					font-weight: 600;
					margin-right: 2px;
				}
				.handlePrintBox .neckBox .neckBoxItem .itemValue{
					font-size: 12px;
				}
				.handlePrintBox .tableBox{
					width: 100%;
					box-sizing: border-box;
					padding: 12px;
					display: flex;
					justify-content: center;
					border-collapse: separate;
					border-spacing: 0;
				}
				.handlePrintBox .tableBox .ant-table-thead tr th{
					border: 2px solid #000;
				}
				.handlePrintBox .tableBox .ant-table-tbody tr td{
					border: 2px solid #000;
				}
				.handlePrintBox .tableBox .ant-table-summary tr td{
					border: 2px solid #000;
				}
				.handlePrintBox .tableUnit{
					width: 100%;
					display: flex;
					justify-content: flex-end;
					box-sizing: border-box;
					font-size: 14px;
				}
				.handlePrintBox .tableUnit .tableRight{
					width: calc(100% / 3);
					font-size: 14px;
					box-sizing: border-box;
					padding-left: 5%;
				}
				.pro-table {
					width: 100%;
					border-collapse: collapse;
				  }
				  .pro-table th, .pro-table td {
					border: 1px solid #ddd;
					padding: 8px;
				  }
				  .pro-table th {
					background-color: #f2f2f2;
					text-align: left;
				  }
				  /* 水印样式 */
				  .watermark {
					position: absolute;
					top: 0;
					left: 0;
					width: 100%;
					height: 100%;
					display: grid;
					grid-template-rows: repeat(4, 1fr); /* 水平行数 */
					grid-template-columns: repeat(4, 1fr); /* 垂直列数 */
					opacity: 0.2;
					pointer-events: none;
					z-index: 1;
					overflow: hidden;
				  }
				  .watermark span {
					display: flex;
					justify-content: center;
					align-items: center;
					transform: rotate(-45deg); /* 水印旋转 */
					font-size: 14px;
					color: rgba(0, 0, 0); /* 半透明水印 */
					user-select: none;
				  }
			</style>
			</head>
			<body>
				<div class="handlePrintBox">
					<div class="custom-header">${title}</div>
					<div class="neckBox">
					${neckBox && neckBox.length > 0
				? neckBox
					.map((item: any) => {
						return `<div class="${item.label === '门店名称' ? 'bigNeckBoxItem' : 'neckBoxItem'}">
										<span class="itemLabel">${item.label ? item.label + '：' : ''}</span>
										<span class="itemValue">${item.value}</span>
									  </div>`;
					})
					.join('') // 连接成单一字符串，避免逗号
				: ''}
					</div>
				<div class="tableUnit">
					<div class="tableRight">单位：元</div>
				</div>
				<div class="tableBox">
					${tableDom}
				</div>
				<div>
					${footer}
				</div>
				</div>
				<div class="watermark">
					${Array(16) // 5x5 网格的水印内容
				.fill('<span></span>')
				.join('')}
				</div>
			</body>
	  	</html>
		`)
		printWindow.document.close();
		printWindow.print();

		// 使用定时器检测打印窗口是否关闭
		const closeCheckInterval = setInterval(() => {
			if (printWindow.closed) {
				clearInterval(closeCheckInterval);
			}
		}, 500);

		// 监听窗口焦点事件，若打印窗口失去焦点，关闭窗口
		printWindow.onfocus = () => {
			printWindow.close();
			clearInterval(closeCheckInterval);
		};
		printWindow.onafterprint = () => printWindow.close();
	}
}

// 自定义打印的内容的打印方法
export const handleNewPrintAHJG = (printName: string, title: string, neckBox?: any, styles?: any, tableDom?: any, footer?: any) => {
	// printName 打印出来文件的名称
	// title 打印内容的标题
	// neckBox 标题下面可能会要求的打印的内容  数组 {label,value}格式 样式已写死
	// styles 获取页面的样式
	// tableDom 要打印显示的表格 直接dom元素拿进来(处理好的)
	// footer 打印内容底部的自定义样式 需求不一样 样式也不一样 外面写好样式和标签直接传入
	const printWindow = window.open('', '_blank', 'width=1600,height=900,scrollbars=yes');
	if (printWindow) {
		printWindow.document.open();
		printWindow.document.write(`
		<html>
			<head>
			<title>${printName || ''}</title>
			<style>
				body {
					font-family: Arial, sans-serif;
					margin: 20px;
					position: relative;
              		overflow: hidden;
				}
				${styles}
				.handlePrintBox{
					width: 100%;
					height: 100%;
					position: relative;
					z-index: 0;
					box-sizing: border-box;
					padding: 20px 0 0 0;
				}
				.handlePrintBox .custom-header {
					font-size: 24px;
					text-align: center;
					margin-bottom: 20px;
					font-weight: 600;
				}
				.handlePrintBox .neckBox{
					width: 100%;
					box-sizing: border-box;
					padding: 12px 5% 12px 5%;
					display: flex;
					flex-wrap: wrap;
					justify-content: space-between;
				}
				.handlePrintBox .neckBox .neckBoxItem{
					width: calc(100% / 4);
					display: flex;
					align-items: center;
					box-sizing: border-box;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem{
					width: calc((100% / 4) * 2);
					display: flex;
					align-items: center;
					box-sizing: border-box;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem .itemLabel{
					font-size: 14px;
					font-weight: 600;
					margin-right: 2px;
				}
				.handlePrintBox .neckBox .bigNeckBoxItem .itemValue{
					font-size: 12px;
				}
				.handlePrintBox .neckBox .neckBoxItem .itemLabel{
					font-size: 14px;
					font-weight: 600;
					margin-right: 2px;
				}
				.handlePrintBox .neckBox .neckBoxItem .itemValue{
					font-size: 12px;
				}
				.handlePrintBox .tableBox{
					width: 100%;
					box-sizing: border-box;
					padding: 12px;
					display: flex;
					justify-content: center;
					border-collapse: collapse;  /* 改为collapse */
					border-spacing: 0;
					overflow-x: auto;  /* 添加横向滚动 */
				}
				.handlePrintBox .tableBox .ant-table-thead tr th{
					border: 2px solid #000;
				}
				.handlePrintBox .tableBox .ant-table-tbody tr td{
					border: 2px solid #000;
				}
				.handlePrintBox .tableBox .ant-table-summary tr td{
					border: 2px solid #000;
				}
				.handlePrintBox .tableUnit{
					width: 100%;
					display: flex;
					justify-content: flex-end;
					box-sizing: border-box;
					font-size: 14px;
				}
				.handlePrintBox .tableUnit .tableRight{
					width: calc(100% / 3);
					font-size: 14px;
					box-sizing: border-box;
					padding-left: 5%;
				}
				.handlePrintBox .tableBox table {
					transform: scale(0.9);  /* 整体缩小10% */
					transform-origin: top left;
					page-break-inside: avoid;
				}
				.pro-table {
					width: 100%;
					border-collapse: collapse;
				  }
				  .pro-table th, .pro-table td {
					border: 1px solid #ddd;
					padding: 8px;
				  }
				  .pro-table th {
					background-color: #f2f2f2;
					text-align: left;
				  }
				  /* 水印样式 */
				  .watermark {
					position: absolute;
					top: 0;
					left: 0;
					width: 100%;
					height: 100%;
					display: grid;
					grid-template-rows: repeat(4, 1fr); /* 水平行数 */
					grid-template-columns: repeat(4, 1fr); /* 垂直列数 */
					opacity: 0.2;
					pointer-events: none;
					z-index: 1;
					overflow: hidden;
				  }
				  .watermark span {
					display: flex;
					justify-content: center;
					align-items: center;
					transform: rotate(-45deg); /* 水印旋转 */
					font-size: 14px;
					color: rgba(0, 0, 0); /* 半透明水印 */
					user-select: none;
				  }
			</style>
			</head>
			<body>
				<div class="handlePrintBox">
					<div class="custom-header">${title}</div>
					<div class="neckBox">
					${neckBox && neckBox.length > 0
				? neckBox
					.map((item: any) => {
						return `<div class="${item.label === '门店名称' ? 'bigNeckBoxItem' : 'neckBoxItem'}">
										<span class="itemLabel">${item.label ? item.label + '：' : ''}</span>
										<span class="itemValue">${item.value}</span>
									  </div>`;
					})
					.join('') // 连接成单一字符串，避免逗号
				: ''}
					</div>
				<div class="tableBox">
					${tableDom}
				</div>
				<div>
					${footer}
				</div>
				</div>
				<div class="watermark">
					${Array(16) // 5x5 网格的水印内容
				.fill('<span>安徽建工集团投资运营管理有限公司</span>')
				.join('')}
				</div>
			</body>
	  	</html>
		`)
		printWindow.document.close();
		printWindow.print();

		// 使用定时器检测打印窗口是否关闭
		const closeCheckInterval = setInterval(() => {
			if (printWindow.closed) {
				clearInterval(closeCheckInterval);
			}
		}, 500);

		// 监听窗口焦点事件，若打印窗口失去焦点，关闭窗口
		printWindow.onfocus = () => {
			printWindow.close();
			clearInterval(closeCheckInterval);
		};
		printWindow.onafterprint = () => printWindow.close();
	}
}


// 打印图片
export const handlePrintImg = (url: any) => {
	const printWindow = window.open('', '_blank', 'width=1400,height=800');
	if (printWindow) {
		printWindow.document.open();
		printWindow.document.close();
		printWindow.document.write(`
		<html>
			<head>
				<style>
				</style>
				<body>
					<div style="width:100%;height:100%;display:flex;justify-content: center;">
						<img style="max-width:100%;max-height:100%" src=${url}>
					</div>
				</body>
			</head>
		</html>
		`)
		printWindow.print();

		// 使用定时器检测打印窗口是否关闭
		const closeCheckInterval = setInterval(() => {
			if (printWindow.closed) {
				clearInterval(closeCheckInterval);
			}
		}, 500);

		printWindow.onfocus = () => {
			printWindow.close();
			clearInterval(closeCheckInterval);
		};
		printWindow.onafterprint = () => printWindow.close();
	}
}





// 记录每一个按钮的 调用了的方法
export const handleSetPublicLog = (obj: any) => {
	// desc 一个数组 入参内容说明  startTime  开始时间  endTime  结束时间  时间戳格式  buttonType 1 为点击了查询按钮

	const currentUser: CurrentUser = session.get('currentUser');
	let nowMenu = session.get("currentMenu")
	let basicInfo = session.get("basicInfo")
	let systemBasin = session.get("systemBasin")
	let browserVersion = session.get("browserVersion")
	if (obj.desc && obj.desc.length > 0) {
		obj.desc.forEach((item: any) => {
			// item.url = 'https://api.eshangtech.com' + item.url
			item.url = 'http://pos.eshangtech.com:8900/' + item.url
		})
	}

	const req: any = {
		USER_ID: currentUser.ID,
		USER_NAME: currentUser.Name,
		BEHAVIORRECORD_TYPE: "2000", // 1000 浏览页面 2000 行为记录 
		BEHAVIORRECORD_EXPLAIN: `在页面${nowMenu.name}${obj.buttonType === 1 ? '点击了查询按钮' : ''}`, // 操作行为说明
		BEHAVIORRECORD_ROUT: nowMenu.pathname,
		BEHAVIORRECORD_ROUTNAME: nowMenu.name,
		REQUEST_INFO: JSON.stringify(obj.desc),// 存的是一个JSON 存完整点的内容 在什么页面点击了什么 调用了什么接口 入参是什么  多个接口的时候是数组格式

		// BEHAVIORRECORD_DESC: obj.desc, // 入参
		BEHAVIORRECORD_TIME: moment(new Date(obj.startTime)).format('YYYY-MM-DD HH:mm:ss'),
		BEHAVIORRECORD_LEAVETIME: moment(new Date(obj.endTime)).format('YYYY-MM-DD HH:mm:ss'),
		BEHAVIORRECORD_DURATION: (obj.endTime - obj.startTime) / 1000,

		OWNERUNIT_ID: currentUser.OwnerUnitId,
		OWNERUNIT_NAME: currentUser.OwnerUnitName,
		BUSINESSMAN_ID: currentUser.BusinessManID,
		BUSINESSMAN_NAME: currentUser.BusinessManName,
		SOURCE_PLATFORM: '驿商云平台',
		USER_LOGINIP: basicInfo.ip,
		USER_LOGINPLACE: `${basicInfo.country || ""}${basicInfo.prov || ""}${basicInfo.city || ""}${basicInfo.district || ""}`,
		BROWSER_VERSION: browserVersion,
		OPERATING_SYSTEM: systemBasin
	}
	console.log('reqreqreqreqreq', req);

	synchroBehaviorRecord(req)
}

// 将一个对象的key值变为 中文字
export const handleChangeKeyTo = async (params: any, keyObj: any) => {
	// params 需要变的对象   keyObj 中文内容
	let newObj: any = {}
	for (let key in params) {
		newObj[keyObj[key]] = params[key]
	}
	return newObj
}


// 传入秒 返回时分
export const secondsToHuman = (seconds: number) => {
	const hours = Math.floor(seconds / 3600);
	const minutes = Math.floor((seconds % 3600) / 60);

	const parts = [];
	if (hours > 0) parts.push(`${hours}小时`);
	if (minutes > 0) parts.push(`${minutes}分钟`);

	return parts.join('') || '0分钟';
}


// 封装一个只要传入操作事项的就可以记录日志
export const handleSetlogSave = async (str?: string) => {
	const currentUser = session.get('currentUser')
	const basicInfo = session.get('basicInfo')
	const browserVersion = session.get('browserVersion')
	const systemBasin = session.get('systemBasin')
	let nowMenu = session.get("currentMenu")

	synchroBehaviorRecord({
		USER_ID: currentUser?.ID,
		USER_NAME: currentUser?.Name,
		BEHAVIORRECORD_TYPE: "2000",
		BEHAVIORRECORD_EXPLAIN: str || "",
		BEHAVIORRECORD_ROUT: nowMenu.pathname,
		BEHAVIORRECORD_ROUTNAME: nowMenu.name,

		BEHAVIORRECORD_TIME: moment().format('YYYY-MM-DD HH:mm:ss'),

		// REQUEST_INFO: str || "",
		OWNERUNIT_ID: currentUser?.OwnerUnitId,
		OWNERUNIT_NAME: currentUser?.OwnerUnitName,
		BUSINESSMAN_ID: currentUser?.BUSINESSMAN_ID,
		BUSINESSMAN_NAME: currentUser?.BUSINESSMAN_NAME,
		SOURCE_PLATFORM: "出行平台",
		USER_LOGINIP: basicInfo?.ip,
		USER_LOGINPLACE: `${basicInfo?.prov}${basicInfo?.city}${basicInfo?.district}`,
		BROWSER_VERSION: browserVersion,
		OPERATING_SYSTEM: systemBasin
	})
}


export function convertTreeToLabelValue<T>(
	tree: T[],
	labelKey: keyof T,
	valueKey: keyof T,
	childrenKey: keyof T = 'children' as keyof T
): any[] {
	return tree.map((item: any) => {
		const node: any = {
			label: item[labelKey],
			value: item[valueKey]
		};
		if (Array.isArray(item[childrenKey]) && item[childrenKey].length > 0) {
			node.children = convertTreeToLabelValue(item[childrenKey], labelKey, valueKey, childrenKey);
		}
		return node;
	});
}



export function convertTreeFieldToNumber(tree: any[], key: string): any[] {
	return tree.map(node => {
		const newNode = {
			...node,
			[key]: typeof node[key] === 'number' ? node[key].toString() : node[key],
		};
		if (Array.isArray(node.children) && node.children.length > 0) {
			newNode.children = convertTreeFieldToNumber(node.children, key);
		}
		return newNode;
	});
}


// 登录密码的正则校验 判断是否符合规则
export function validatePassword(password: string) {
	if (!password || password.length < 8) {
		return false;
	}
	const hasDigit = /\d/.test(password);
	const hasLower = /[a-z]/.test(password);
	const hasUpper = /[A-Z]/.test(password);
	const hasSpecial = /[!@#$%^&*(),.?":{}|<>_\-+=~`[\]\\;]/.test(password);
	// 统计符合的种类
	let count = 0;
	if (hasDigit) count++;
	if (hasLower || hasUpper) count++; // 大小写都算作字母
	if (hasSpecial) count++;
	return count >= 2;
}


/**
 * 对多层级树形数据按指定字段进行排序
 * @param data 树形数据数组
 * @param sortField 排序字段，格式: "字段名 排序方式" (如: "Total_Count desc"、"TotalRevenue.Revenue_Amount asc")
 * @param childrenKey 子节点的key名称，默认为 'children'
 * @returns 排序后的树形数据
 */
export function sortTreeData(data: any[], sortField: string, childrenKey: string = 'children'): any[] {
	if (!data || !Array.isArray(data) || data.length === 0 || !sortField) {
		return data;
	}

	const parts = sortField.trim().split(/\s+/);
	if (parts.length !== 2) {
		console.warn('排序字段格式错误，应为: "字段名 排序方式"，如: "Total_Count desc" 或 "TotalRevenue.Revenue_Amount asc"');
		return data;
	}

	const [fieldPath, sortOrder] = parts;
	const isDesc = sortOrder.toLowerCase() === 'desc';

	/**
	 * 根据字段路径获取对象的值
	 * @param obj 目标对象
	 * @param path 字段路径，如 "TotalRevenue.Revenue_Amount"
	 * @returns 字段值
	 */
	function getNestedValue(obj: any, path: string): any {
		if (!obj || typeof obj !== 'object') {
			return null;
		}

		const keys = path.split('.');
		let current = obj;

		for (const key of keys) {
			if (current === null || current === undefined) {
				return null;
			}
			current = current[key];
		}

		return current;
	}

	function sortRecursive(nodes: any[]): any[] {
		// 对当前层级进行排序
		const sortedNodes = [...nodes].sort((a, b) => {
			const aValue = getNestedValue(a, fieldPath);
			const bValue = getNestedValue(b, fieldPath);

			// 处理 null, undefined 的情况，将它们排到最后
			if (aValue == null && bValue == null) return 0;
			if (aValue == null) return 1;
			if (bValue == null) return -1;

			// 数值比较
			if (typeof aValue === 'number' && typeof bValue === 'number') {
				return isDesc ? bValue - aValue : aValue - bValue;
			}

			// 字符串比较（先尝试转换为数字）
			const aNum = Number(aValue);
			const bNum = Number(bValue);

			if (!isNaN(aNum) && !isNaN(bNum)) {
				return isDesc ? bNum - aNum : aNum - bNum;
			}

			// 字符串比较
			const aStr = String(aValue);
			const bStr = String(bValue);

			if (isDesc) {
				return bStr.localeCompare(aStr);
			} else {
				return aStr.localeCompare(bStr);
			}
		});

		// 递归排序子节点
		return sortedNodes.map(node => {
			if (node[childrenKey] && Array.isArray(node[childrenKey]) && node[childrenKey].length > 0) {
				return {
					...node,
					[childrenKey]: sortRecursive(node[childrenKey])
				};
			}
			return node;
		});
	}

	return sortRecursive(data);
}



/**
 * 格式化多层级树形数据 - 千分号格式化和枚举解析
 * @param data 多层级数组数据
 * @param formatFields 需要格式化的字段数组 (支持嵌套字段如 "obj.fieldName")
 * @param enumFields 需要解析枚举的字段数组 (支持嵌套字段)
 * @param enumData 枚举对应的数据数组，按顺序对应 enumFields
 * @param childrenKey 子节点的key名称，默认为 'children'
 * @returns 格式化后的数组数据
 */
export function formatTreeData(
	data: any[],
	formatFields: string[] = [],
	enumFields: string[] = [],
	enumData: any[] = [],
	percentFields: string[] = [],
	childrenKey: string = 'children'
): any[] {
	if (!data || !Array.isArray(data) || data.length === 0) {
		return data;
	}

	/**
	 * 根据字段路径获取对象的值
	 * @param obj 目标对象
	 * @param path 字段路径，如 "obj.fieldName"
	 * @returns 字段值
	 */
	function getNestedValue(obj: any, path: string): any {
		if (!obj || typeof obj !== 'object') {
			return undefined;
		}

		const keys = path.split('.');
		let current = obj;

		for (const key of keys) {
			if (current === null || current === undefined) {
				return undefined;
			}
			current = current[key];
		}

		return current;
	}

	/**
	 * 根据字段路径设置对象的值
	 * @param obj 目标对象
	 * @param path 字段路径，如 "obj.fieldName"
	 * @param value 要设置的值
	 */
	function setNestedValue(obj: any, path: string, value: any): void {
		if (!obj || typeof obj !== 'object') {
			return;
		}

		const keys = path.split('.');
		let current = obj;

		for (let i = 0; i < keys.length - 1; i++) {
			const key = keys[i];
			if (current[key] === null || current[key] === undefined || typeof current[key] !== 'object') {
				current[key] = {};
			}
			current = current[key];
		}

		current[keys[keys.length - 1]] = value;
	}

	/**
	 * 将数字格式化为千分号字符串
	 * @param value 要格式化的值
	 * @returns 格式化后的字符串
	 */
	function formatNumber(value: any): string {
		if (value === null || value === undefined || value === '') {
			return '';
		}

		const num = Number(value);
		if (isNaN(num)) {
			return String(value);
		}

		return num.toLocaleString();
	}

	/**
	 * 根据枚举数据解析值
	 * @param value 要解析的值
	 * @param enumData 枚举数据，支持对象格式 {1000:"枚举1",2000:"枚举2"} 或数组格式
	 * @returns 解析后的值
	 */
	function parseEnumValue(value: any, enumData: any): any {
		if (!enumData) {
			return value;
		}

		// 支持对象格式 {1000:"枚举1",2000:"枚举2"}
		if (typeof enumData === 'object' && !Array.isArray(enumData)) {
			// 直接匹配
			let enumValue = enumData[value];
			if (enumValue !== undefined) {
				return enumValue;
			}

			// 类型转换匹配：尝试字符串和数字的相互转换
			const valueStr = String(value);
			const valueNum = Number(value);

			// 如果原值是数字，尝试用字符串匹配
			if (!isNaN(valueNum)) {
				enumValue = enumData[valueStr];
				if (enumValue !== undefined) {
					return enumValue;
				}
			}

			// 如果原值是字符串，尝试用数字匹配
			if (!isNaN(valueNum)) {
				enumValue = enumData[valueNum];
				if (enumValue !== undefined) {
					return enumValue;
				}
			}

			// 遍历所有键进行宽松匹配
			for (const key in enumData) {
				if (String(key) === String(value) || Number(key) === Number(value)) {
					return enumData[key];
				}
			}

			return value;
		}

		// 支持数组格式（保持向下兼容）
		if (Array.isArray(enumData) && enumData.length > 0) {
			const enumItem = enumData.find(item => {
				// 支持多种匹配方式，包括类型转换
				const itemValue = item.value || item.id || item.key || item.code;
				return itemValue === value ||
					String(itemValue) === String(value) ||
					Number(itemValue) === Number(value);
			});

			if (enumItem) {
				// 返回枚举项的显示文本
				return enumItem.label || enumItem.name || enumItem.text || enumItem.title || value;
			}
		}

		return value;
	}

	function formatRecursive(nodes: any[]): any[] {
		return nodes.map(node => {
			// 深拷贝节点，避免修改原数据
			const newNode = JSON.parse(JSON.stringify(node));

			// 处理格式化字段
			formatFields.forEach(fieldPath => {
				const value = getNestedValue(newNode, fieldPath);
				if (value !== undefined) {
					const formattedValue = formatNumber(value);
					setNestedValue(newNode, fieldPath, formattedValue);
				}
			});

			// 处理枚举字段
			enumFields.forEach((fieldPath, index) => {
				const value = getNestedValue(newNode, fieldPath);
				if (value !== undefined && enumData[index]) {
					const parsedValue = parseEnumValue(value, enumData[index]);
					setNestedValue(newNode, fieldPath, parsedValue);
				}
			});

			// 处理百分号字段
			percentFields.forEach((fieldPath) => {
				const value = getNestedValue(newNode, fieldPath);
				if (value !== undefined) {
					// 如果值是null，设置为空字符串
					if (value === null) {
						setNestedValue(newNode, fieldPath, '');
						return;
					}

					const currentValueStr = String(value);

					// 如果值后面还没有百分号，则添加
					if (!currentValueStr.endsWith('%')) {
						const percentValue = currentValueStr + '%';
						setNestedValue(newNode, fieldPath, percentValue);
					}
				}
			});

			// 递归处理子节点
			if (newNode[childrenKey] && Array.isArray(newNode[childrenKey]) && newNode[childrenKey].length > 0) {
				newNode[childrenKey] = formatRecursive(newNode[childrenKey]);
			}

			return newNode;
		});
	}

	return formatRecursive(data);
}

export async function getUserIP(): Promise<string> {
	try {
		// 尝试多个第三方API服务
		const apis = [
			'https://api.ipify.org?format=json',
			'https://ipapi.co/json/',
			'https://jsonip.com/',
			'https://httpbin.org/ip'
		];

		for (const api of apis) {
			try {
				const response = await fetch(api, {
					method: 'GET',
					timeout: 5000, // 5秒超时
				});

				if (!response.ok) {
					continue;
				}

				const data = await response.json();

				// 根据不同API返回格式获取IP
				if (data.ip) {
					return data.ip;
				} else if (data.origin) {
					// httpbin返回格式
					return data.origin;
				}
			} catch (error) {
				console.warn(`IP API ${api} 请求失败:`, error);
				continue;
			}
		}

		throw new Error('所有IP服务都无法访问');
	} catch (error) {
		console.error('获取IP地址失败:', error);
		return '获取失败';
	}
}

/**
 * 根据IP地址获取地理位置信息
 * @param ip IP地址
 * @returns Promise<object> 地理位置信息
 */
export async function getLocationByIP(ip: string, ak: string): Promise<{
	country?: string;
	province?: string;
	city?: string;
	district?: string;
	isp?: string;
	success: boolean;
	message?: string;
}> {
	if (!ip || ip === '获取失败') {
		return {
			success: false,
			message: 'IP地址无效'
		};
	}

	if (!ak) {
		return {
			success: false,
			message: '百度地图API密钥(ak)不能为空'
		};
	}

	try {
		const response = await fetch(`/baidu-api/location/ip?ip=${ip}&ak=${ak}`, {
			method: 'GET',
			timeout: 8000,
			headers: {
				'Accept': 'application/json'
			}
		});

		if (!response.ok) {
			throw new Error(`HTTP错误: ${response.status}`);
		}

		const data = await response.json();

		// 检查百度API返回状态
		if (data.status !== 0) {
			return {
				success: false,
				message: `百度API错误: ${data.message || '未知错误'}`
			};
		}

		// 解析百度地图返回的数据
		const content = data.content;
		const addressDetail = content.address_detail;

		return {
			country: '中国', // 百度地图IP定位默认中国
			province: addressDetail.province || '',
			city: addressDetail.city || '',
			district: addressDetail.district || '',
			isp: content.address || '',
			success: true
		};

	} catch (error) {
		console.error('获取地理位置失败:', error);
		return {
			success: false,
			message: '获取地理位置失败'
		};
	}
}