package com.xinyilu.common.utils;

import com.xinyilu.common.exception.ServiceException;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * @Description 年龄工具类
 * @Author 纪寒
 * @Date 2022-08-10 13:32:59
 */
public class AgeUtil {

    /**
     * 3岁
     */
    private static final double THREE = 3.0;

    /**
     * 3.5岁
     */
    private static final double THREE_FIVE = 3.5;

    /**
     * 4.0岁
     */
    private static final double FOUR = 4.0;

    /**
     * 4.5岁
     */
    private static final double FOUR_FIVE = 4.5;

    /**
     * 5.0岁
     */
    private static final double FIVE = 5.0;

    /**
     * 5.5岁
     */
    private static final double FIVE_FIVE = 5.5;

    /**
     * 6.0岁
     */
    private static final double SIX = 6.0;

    /**
     * 根据出生日期计算年龄数值
     *
     * @param date 出生日期
     * @return 年龄数值
     */
    public static double getStudentAgeMonth(String date) {
        if (StringUtils.isBlank(date)) {
            throw new ServiceException("请输入正确的出生日期！");
        }
        String[] data = StringUtils.split(date, "-");
        if (data.length < 3) {
            throw new ServiceException("请输入正确的出生日期！");
        }
        Calendar birthday = new GregorianCalendar(Integer.parseInt(data[0]), Integer.parseInt(data[1]), Integer.parseInt(data[2]));
        Calendar now = Calendar.getInstance();
        int day = now.get(Calendar.DAY_OF_MONTH) - birthday.get(Calendar.DAY_OF_MONTH);
        //月份从0开始计算，所以需要+1
        int month = now.get(Calendar.MONTH) + 1 - birthday.get(Calendar.MONTH);
        BigDecimal monthFraction;
        int year = now.get(Calendar.YEAR) - birthday.get(Calendar.YEAR);
        //按照减法原理，先day相减，不够向month借；然后month相减，不够向year借；最后year相减。
        if (day < 0) {
            month -= 1;
            //得到上一个月，用来得到上个月的天数。
            now.add(Calendar.MONTH, -1);
        }
        if (month < 0) {
            //当前月份加12个月
            monthFraction = BigDecimal.valueOf(month).add(BigDecimal.valueOf(12)).divide(BigDecimal.valueOf(12), 1, RoundingMode.HALF_UP);
            year--;
        } else {
            //当前月份
            monthFraction = BigDecimal.valueOf(month).divide(BigDecimal.valueOf(12), 1, RoundingMode.HALF_UP);
        }
        BigDecimal bigDecimal = BigDecimal.ZERO;
        if (year >= 0) {
            bigDecimal = bigDecimal.add(BigDecimal.valueOf(year));
        }
        if ((monthFraction.compareTo(BigDecimal.ZERO) > 0)) {
            bigDecimal = bigDecimal.add(monthFraction);
        }
        //今天出生
        if (year == 0 && month == 0 && day == 0) {
            return BigDecimal.ZERO.doubleValue();
        }
        double studentAgeMonth = bigDecimal.doubleValue();
        //将真实年龄与各年龄对比取值
        double age = 0.0;
        if (studentAgeMonth < THREE) {
            age = THREE;
        }
        age = getAge(studentAgeMonth, age, THREE, THREE_FIVE, FOUR, FOUR_FIVE);
        age = getAge(studentAgeMonth, age, FOUR_FIVE, FIVE, FIVE_FIVE, SIX);
        if (studentAgeMonth >= SIX) {
            age = SIX;
        }
        return age;
    }

    /**
     * 根据不同年龄范围获取不同的年龄值
     *
     * @param studentAgeMonth 真实年龄
     * @param age             返回年龄值
     * @param first           年龄起始值1
     * @param second          年龄结束值1
     * @param third           年龄起始值2
     * @param forth           年龄结束值2
     * @return 年龄取值
     */
    private static double getAge(double studentAgeMonth, double age, double first, double second, double third, double forth) {
        if (studentAgeMonth >= first && studentAgeMonth < second) {
            age = first;
        }
        if (studentAgeMonth >= second && studentAgeMonth < third) {
            age = second;
        }
        if (studentAgeMonth >= third && studentAgeMonth < forth) {
            age = third;
        }
        return age;
    }
}
