<template>
	<view class="container">
		<div style="display: flex;flex-direction: column;">
			<!-- <div style="display: flex;justify-content: space-between;align-items: center;">
				<text class="section-title">输入</text>
				<el-button size="small" type="primary" @click="addTargetRow">添加</el-button>
			</div> -->
			<el-table size="small" border :data="inputData" max-height="calc(100vh - 450px)" empty-text="暂无数据，请添加猫咪势力">
				<el-table-column label="顺序" width="55px">
					<template #="{ $index }">{{ $index + 1 }}</template>
				</el-table-column>

				<el-table-column label="目标角色">
					<template #header>
						<div style="display: flex;justify-content: space-between;">
							目标角色
							<el-tooltip content="编辑" placement="top">
								<el-button type="primary" link style="margin-left: 0px;" @click="editRow('母', '目标角色')">
									<uni-icons style="color: #409eff" size="14" type="compose" />
								</el-button>
							</el-tooltip>
						</div>
					</template>

					<el-table-column label="公" min-width="60px" prop="targetMale" />
					<el-table-column label="母" min-width="60px" prop="targetFemale" />
				</el-table-column>

				<el-table-column label="备选角色">
					<template #header>
						<div style="display: flex;justify-content: space-between;">
							备选角色
							<el-tooltip content="编辑" placement="top">
								<el-button type="primary" link style="margin-left: 0px;" @click="editRow('公', '备选角色')">
									<uni-icons style="color: #409eff" size="14" type="compose" />
								</el-button>
							</el-tooltip>
						</div>
					</template>

					<el-table-column label="公" min-width="60px" prop="backupMale" />
					<el-table-column label="母" min-width="60px" prop="backupFemale" />
				</el-table-column>
			</el-table>
		</div>

		<div style="display: flex;">
			<el-button type="primary" style="width:100%;margin-bottom: 10px;margin-top:10px" @click="switchRoles">
				交换角色
			</el-button>

			<el-button type="primary" style="width:100%;margin-bottom: 10px;margin-top:10px"
				@click="calculateBestMatch">
				计算最佳配对
			</el-button>
		</div>

		<!-- 输出表格 -->
		<view class="section" v-if="outputData.length > 0">

			<div style="display: flex;justify-content: space-between;" >
				<text class="section-title">输出， 计算时间 {{ time }} ms </text>
				<span>差额: {{ powerDifference }}</span>
			</div>

			<el-table size="small" border :data="outputData">
				<el-table-column label="顺序" width="55px">
					<template #="{ $index }">{{ $index + 1 === outputData.length ? '合计' : $index + 1}}</template>
				</el-table-column>


				<el-table-column label="目标角色">
					<el-table-column label="公" min-width="60px" prop="targetMale" />
					<el-table-column label="母" min-width="60px" prop="targetFemale" />
				</el-table-column>

				<el-table-column label="备选角色">
					<el-table-column label="公" min-width="60px" prop="backupMale" />
					<el-table-column label="母" min-width="60px" prop="backupFemale" />
				</el-table-column>
			</el-table>
		</view>


		<uni-popup ref="batchRef" :is-mask-click="false">
			<div
				style="display: flex;flex-direction: column;justify-content: center;padding: 10px; width: 95%;background: #fff;border-radius: 10px;padding: 10px;">
				<div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;">
					<span></span>
					<h4 style="margin-bottom: 10px"> 编辑{{ role }}</h4>
					<uni-icons type="closeempty" size="18" @click="batchRef.close()"></uni-icons>
				</div>


				<span class="dialog-title">猫咪势力(公)</span>
				<textarea v-model="malePowers" placeholder="用逗号隔开，如:200,10,100"
					style="height: 70px;border: 1px solid #dfe2e5" />

				<span class="dialog-title">猫咪势力(母)</span>
				<textarea v-model="feMalePowers" placeholder="用逗号隔开，如:200,10,100"
					style="height: 70px;border: 1px solid #dfe2e5" />


				<button size='mini' type="primary" @click="handleConfirm">保存</button>
			</div>
		</uni-popup>

	</view>
</template>

<script setup>
import { ref, computed } from 'vue';
import { ElMessage } from "element-plus"

const gender = ref("")
const powers = ref("")
const time = ref("")

const malePowers = ref('')
const feMalePowers = ref('')
const role = ref("")

const type = ref('')

const mockData = [

]

const inputData = ref(mockData);
const outputData = ref([]);

const batchRef =  ref(null)

function editRow(_gender, _role) {
	type.value = 'edit'
	gender.value = _gender
	role.value = _role
	
	const roleProp = role.value === '目标角色' ? 'target' : 'backup'
	malePowers.value = inputData.value.map(item => item[`${roleProp}Male`]).filter(item => !!item).join(',')
	feMalePowers.value = inputData.value.map(item => item[`${roleProp}Female`]).filter(item => !!item).join(',')
	batchRef.value.open()
}


function switchRoles(){
	outputData.value = []
	// const cloneInputData = inputData.value.map(item => ({ ...item }))
	const backups = inputData.value.map(item => ({ male: item.backupMale, female: item.backupFemale }))
	const targets = inputData.value.map(item => ({ male: item.targetMale, female: item.targetFemale }))
	
	inputData.value = inputData.value.map((_, index) => ({
		backupFemale: targets[index]?.female || null,
		backupMale: targets[index]?.male || null,
		targetFemale: backups[index]?.female || null,
		targetMale: backups[index]?.male || null,
	}))

}

const powerDifference = ref(0)

// 目标角色操作
const addTargetRow = () => {
	gender.value = ''
	powers.value = ''
	role.value = ''
	batchRef.value.open()
};


function isPositiveInteger(str) {
    return /^[1-9]\d*$/.test(str);
}

function generatePowers(_powers, gender){
	const keys = ['targetMale', 'targetFemale', 'backupMale', 'backupFemale']
	
	_powers = _powers.replace(/，|、|,/g, ',')
	const powerSet = _powers.split(',').map(item => item.trim()).filter(item => item !== '')
	
	const isOk = powerSet.every(num => isPositiveInteger(num))

	if (!isOk && powerSet.length !== 0) return false

	
	const roleProp = role.value === '目标角色' ? 'target' : 'backup'
	const genderProp = gender === '公' ? 'Male' : 'Female'


	inputData.value.forEach((_, index) => {
		inputData.value[index][`${roleProp}${genderProp}`] = null
	})

	const prop = `${roleProp}${genderProp}`
	const values = inputData.value.map(item => item[prop]).filter(value => value);

	if (inputData.value.length === 0) {
		for (let index = 0; index < powerSet.length; index++) {
			const item = {}
			keys.forEach(key => {
				if (key === prop) {
					item[key] = powerSet[index]
				} else {
					item[key] = null
				}
			})

			inputData.value.push(item)
		}

	} else if (values.length < inputData.value.length) {
		let pIndex = -1
		for (let index = values.length; index < inputData.value.length; index++) {
			pIndex += 1
			inputData.value[index][prop] = powerSet[pIndex]
		}

		const calcNum = powerSet.length - (pIndex + 1)

		for (let index = 0; index < calcNum; index++) {
			pIndex += 1
			const item = {}

			keys.forEach(key => {
				if (key === prop) {
					item[key] = powerSet[pIndex]
				} else {
					item[key] = null
				}
			})

			inputData.value.push(item)
		}
	}

	inputData.value = inputData.value.filter(item => {
		if(!item.backupFemale && !item.backupMale && !item.targetFemale && !item.targetMale){
			return false
		}
		
		return true
	})
	
	console.log(inputData.value)
}


function handleConfirm(){	
	const _malePowers = malePowers.value.trim()
	const _feMalePowers = feMalePowers.value.trim()

	const isMaleOk = generatePowers(_malePowers, '公')
	const isFemakeOk = generatePowers(_feMalePowers, '母')
	
	if(typeof isMaleOk === 'boolean' && !isMaleOk){
		ElMessage.warning('势力必须为数字')
		return
	}	else if(typeof isFemakeOk === 'boolean' && !isFemakeOk){
		ElMessage.warning('势力必须为数字')
		return
	}
	
	
	batchRef.value.close()
}

// 生成数组的所有组合（辅助函数，用于生成指定个数元素的组合情况）
function getCombinations(arr, num) {
    const result = [];
	if (num === 0) { return [[]]; }


    for (let i = 0; i < arr.length; i++) {
        const element = arr[i];

        const remainingCombos = getCombinations(arr.slice(i + 1), num - 1);

		for (const combo of remainingCombos) {
            result.push([element].concat(combo));
        }
    }

    return result;
}


function calculateBestMatch() {
	let startTime = new Date().getTime()
	let endTime = null
			
	outputData.value = []

	const targetData = []
	const backupData = []

	inputData.value.forEach(item => {
		if (item.targetMale) { targetData.push({ gender: '公', power: item.targetMale }) }
		if (item.targetFemale) { targetData.push({ gender: '母', power: item.targetFemale }) }
		if (item.backupMale) { backupData.push({ gender: '公', power: item.backupMale }) }
		if (item.backupFemale) { backupData.push({ gender: '母', power: item.backupFemale }) }
	})


	const targetMale = targetData.filter(item => item.gender === '公').map(item => Number(item.power));
	const targetFemale = targetData.filter(item => item.gender === '母').map(item => Number(item.power));
	const backupMale = backupData.filter(item => item.gender === '公').map(item => Number(item.power));
	const backupFemale = backupData.filter(item => item.gender === '母').map(item => Number(item.power));
	// const targetMale = [153, 91, 77, 138, 90, 80, 60, 54, 52, 52, 52];
	// const targetFemale = [121, 118, 115, 86, 84, 84, 59, 53, 51];
	// const backupMale = [180, 165, 158, 154, 152, 151, 150, 150, 102, 101, 101, 93, 61, 30, 30, 29, 29, 29, 27, 10, 10];
	// const backupFemale = [174, 152, 147, 102, 101, 98, 98, 97, 62, 60, 58, 19]; 

	// const targetMale = [238, 90, 90];
	// const targetFemale = [86, 84, 84];
	// const backupMale = [153, 91, 77];
	// const backupFemale = [121, 118, 115]; 
	if(targetFemale.length + targetFemale.length > 20){
		ElMessage.warning('目标角色公数据与母数据的和不能超过20条')
		return
	}
	
	if(backupMale.length > 20){
		ElMessage.warning('备选角色的公数据不能超过20条')
		return
	}
	
	if(backupFemale.length > 20){
		ElMessage.warning('备选角色的母数据不能超过20条')
		return
	}
	

	if (targetFemale.length > backupMale.length && backupMale.length !== 0){
		ElMessage.warning('备选角色的公数据长度必须大于或等于目标角色的母数据')
		return
	}

	if (targetMale.length > backupFemale.length && backupFemale.length !== 0) {
		ElMessage.warning('备选角色的母数据长度必须或等于大于目标角色的公数据')
		return
	}

	const targetMaleLen = targetMale.length;
	const targetFemaleLen = targetFemale.length;


	let targetWeight = 0
	if (backupMale.length === 0){
		targetWeight =  targetMale.reduce((acc, val) => acc + val, 0);
	} else if(backupFemale.length === 0){
		targetWeight = targetFemale.reduce((acc, val) => acc + val, 0)
	} else if(backupMale.length !== 0 && backupFemale.length !== 0){
		targetWeight = targetMale.reduce((acc, val) => acc + val, 0) + targetFemale.reduce((acc, val) => acc + val, 0);
	}

	let minDifference = Infinity; 
    let bestfemaleCombination = null;
    let bestMaleCombination = null;
	const femaleCombinations = getCombinations(backupFemale, targetMaleLen);
	const maleCombinations = getCombinations(backupMale, targetFemaleLen);

	if (femaleCombinations.length !== 0 && maleCombinations.length !== 0){
		for (const femaleComb of femaleCombinations) {
			for (const maleComb of maleCombinations) {
				const totalWeight = femaleComb.reduce((acc, val) => acc + val, 0) + maleComb.reduce((acc, val) => acc + val, 0);
				const difference = Math.abs(totalWeight - targetWeight);
				if (difference < minDifference) {
					minDifference = difference;
					bestfemaleCombination = femaleComb;
					bestMaleCombination = maleComb;
					if (minDifference == 0) {
						break;
					}
				}
			}
		}
	}


	// 备选数据的母为空
	if (femaleCombinations.length === 0 && maleCombinations.length !== 0) {
		for (const maleComb of maleCombinations) {
			const totalWeight = maleComb.reduce((acc, val) => acc + val , 0);
			const difference = Math.abs(totalWeight - targetWeight);
			if (difference < minDifference) {
				minDifference = difference;
				bestMaleCombination = maleComb;
				if (minDifference == 0) {
					break;
				}
			}
		}
	}

	// 备选数据的公为空
	if (femaleCombinations.length !== 0 && maleCombinations.length === 0) {
		for (const femaleComb of femaleCombinations) {
				const totalWeight = femaleComb.reduce((acc, val) => acc + val, 0)
				const difference = Math.abs(totalWeight - targetWeight);
				if (difference < minDifference) {
					minDifference = difference;
					bestfemaleCombination = femaleComb;
					// bestMaleCombination = maleComb;
					if (minDifference == 0) {
						break;
					}
				}
		}
	}

	bestMaleCombination && bestMaleCombination.sort((a, b) => b - a)
	bestfemaleCombination && bestfemaleCombination.sort((a, b) => b - a)
	targetMale.sort((a, b) =>  b - a)
	targetFemale.sort((a, b) =>  b - a)

	if (!bestMaleCombination && !bestfemaleCombination){ return }


	bestfemaleCombination && targetMale.forEach((_, index) => {
		outputData.value.push({
			targetMale: targetMale[index],
			targetFemale: null,
			backupMale: null,
			backupFemale: bestfemaleCombination[index]
		})
	})
	
	
	const ml = targetMale.length
	const fl = targetFemale.length
	
	for(let index = 0; index < fl; index ++){
		if(outputData.value[index]){
			outputData.value[index].targetFemale = targetFemale[index]
			outputData.value[index].backupMale = bestMaleCombination[index]
		} else {
			outputData.value.push({
				targetMale: null,
				targetFemale: targetFemale[index],
				backupMale: bestMaleCombination[index],
				backupFemale: null
			})
			
		}
	}

	outputData.value.push({
		targetMale: outputData.value.reduce((prev, current) => prev + current.targetMale,0),
		targetFemale: outputData.value.reduce((prev, current) => prev + current.targetFemale,0),
		backupMale: outputData.value.reduce((prev, current) => prev + current.backupMale,0),
		backupFemale: outputData.value.reduce((prev, current) => prev + current.backupFemale,0)
	})

	powerDifference.value = minDifference
	 endTime = new Date().getTime()
	 time.value = endTime - startTime
}
</script>

<style>
textarea {
	font-size: 13px;
	padding: 8px;
}
</style>

<style lang="scss" scoped>

.dialog-title {
			line-height: 30px;
			padding-left: 10px;
			font-size: 14px;
}


	.table-wrapper {
		font-size: 14px !important;
	}
.custom-picker {
    border: 1px solid #e3e3e3;
    padding: 3px 5px;
    text-align: center;
	width: 100%;
	
    
    div {
        display: flex;
        justify-content: space-between;
        
        text {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
        }
    }
}

.container {
    padding: 20px;
}

.section {
    margin-bottom: 20px;
}

.section-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 10px;
}

.input {
    width: 100%;
    text-align: center;
    border: 1px solid #ddd;
    padding: 5px;
}

button {
    margin: 5px;
}

.add-btn,
.calculate-btn {
    background-color: #007bff;
    color: white;
    padding: 10px;
    font-size: 16px;
    text-align: center;
    border-radius: 5px;
}

.delete-btn {
    background-color: #ff4d4f;
    color: white;
    padding: 5px;
    font-size: 14px;
    border-radius: 5px;
}

.summary {
    margin-top: 20px;
    font-size: 14px;
    text-align: right;
    font-weight: bold;
}
</style>
