package com.yd.csf.api.service.impl;

import com.yd.common.result.Result;
import com.yd.csf.api.service.ApiCsfCommonService;
import com.yd.csf.feign.request.common.ApiCsfCalculateRequest;
import com.yd.csf.feign.response.common.ApiCsfCalculateResponse;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

@Slf4j
@Service
public class ApiCsfCommonServiceImpl implements ApiCsfCommonService {

    // 身份证号码正则表达式（15位或18位）
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("(^\\d{15}$)|(^\\d{17}([0-9]|X|x)$)");
    // 日期格式
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

//    public static void main(String[] args) {
//        ApiCsfCalculateRequest request = new ApiCsfCalculateRequest();
//        request.setCalculateType(6);
//        request.setRequestValue("342522199409194514");
//        ApiCsfCommonService apiCsfCommonService = new ApiCsfCommonServiceImpl();
//        Result<List<ApiCsfCalculateResponse>> result = apiCsfCommonService.calculate(request);
//        System.out.println(result);
//    }

    /**
     * 计算-字段值
     * @param request
     * @return
     */
    @Override
    public Result<List<ApiCsfCalculateResponse>> calculate(ApiCsfCalculateRequest request) {
        List<ApiCsfCalculateResponse> responses = new ArrayList<>();
        try {
            // 参数校验
            if (request == null) {
                return Result.fail("请求参数不能为空");
            }

            if (request.getCalculateType() == null) {
                return Result.fail("计算类型不能为空");
            }

            // 创建响应对象
            ApiCsfCalculateResponse response = new ApiCsfCalculateResponse();
            response.setCalculateType(request.getCalculateType());
            response.setRequestValue(request.getRequestValue());
            response.setRequestValueList(request.getRequestValueList());

            String result;
            switch (request.getCalculateType()) {
                case 1:
                    // 1-通过中文自动加载全部大写的拼音
                    result = calculatePinyin(request.getRequestValue());
                    response.setResponseValue(result);
                    responses.add(response);
                    break;
                case 2:
                    // 2-身份证号码计算性别
                    result = calculateGenderFromIdCard(request.getRequestValue());
                    response.setResponseValue(result);
                    responses.add(response);
                    break;
                case 3:
                    // 3-身份证号码计算生日
                    result = calculateBirthdayFromIdCard(request.getRequestValue());
                    response.setResponseValue(result);
                    responses.add(response);
                    break;
                case 4:
                    // 4-生日计算年龄
                    result = calculateAgeFromBirthday(request.getRequestValue());
                    response.setResponseValue(result);
                    responses.add(response);
                    break;
                case 5:
                    // 5-身高和体重计算BMI指数
                    result = calculateBMI(request.getRequestValueList());
                    response.setResponseValue(result);
                    responses.add(response);
                    break;
                case 6:
                    // 6-身份证号码计算性别/生日/年龄
                    //性别
                    ApiCsfCalculateResponse response1 = new ApiCsfCalculateResponse();
                    //生日
                    ApiCsfCalculateResponse response2 = new ApiCsfCalculateResponse();
                    //年龄
                    ApiCsfCalculateResponse response3 = new ApiCsfCalculateResponse();
                    BeanUtils.copyProperties(request,response1);
                    response1.setCalculateType(2);
                    response1.setRequestValue(calculateGenderFromIdCard(request.getRequestValue()));
                    responses.add(response1);
                    BeanUtils.copyProperties(request,response2);
                    response2.setCalculateType(3);
                    response2.setRequestValue(calculateBirthdayFromIdCard(request.getRequestValue()));
                    responses.add(response2);
                    BeanUtils.copyProperties(request,response3);
                    response3.setCalculateType(4);
                    response3.setRequestValue(calculateAgeFromBirthday(response2.getRequestValue()));
                    responses.add(response3);
                    break;
                default:
                    return Result.fail("不支持的计算类型: " + request.getCalculateType());
            }

            return Result.success(responses);
        } catch (Exception e) {
            log.error("计算服务异常: ", e);
            return Result.fail("计算失败: " + e.getMessage());
        }
    }

    /**
     * 通过中文自动加载全部大写的拼音
     * @param chinese
     * @return
     */
    private String calculatePinyin(String chinese) {
        if (StringUtils.isBlank(chinese)) {
            throw new IllegalArgumentException("中文内容不能为空");
        }

        // 中文转拼音
        return convertChineseToPinyin(chinese).toUpperCase();
    }

    /**
     * 身份证号码计算性别
     * @param idCard
     * @return
     */
    private String calculateGenderFromIdCard(String idCard) {
        if (StringUtils.isBlank(idCard)) {
            throw new IllegalArgumentException("身份证号码不能为空");
        }

        if (!ID_CARD_PATTERN.matcher(idCard).matches()) {
            throw new IllegalArgumentException("身份证号码格式不正确");
        }

        // 获取性别位
        String genderCode;
        if (idCard.length() == 15) {
            // 15位身份证：最后一位是性别位（奇数为男，偶数为女）
            genderCode = idCard.substring(14, 15);
        } else {
            // 18位身份证：倒数第二位是性别位（奇数为男，偶数为女）
            genderCode = idCard.substring(16, 17);
        }

        int code = Integer.parseInt(genderCode);
        return code % 2 == 1 ? "男" : "女";
    }

    /**
     * 身份证号码计算生日
     * @param idCard
     * @return
     */
    private String calculateBirthdayFromIdCard(String idCard) {
        if (StringUtils.isBlank(idCard)) {
            throw new IllegalArgumentException("身份证号码不能为空");
        }

        if (!ID_CARD_PATTERN.matcher(idCard).matches()) {
            throw new IllegalArgumentException("身份证号码格式不正确");
        }

        String birthdayStr;
        if (idCard.length() == 15) {
            // 15位身份证：第7-12位是生日（yyMMdd）
            birthdayStr = "19" + idCard.substring(6, 12);
        } else {
            // 18位身份证：第7-14位是生日（yyyyMMdd）
            birthdayStr = idCard.substring(6, 14);
        }

        // 格式化为yyyy-MM-dd
        try {
            LocalDate birthday = LocalDate.parse(birthdayStr,
                    DateTimeFormatter.ofPattern("yyyyMMdd"));
            return birthday.format(DATE_FORMATTER);
        } catch (Exception e) {
            throw new IllegalArgumentException("身份证生日信息异常: " + birthdayStr);
        }
    }

    /**
     * 生日计算年龄
     * @param birthday
     * @return
     */
    private String calculateAgeFromBirthday(String birthday) {
        if (StringUtils.isBlank(birthday)) {
            throw new IllegalArgumentException("生日不能为空");
        }

        try {
            LocalDate birthDate = LocalDate.parse(birthday, DATE_FORMATTER);
            LocalDate currentDate = LocalDate.now();

            if (birthDate.isAfter(currentDate)) {
                throw new IllegalArgumentException("生日日期不能晚于当前日期");
            }

            Period period = Period.between(birthDate, currentDate);
            return String.valueOf(period.getYears());
        } catch (Exception e) {
            throw new IllegalArgumentException("生日格式不正确，应为yyyy-MM-dd格式");
        }
    }

    /**
     * 身高和体重计算BMI指数
     * @param requestValueList
     * @return
     */
    private String calculateBMI(List<String> requestValueList) {
        if (requestValueList == null || requestValueList.size() < 2) {
            throw new IllegalArgumentException("身高和体重参数不能为空");
        }

        try {
            // 身高（米）和体重（千克）
            double height = Double.parseDouble(requestValueList.get(0));
            double weight = Double.parseDouble(requestValueList.get(1));

            if (height <= 0 || weight <= 0) {
                throw new IllegalArgumentException("身高和体重必须为正数");
            }

            if (height > 3) {
                // 如果身高输入的是厘米，转换为米
                height = height / 100;
            }

            double bmi = weight / (height * height);

            // 保留两位小数
            return String.format("%.2f", bmi);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("身高和体重必须是有效数字");
        }
    }

    /**
     * 中文转拼音辅助方法
     * @param chinese
     * @return
     */
    private String convertChineseToPinyin(String chinese) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        StringBuilder pinyin = new StringBuilder();
        for (char c : chinese.toCharArray()) {
            if (Character.toString(c).matches("[\\u4E00-\\u9FA5]")) {
                try {
                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
                    if (pinyinArray != null && pinyinArray.length > 0) {
                        pinyin.append(pinyinArray[0]);
                    }
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    pinyin.append(c);
                }
            } else {
                pinyin.append(c);
            }
        }
        return pinyin.toString();
    }


}
