package com.kingdee.eas.custom.hireapproval.service;

import com.alibaba.fastjson.JSONObject;
import com.kingdee.bos.BOSException;
import com.kingdee.bos.Context;
import com.kingdee.bos.bsf.service.app.IHRMsfService;
import com.kingdee.eas.basedata.assistant.CurrencyCollection;
import com.kingdee.eas.basedata.assistant.CurrencyFactory;
import com.kingdee.eas.basedata.assistant.CurrencyInfo;
import com.kingdee.eas.basedata.assistant.ICurrency;
import com.kingdee.eas.common.EASBizException;
import com.kingdee.eas.custom.hireapproval.*;
import com.kingdee.eas.custom.hireapproval.bizEnum.ExecuteStateEnum;
import com.kingdee.eas.custom.hireapproval.bizEnum.SalaryTypeEnum;
import com.kingdee.eas.utils.StringExUtils;
import com.kingdee.shr.cmpdesign.app.v2.base.AdjustSalaryItemCollection;
import com.kingdee.shr.cmpdesign.app.v2.base.AdjustSalaryItemFactory;
import com.kingdee.shr.cmpdesign.app.v2.base.IAdjustSalaryItem;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 写入OA录用定薪数据
 * @Date 2025/7/25 15:49
 * @Created by Heyuan
 */
public class SaveOAHireSalaryData implements IHRMsfService {
    private static Logger logger = Logger.getLogger(SaveOAHireSalaryData.class);

    @Override
    public Object process(Context ctx, Map<String, Object> params) throws EASBizException, BOSException {
        logger.error("开始执行 SaveOAHireSalaryData");
        CallServiceRecordInfo recordInfo = new CallServiceRecordInfo();
        recordInfo.setServiceName("saveOAHireSalaryData");
        recordInfo.setExecuteStatus(ExecuteStateEnum.SUCCESS);
        recordInfo.setRequestParams(new JSONObject(params).toJSONString());
        Map<String, Object> result = new HashMap<String, Object>(4);
        try {
            OAHireSalaryDataInfo info = execute(ctx, params);
            result.put("code", 200);
            result.put("message", "成功");
            result.put("number", info.getNumber());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.put("code", 500);
            result.put("message", "写入失败: " + e.getMessage());
            result.put("number", "");
            recordInfo.setExecuteStatus(ExecuteStateEnum.ERROR);
            recordInfo.setExecuteResult("写入失败: " + e.getMessage());
        } finally {
            recordInfo.setResponse(new JSONObject(result).toJSONString());
            ICallServiceRecord iCallServiceRecord = CallServiceRecordFactory.getLocalInstance(ctx);
            iCallServiceRecord.save(recordInfo);
            logger.error("结束执行 SaveOAHireSalaryData");
        }
        return result;
    }

    /**
     * 获取币别数据
     *
     * @param ctx
     * @return
     * @throws BOSException
     */
    private Map<String, CurrencyInfo> getCurrencyMap(Context ctx) throws BOSException {
        ICurrency iCurrency = CurrencyFactory.getLocalInstance(ctx);
        CurrencyCollection currencyCol = iCurrency.getCurrencyCollection();
        if (currencyCol.isEmpty()) {
            throw new BOSException("没有获取到币别数据");
        }
        Map<String, CurrencyInfo> currencyMap = new HashMap();
        for (int i = 0; i < currencyCol.size(); i++) {
            CurrencyInfo currencyInfo = currencyCol.get(i);
            String number = currencyInfo.getNumber();
            currencyMap.put(number, currencyInfo);
        }
        return currencyMap;
    }

    private OAHireSalaryDataInfo execute(
            Context ctx,
            Map<String, Object> params
    ) throws EASBizException, BOSException {
        String idNumber = (String) params.get("idNumber");
        String passport = (String) params.get("passport");
        String oANumber = (String) params.get("oANumber");
        String insFundCity = (String) params.get("insFundCity");
        String socialLevel = (String) params.get("socialLevel");
        String insFundBase = (String) params.get("insFundBase");
        String salaryCalcType = (String) params.get("salaryCalcType");//计薪方式
        String personName = (String) params.get("personName");//员工姓名
        String department = (String) params.get("department");//所属部门
        if (!StringExUtils.isAnyNotEmpty(idNumber, passport)) {
            throw new BOSException("身份证号码和其他证件号不能全为空!");
        }
        if (params.get("salaries") == null) {
            throw new BOSException("薪酬数据不能为空!");
        }
        if (!(params.get("salaries") instanceof List)) {
            throw new BOSException("薪酬数据 数据结构为List");
        }
        List<Map<String, Object>> salaries = (List) params.get("salaries");
        if (salaries.isEmpty()) {
            throw new BOSException("薪酬数据不能为空!");
        }
        if (StringUtils.isBlank(salaryCalcType)) {
            throw new BOSException("计薪方式编码不能为空!");
        }
        SalaryTypeEnum salaryTypeEnum = SalaryTypeEnum.getEnum(salaryCalcType);
        if (salaryTypeEnum == null) {
            throw new BOSException("计薪方式编码[" + salaryCalcType + "]不存在");
        }
        IOAHireSalaryData iOAHireSalaryData = OAHireSalaryDataFactory.getLocalInstance(ctx);
        IAdjustSalaryItem iAdjustSalaryItem = AdjustSalaryItemFactory.getLocalInstance(ctx);
        //币别数据
        Map<String, CurrencyInfo> currencyMap = getCurrencyMap(ctx);
        OAHireSalaryDataInfo info = iOAHireSalaryData.getOrCreateOAHireSalaryDataByIdNumber(idNumber, passport);
        ExecuteStateEnum executeStatus = info.getExecuteStatus();
        if (ExecuteStateEnum.SUCCESS.equals(executeStatus)) {
            throw new BOSException("数据已经存在且已经执行成功，不允许更新！");
        }
        OAHireSalaryDataEntryCollection entrys = info.getEntrys();
        entrys.clear();//清空分录
        info.setIdNumber(idNumber);//身份证号码
        info.setOaNumber(oANumber);//OA单据编号
        info.setPassport(passport);//其他证件号码
        info.setPersonName(personName);
        info.setDepartment(department);
        info.setExecuteStatus(ExecuteStateEnum.UNEXECUTE);//状态未执行
        info.setSalaryCalcType(salaryTypeEnum);
        if (StringUtils.isNotBlank(insFundBase)) {
            info.setInsFundBase(new BigDecimal(insFundBase));
        }
        info.setInsFundCity(insFundCity);
        info.setSocialLevel(socialLevel);
        info.setExecuteResult(null);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < salaries.size(); i++) {
            Map<String, Object> salary = salaries.get(i);
            OAHireSalaryDataEntryInfo entryInfo = new OAHireSalaryDataEntryInfo();
            String moneyStr = (String) salary.get("money");
            if (StringUtils.isBlank(moneyStr)) {
                throw new BOSException("薪酬数据 金额不能为空!");
            }
            BigDecimal money = new BigDecimal(moneyStr);
            if (money.compareTo(BigDecimal.ZERO) < 0) {
                throw new BOSException("薪酬数据 金额不能小于0");
            }
            entryInfo.setMoney(money);
            String effectDate = (String) salary.get("effectDate");
            if (StringUtils.isNotBlank(effectDate)) {
                try {
                    Date parse = sdf.parse(effectDate);
                    entryInfo.setOAEffectDate(parse);
                } catch (ParseException e) {
                    throw new BOSException("生效日期解析错误[" + effectDate + "],标准格式为yyyy-MM-dd");
                }
            }
            String currencyNumber = (String) salary.get("currencyNumber");
            if (StringUtils.isBlank(currencyNumber)) {
                currencyNumber = "CNY";
            }
            CurrencyInfo currencyInfo = currencyMap.get(currencyNumber);
            if (currencyInfo == null) {
                throw new BOSException("薪酬数据 币别数据[" + currencyNumber + "]不存在");
            }
            entryInfo.setCurrency(currencyInfo);
            //定薪项目
            String cmpItemNumber = (String) salary.get("cmpItemNumber");
            if (StringUtils.isBlank(cmpItemNumber)) {
                throw new BOSException("薪酬数据 调薪项目编码不能为空!");
            }
            AdjustSalaryItemCollection adjustSalaryItemCol =
                    iAdjustSalaryItem.getAdjustSalaryItemCollection("where number='" + cmpItemNumber + "'");
            if (adjustSalaryItemCol.isEmpty()) {
                throw new BOSException("薪酬数据 定薪项目[" + cmpItemNumber + "]不存在");
            }
            entryInfo.setCmpItem(adjustSalaryItemCol.get(0));
            entrys.add(entryInfo);
        }
        //保存
        iOAHireSalaryData.save(info);
        return info;
    }
}
