package jnpf.personnels.utils;

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 司龄计算工具类
 * 用于计算员工司龄并显示为自然年月日格式（示例：1 年 3 个月 15 天）
 * 
 * @author Assistant
 * @date 2026/03/06
 */
public class CompanyAgeUtil {

    /**
     * 计算司龄，返回自然年月日格式
     * 格式：X 年 Y 个月 Z 天
     * 
     * @param startDate 入职日期
     * @param endDate 结束日期（通常为当前日期，为 null 时使用当前日期）
     * @return 司龄字符串，格式如：1 年 3 个月 15 天
     */
    public static String calculateServiceAge(Date startDate, Date endDate) {
        if (startDate == null) {
            return "0 年 0 个月 0 天";
        }
        
        // 如果结束日期为空，使用当前日期
        if (endDate == null) {
            endDate = new Date();
        }
        
        // 转换为 LocalDate 进行计算
        LocalDate startLocalDate;
        LocalDate endLocalDate;
        if (startDate instanceof java.sql.Date) {
            startLocalDate = ((java.sql.Date) startDate).toLocalDate();
        } else {
            startLocalDate = startDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        if (endDate instanceof java.sql.Date) {
            endLocalDate = ((java.sql.Date) endDate).toLocalDate();
        } else {
            endLocalDate = endDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        
        // 确保开始日期早于结束日期
        if (startLocalDate.isAfter(endLocalDate)) {
            return "0 年 0 个月 0 天";
        }
        
        // 计算完整的月份差异
        long monthsBetween = ChronoUnit.MONTHS.between(startLocalDate, endLocalDate);
        
        // 计算剩余天数
        LocalDate tempDate = startLocalDate.plusMonths(monthsBetween);
        long daysBetween = ChronoUnit.DAYS.between(tempDate, endLocalDate);
        
        // 计算年、月、日
        long years = monthsBetween / 12;
        long months = monthsBetween % 12;
        long days = daysBetween;
        
        // 处理边界情况：如果天数接近一个月，调整为月
        if (days >= 30) {
            months += days / 30;
            days = days % 30;
        }
        
        // 如果月份超过 12，调整为年
        if (months >= 12) {
            years += months / 12;
            months = months % 12;
        }
        
        return years + "年" + months + "个月" + days + "天";
    }
    
    /**
     * 计算司龄到当前日期
     * 
     * @param startDate 入职日期
     * @return 司龄字符串，格式如：1 年 3 个月 15 天
     */
    public static String calculateServiceAgeToNow(Date startDate) {
        return calculateServiceAge(startDate, null);
    }
    
    /**
     * 精简版司龄显示（省略为 0 的单位）
     * 例如：1 年 3 个月、3 个月 15 天、1 年、15 天
     * 
     * @param startDate 入职日期
     * @param endDate 结束日期（为 null 时使用当前日期）
     * @return 精简版司龄字符串
     */
    public static String calculateServiceAgeShort(Date startDate, Date endDate) {
        String fullAge = calculateServiceAge(startDate, endDate);
        
        StringBuilder result = new StringBuilder();
        
        // 提取年、月、日
        String[] parts = fullAge.split("年");
        long years = Long.parseLong(parts[0]);
        
        String[] monthParts = parts[1].split("个月");
        long months = Long.parseLong(monthParts[0]);
        
        String[] dayParts = monthParts[1].split("天");
        long days = Long.parseLong(dayParts[0]);
        
        if (years > 0) {
            result.append(years).append("年");
        }
        
        if (months > 0) {
            result.append(months).append("个月");
        }
        
        if (days > 0 || result.length() == 0) {
            result.append(days).append("天");
        }
        
        return result.toString();
    }
    
    /**
     * 获取司龄的总天数
     * 
     * @param startDate 入职日期
     * @param endDate 结束日期（为 null 时使用当前日期）
     * @return 总天数
     */
    public static long getTotalDays(Date startDate, Date endDate) {
        if (startDate == null) {
            return 0;
        }
        
        if (endDate == null) {
            endDate = new Date();
        }
        
        LocalDate startLocalDate;
        LocalDate endLocalDate;
        if (startDate instanceof java.sql.Date) {
            startLocalDate = ((java.sql.Date) startDate).toLocalDate();
        } else {
            startLocalDate = startDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        if (endDate instanceof java.sql.Date) {
            endLocalDate = ((java.sql.Date) endDate).toLocalDate();
        } else {
            endLocalDate = endDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        
        return ChronoUnit.DAYS.between(startLocalDate, endLocalDate);
    }
    
    /**
     * 获取司龄的总月数（包含零头天数折算）
     * 
     * @param startDate 入职日期
     * @param endDate 结束日期（为 null 时使用当前日期）
     * @return 总月数（保留两位小数）
     */
    public static double getTotalMonths(Date startDate, Date endDate) {
        if (startDate == null) {
            return 0.0;
        }
        
        if (endDate == null) {
            endDate = new Date();
        }
        
        LocalDate startLocalDate;
        LocalDate endLocalDate;
        if (startDate instanceof java.sql.Date) {
            startLocalDate = ((java.sql.Date) startDate).toLocalDate();
        } else {
            startLocalDate = startDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        if (endDate instanceof java.sql.Date) {
            endLocalDate = ((java.sql.Date) endDate).toLocalDate();
        } else {
            endLocalDate = endDate.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        }
        
        long months = ChronoUnit.MONTHS.between(startLocalDate, endLocalDate);
        LocalDate tempDate = startLocalDate.plusMonths(months);
        long days = ChronoUnit.DAYS.between(tempDate, endLocalDate);
        
        return months + (days / 30.0);
    }

    /**
     * 计算员工从入职日期到现在的司龄（以年、月、天为单位）
     *
     * @param startDateD 入职日期
     * @param endDateD 结束日期
     * @return 司龄字符串，格式如 "x年x月x天"
     */
    public static  String calculateSeniority(Date startDateD,Date endDateD) {

        // 参数校验
        if (startDateD == null || endDateD == null) {
            return "0天";
        }
        // 处理 java.sql.Date 和 java.util.Date
        LocalDate startDate;
        LocalDate endDate;
        if (startDateD instanceof java.sql.Date) {
            startDate = ((java.sql.Date) startDateD).toLocalDate();
        } else {
            startDate = startDateD.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
        if (endDateD instanceof java.sql.Date) {
            endDate = ((java.sql.Date) endDateD).toLocalDate();
        } else {
            endDate = endDateD.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
        // 确保开始日期不晚于当前日期
        if (startDate.isAfter(endDate)) {
            return "0天";
        }

        Period period = Period.between(startDate, endDate);
        int years = period.getYears();
        int months = period.getMonths();
        int days = period.getDays();

        StringBuilder sb = new StringBuilder();

        if (years > 0) {
            sb.append(years).append("年");
        }
        if (months > 0) {
            sb.append(months).append("月");
        }
        if (days > 0 || sb.length() == 0) { // 避免返回空字符串，至少保留“0天”
            sb.append(days).append("天");
        }

        return sb.toString();
    }
}
