package com.engine.salary.wrapper;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.entity.config.SalaryConfig;
import com.engine.salary.entity.salaryarchive.config.ArchiveFieldConfig;
import com.engine.salary.entity.salaryitem.config.SalaryItemAllConfig;
import com.engine.salary.entity.taxagent.config.TaxAgentConfig;
import com.engine.salary.entity.taxagent.po.TaxAgentBasePO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.sys.config.SysConfig;
import com.engine.salary.sys.entity.param.*;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.sys.entity.vo.AppSettingVO;
import com.engine.salary.sys.entity.vo.OrderRuleVO;
import com.engine.salary.sys.entity.vo.UploadConfigResponse;
import com.engine.salary.sys.enums.TaxDeclarationFunctionEnum;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.RuntimeTypeEnum;
import com.engine.salary.util.valid.ValidUtil;
import com.engine.salary.util.xml.XStreamUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.hrm.User;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 累计专项附加扣除
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
@Slf4j
public class SalarySystemConfigWrapper extends Service {

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }

    private SalaryItemService getSalaryItemService(User user) {
        return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
    }

    private SalaryArchiveItemService getSalaryArchiveItemService(User user) {
        return ServiceUtil.getService(SalaryArchiveItemServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private SalaryFormulaService getSalaryFormulaService(User user) {
        return ServiceUtil.getService(SalaryFormulaServiceImpl.class, user);
    }

    private TaxAgentBaseService getTaxAgentBaseService(User user) {
        return ServiceUtil.getService(TaxAgentBaseServiceImpl.class, user);
    }

    private SalaryCacheService getSalaryCacheService(User user) {
        return ServiceUtil.getService(SalaryCacheServiceImpl.class, user);
    }

    public Map<String, Object> info() {
        BaseBean baseBean = new BaseBean();
        String log = baseBean.getPropValue("hrmSalary", "log");
        String version = baseBean.getPropValue("hrmSalary", "version");
        String openFormulaForcedEditing = baseBean.getPropValue("hrmSalary", "openFormulaForcedEditing");
        String showEncryptOperationButton = baseBean.getPropValue("hrmSalary", "showEncryptOperationButton");

        Map<String, Object> o = new HashMap<>();
        o.put("log", log);
        o.put("version", version);
        o.put("openFormulaForcedEditing", openFormulaForcedEditing);
        o.put("showEncryptOperationButton", showEncryptOperationButton);


        List<SalarySysConfPO> confPOS = getSalarySysConfService(user).listSome(SalarySysConfPO.builder().build());
        Map<String, String> map = SalaryEntityUtil.convert2Map(confPOS, SalarySysConfPO::getConfKey, SalarySysConfPO::getConfValue);
        o.putAll(map);
        return o;
    }

    /**
     * 操作是否需要申报功能
     *
     * @param flag 开启 0/关闭 1/重新开启 2
     * @return 执行结果
     */
    public boolean operateTaxDeclarationFunction(TaxDeclarationFunctionEnum flag) {
        return getSalarySysConfService(user).operateTaxDeclarationFunction(flag);
    }

    /**
     * 获取单一配置
     *
     * @param code
     * @return
     */
    public String getOneByCode(String code) {
        SalarySysConfPO one = getSalarySysConfService(user).getOneByCode(code);
        if (one != null) {
            return one.getConfValue();
        } else {
            return StringUtils.EMPTY;
        }
    }


    public PageInfo<SalarySysConfPO> list(SalarySysConfQueryParam param) {
        List<SalarySysConfPO> salarySysConfPOS = getSalarySysConfService(user).listSome(SalarySysConfPO.builder().build());

        List<SalarySysConfPO> list = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), salarySysConfPOS);
        PageInfo<SalarySysConfPO> page = new PageInfo<>(list, SalarySysConfPO.class);

        page.setTotal(salarySysConfPOS.size());
        page.setPageNum(param.getCurrent());
        page.setPageSize(param.getPageSize());
        return page;
    }


    public void save(SalarySysConfPO salarySysConfPO) {
        ValidUtil.doValidator(salarySysConfPO);
        getSalarySysConfService(user).save(salarySysConfPO);
    }

    public void update(SalarySysConfPO salarySysConfPO) {
        ValidUtil.doValidator(salarySysConfPO, RuntimeTypeEnum.UPDATE);
        getSalarySysConfService(user).update(salarySysConfPO);
    }

    public SalarySysConfPO detail(Long id) {
        return getSalarySysConfService(user).getById(id);
    }

    public void updateByCode(SalarySysConfPO salarySysConfPO) {
        getSalarySysConfService(user).updateByCode(salarySysConfPO);
    }

    public void updateOrderRule(OrderRuleParam param) {
        getSalarySysConfService(user).updateOrderRule(param);
    }

    public OrderRuleVO orderRule() {
        return getSalarySysConfService(user).orderRule();
    }

    public void saveMatchEmployeeModeRule(MatchEmployeeModeSaveParam param) {
        ValidUtil.doValidator(param);
        getSalarySysConfService(user).saveMatchEmployeeModeRule(param.getRule());
    }

    public void saveAppSetting(AppSettingSaveParam param) {
        ValidUtil.doValidator(param);
        getSalarySysConfService(user).saveAppSetting(param);
    }

    public AppSettingVO appSetting() {

        return getSalarySysConfService(user).appSetting();

    }

    public Map<String, Object> saveEncryptSetting(AppSettingSaveParam param) {
        return getSalarySysConfService(user).saveEncryptSetting(param);
    }

    public Map<String, Object> getEncryptProgress(String progressId) {
        return getSalarySysConfService(user).getEncryptProgress(progressId);
    }

    public void saveSalaryAcctEmployeeRule(String rule) {
        getSalarySysConfService(user).saveSalaryAcctEmployeeRule(rule);
    }

    public void saveWithDrawTaxDeclaration(SalarySysConfPO param) {
        getSalarySysConfService(user).saveWithDrawTaxDeclaration(param);
    }

    public void saveArchiveDelete(String setting) {
        getSalarySysConfService(user).saveArchiveDelete(setting);
    }

    public void operate(SalarySysConfPO salarySysConfPO) {
        getSalarySysConfService(user).operate(salarySysConfPO);
    }

    public void saveSalarySendFeedback(SalarySysConfPO param) {
        getSalarySysConfService(user).saveSalarySendFeedback(param);
    }


    public SalaryConfig downloadConfig() {
        Boolean chief = getTaxAgentService(user).isChief((long) user.getUID());
        if (!chief) {
            throw new SalaryRunTimeException("您不是薪酬总管理员，无法迁入出配置！");
        }


        SalaryConfig salaryConfig = new SalaryConfig();
        SysConfig sysConfig = getSalarySysConfService(user).getConfig();
        salaryConfig.setSysConfig(sysConfig);

//        FormluaConfig formluaConfig = getSalaryFormulaService(user).getConfig();
//        salaryConfig.setFormluaConfig(formluaConfig);

        SalaryItemAllConfig salaryItemConfig = getSalaryItemService(user).getConfig();
        salaryConfig.setSalaryItemConfig(salaryItemConfig);

        ArchiveFieldConfig archiveFieldConfig = getSalaryArchiveItemService(user).getConfig();
        salaryConfig.setArchiveFieldConfig(archiveFieldConfig);

        TaxAgentBasePO taxAgentBaseConfig = getTaxAgentBaseService(user).getConfig();
        salaryConfig.setTaxAgentBaseConfig(taxAgentBaseConfig);

        List<TaxAgentConfig> taxAgentConfigs = getTaxAgentService(user).getConfig();
        salaryConfig.setTaxAgentConfigs(taxAgentConfigs);

        return salaryConfig;
    }

    public UploadConfigResponse uploadConfig(UploadConfigParam param) {
        Boolean chief = getTaxAgentService(user).isChief((long) user.getUID());
        if (!chief) {
            throw new SalaryRunTimeException("您不是薪酬总管理员，无法迁入配置！");
        }

        UploadConfigResponse lastResponse = getSalaryCacheService(user).get(SalaryCacheKey.UPLOAD_SALARY_CONFIG);
        if (lastResponse != null && !lastResponse.isFinish()) {
            throw new SalaryRunTimeException("迁入任务进行中，请等待上次任务完成！");
        }

//        LocalRunnable localRunnable = new LocalRunnable() {
//            @Override
//            public void execute() {
                UploadConfigResponse response = UploadConfigResponse.builder().finish(false).results(new ArrayList<>()).build();
                getSalaryCacheService(user).set(SalaryCacheKey.UPLOAD_SALARY_CONFIG, response);

                InputStream fileInputStream = null;
                try {
                    fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
                    Reader reader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
                    BufferedReader bufferedReader = new BufferedReader(reader);
                    String line;
                    StringBuilder xml = new StringBuilder();
                    while ((line = bufferedReader.readLine()) != null) {
                        xml.append(line);
                    }

                    SalaryConfig config = XStreamUtil.unmarshal(SalaryConfig.class, xml.toString());

                    UploadConfigResponse.Result sysConfigResult = getSalarySysConfService(user).parseConfig(config.getSysConfig());
                    response.getResults().add(sysConfigResult);

                    UploadConfigResponse.Result salaryItemResult = getSalaryItemService(user).parseConfig(config.getSalaryItemConfig());
                    response.getResults().add(salaryItemResult);

                    UploadConfigResponse.Result archiveFieldResult = getSalaryArchiveItemService(user).parseConfig(config.getArchiveFieldConfig());
                    response.getResults().add(archiveFieldResult);

                    UploadConfigResponse.Result taxAgentBaseResult = getTaxAgentBaseService(user).parseConfig(config.getTaxAgentBaseConfig());
                    response.getResults().add(taxAgentBaseResult);

                    List<UploadConfigResponse.Result> results = getTaxAgentService(user).parseConfig(config.getTaxAgentConfigs());
                    response.getResults().addAll(results);
                } catch (Exception e) {
                    log.error("加载失败", e);
                } finally {
                    response.setFinish(true);
                    IOUtils.closeQuietly(fileInputStream);
                }
                getSalaryCacheService(user).set(SalaryCacheKey.UPLOAD_SALARY_CONFIG, response);
//            }
//        };
//        ThreadPoolUtil.fixedPoolExecute(ModulePoolEnum.HRM, "UPLOAD_SALARY_CONFIG", localRunnable);

        return response;
    }
}
