package service

import (
	"math"
	"regexp"
	"server/common"
	"server/modules/user/vo"
	"server/modules/yx/dto"
	"strconv"
	"strings"
)

// ScoreUtil 分数计算工具函数集合
// 移植自 Java 版本的 ScoreUtil.java

var (
	BigDecimal0    = 0.0
	BigDecimal05   = 0.5
	BigDecimal075  = 0.75
	BigDecimal0133 = 0.133
	BigDecimal0667 = 0.667
	BigDecimal004  = 0.04
	BigDecimal0467 = 0.467
	BigDecimal0067 = 0.067
	BigDecimal0333 = 0.333
	BigDecimal0093 = 0.093
	BigDecimal02   = 0.2
	BigDecimal07   = 0.7
	BigDecimal03   = 0.3
	BigDecimal04   = 0.4
	BigDecimal06   = 0.6
	BigDecimal1    = 1.0
	BigDecimal100  = 100.0
	BigDecimal150  = 150.0
	BigDecimal95x  = 95.0
	BigDecimal85x  = 85.0
	BigDecimal7p5  = 7.5
	BigDecimal5    = 5.0
)

// ComputeHistoryMajorEnrollScoreLineDifferenceWithRulesEnrollProbability 计算历年录取分差
func ComputeHistoryMajorEnrollScoreLineDifferenceWithRulesEnrollProbability(majorType string,
	rulesEnrollProbability, probabilityOperator string,
	HistoryMajorEnrollMap map[string]dto.YxHistoryMajorEnrollDTO) map[string]any {

	if len(HistoryMajorEnrollMap) == 0 {
		return map[string]any{"scoreDifference": 0.0}
	}

	sum := 0.0
	validYearCount := 0

	for _, enrollData := range HistoryMajorEnrollMap {
		admissionLine := enrollData.AdmissionLine
		controlLine := enrollData.ControlLine
		if admissionLine <= 0 || controlLine <= 0 {
			continue
		}
		// 计算分差
		currentDiff := admissionLine - controlLine

		// currentDiff := enrollData.ScoreLineDifference

		// 特殊逻辑：高职高专（非体育类）需计算分差率（分差/省控线）
		// Java: boolean isVocationalCollege = "高职高专".equals(enrollData.getBatch());
		// boolean isSportsMajor = "体育类".equals(enrollData.getMajorType());
		if "体育类" == majorType {
			if "2024" == enrollData.Year && "专过文排" != enrollData.EnrollmentCode && "文过专排" != enrollData.EnrollmentCode {
				currentDiff = currentDiff * common.Number7p5
			} else if "2024" == enrollData.Year && "文过专排" == enrollData.EnrollmentCode { // Placeholder
				currentDiff = currentDiff * common.Number5
			} else if "2023" == enrollData.Year {
				continue
			} else if rulesEnrollProbability == enrollData.RulesEnrollProbability { // Need field
				sum += currentDiff
				validYearCount++
				continue
			}
		} else {
			// 非高职高专 or 体育类：检查录取方式是否一致
			if probabilityOperator != enrollData.ProbabilityOperator {
				continue
			}
		}

		sum += currentDiff
		validYearCount++
	}

	averageDiff := 0.0
	if validYearCount > 0 {
		averageDiff = sum / float64(validYearCount)
	}

	return map[string]any{"scoreDifference": averageDiff}
}

// ConvertIntoScore 计算折合分
func ConvertIntoScore(rulesEnrollProbability string, culturalScore, professionalScore float64, operator string) float64 {
	score := 0.0
	if operator != "" {
		// operator: 例如: "文*0.5+专*0.5"
		parts := strings.Split(operator, "+")
		for _, part := range parts {
			subParts := strings.Split(part, "*")
			if len(subParts) == 2 {
				ratio, _ := strconv.ParseFloat(subParts[1], 64)
				if strings.Contains(subParts[0], "文") {
					score += culturalScore * ratio
				} else {
					score += professionalScore * ratio
				}
			}
		}
	}

	return round(score, 4)
}

// CrossingControlLine 判断是否过省控线
func CrossingControlLine(rulesEnrollProbability string, culturalScore, professionalScore, culturalControlLine, specialControlLine float64) bool {
	if rulesEnrollProbability == common.CulturalControlLineGuo {
		return culturalScore >= culturalControlLine
	} else if rulesEnrollProbability == common.SpecialControlLineGuo {
		return professionalScore >= specialControlLine
	} else if rulesEnrollProbability == common.CulturalControlLineGuoMain {
		return culturalScore >= specialControlLine
	}
	return culturalScore >= culturalControlLine && professionalScore >= specialControlLine
}

// CommonCheckEnrollProbability 计算录取率
func CommonCheckEnrollProbability(nowYearDiff, historyThreeYearDiff float64) float64 {
	enrollProbability := 0.0
	if nowYearDiff == 0 && historyThreeYearDiff > 0 {
		enrollProbability = 75.0 / historyThreeYearDiff
	} else if nowYearDiff == 0 && historyThreeYearDiff <= 0 {
		enrollProbability = 50.0
	} else if nowYearDiff > 0 && historyThreeYearDiff <= 0 {
		enrollProbability = nowYearDiff * 100 * 0.75
	} else if nowYearDiff < 0 && historyThreeYearDiff <= 0 {
		enrollProbability = 0.0
	} else {
		// (当前年分差/去年分差)*0.75 * 100
		if historyThreeYearDiff != 0 {
			enrollProbability = (nowYearDiff / historyThreeYearDiff) * 100 * 0.75
		}
	}
	return enrollProbability
}

// CommonCheckEnrollProbabilityBeilv 录取率倍率调整
func CommonCheckEnrollProbabilityBeilv(enrollProbability float64) float64 {
	if enrollProbability > 150 {
		return 95.0
	} else if enrollProbability > 100 {
		return 85.0
	} else if enrollProbability <= 0 {
		return 0.0
	}
	return enrollProbability
}

// OtherScoreJudge 其他录取要求
func OtherScoreJudge(professionalScore float64, userScoreVO vo.UserScoreVO, schoolMajorDTO dto.SchoolMajorDTO) bool {
	// 简单实现，参考 Java 逻辑
	if schoolMajorDTO.EnglishScoreLimitation > 0 && userScoreVO.EnglishScore < schoolMajorDTO.EnglishScoreLimitation {
		return false
	}
	if schoolMajorDTO.CulturalScoreLimitation > 0 && userScoreVO.CulturalScore < schoolMajorDTO.CulturalScoreLimitation {
		return false
	}
	// 专业分限制等...
	return true
}

// HasComputeEnrollProbabilityPermissions 判断是否有权限计算
func HasComputeEnrollProbabilityPermissions(nowBatch, majorBatch string) bool {
	return "" != nowBatch && "" != majorBatch
}

// round 四舍五入
func round(val float64, precision int) float64 {
	ratio := math.Pow(10, float64(precision))
	return math.Round(val*ratio) / ratio
}

// ReplaceLastZeroChar 格式化操作符字符串 (Java: replaceLastZeroChar)
func ReplaceLastZeroChar(input string) string {
	if input == "" {
		return ""
	}
	re := regexp.MustCompile(`(\d+\.\d*?)0+(\D|$)`)
	input = re.ReplaceAllString(input, "$1$2")
	input = strings.ReplaceAll(input, "1.", "1")
	// 简化处理
	return input
}
