package thyyxxk.webserver.service.dictionary;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.Capacity;
import thyyxxk.webserver.constants.NationalMatchType;
import thyyxxk.webserver.constants.sidicts.SiFunction;
import thyyxxk.webserver.dao.his.dictionary.NationalMatchDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.ChargeItemMatch;
import thyyxxk.webserver.entity.nationalmatch.*;
import thyyxxk.webserver.service.medicalinsurance.ExecService;
import thyyxxk.webserver.utils.*;

import java.util.*;

/**
 * @description: 新医保国家目录匹配Service
 * @author: DingJie
 * @create: 2021-06-10 14:50:27
 **/
@Slf4j
@Service
public class NationalMatchService {
    private final ExecService exec;
    private final NationalMatchDao dao;

    @Autowired
    public NationalMatchService(ExecService exec, NationalMatchDao dao) {
        this.exec = exec;
        this.dao = dao;
    }

    public ResultVo<Map<String, Object>> selectLocalItems(QueryParam param) {
        log.info("是否导出：{}", param.getExport());
        Page<StandardLocalItem> iPage = param.getExport() ? new Page<>(1, -1) :
                new Page<>(param.getCurrentPage(), param.getPageSize());
        String code = param.getCode();
        code = StringUtil.isBlank(code) ? "%%" : code.trim().toUpperCase();
        String name = param.getName();
        name = StringUtil.isBlank(name) ? "%%" : "%" + name.trim() + "%";
        String statusColumn = param.getYbType() == 1 ? "national_status" : "injury_match_status";
        String codeColumn = param.getYbType() == 1 ? "national_code" : "ake001";
        String nameColumn = param.getYbType() == 1 ? "national_name" : "ake002";
        String upldFlagColumn = param.getYbType() == 1 ? "uploaded_flag" : "injury_upload_flag";
        String statement = "";
        if (param.getYbType() == 2) {
            statement = "startTime=(select max(d.aae030) from t_industrial_injury_catalogue d where d.aaz231=a.aaz231 )," +
                    "endTime=(select max(d.aae031) from t_industrial_injury_catalogue d where d.aaz231=a.aaz231), ";
        }
        String uploadStatement = "";
        if (null != param.getUploadFlag()) {
            uploadStatement = "and " + upldFlagColumn + "=" + param.getUploadFlag();
        }
        if (param.getType() == NationalMatchType.MEDICINE) {
            iPage = dao.selectLocalMedicines(iPage, code, name, param.getType(), param.getDelFlag(),
                    param.getStatus(), statusColumn, codeColumn, nameColumn, upldFlagColumn, statement, uploadStatement);
        } else if(param.getType() == NationalMatchType.HERBAL) {
            iPage = dao.selectLocalHerbals(iPage, code, name, param.getType(), param.getDelFlag(),
                    param.getStatus(), statusColumn, codeColumn, nameColumn, upldFlagColumn, statement, uploadStatement);
        } else if (param.getType() == NationalMatchType.SERVICE) {
            iPage = dao.selectLocalServices(iPage, code, name, param.getType(), param.getDelFlag(),
                    param.getStatus(), statusColumn, codeColumn, nameColumn, upldFlagColumn, statement, uploadStatement);
        } else {
            iPage = dao.selectLocalSupplies(iPage, code, name, param.getType(), param.getDelFlag(),
                    param.getStatus(), statusColumn, codeColumn, nameColumn, upldFlagColumn, statement, uploadStatement);
        }
        if (iPage.getRecords().isEmpty()) {
            return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有符合条件的数据。");
        }
        Map<String, Object> map = new HashMap<>(Capacity.TWO);
        map.put("total", iPage.getTotal());
        map.put("list", iPage.getRecords());
        return ResultVoUtil.success(map);
    }

    public ResultVo<String> asyncNewNameForServicesOrItems() {
        dao.asyncNewNameForServices();
        return ResultVoUtil.success("同步成功。");
    }

    public ResultVo<List> selectNationalItems(StandardLocalItem param) {
        int type = param.getType();
        String message = param.getYbType() == 1 ? "没有符合条件的国家目录。" : "没有符合条件的工伤目录。";
        if (type == NationalMatchType.MEDICINE) {
            List<SiCentralMedicine> list;
            if (param.getYbType() == 1) {
                String approve = param.getApprovalNumber();
                approve = StringUtil.isBlank(approve) ? "%%" : "%" + approve.replace("国药准字", "") + "%";
                list = dao.selectNationalMedicines(param.getFuzzyName(), approve);
                if (null == list || list.isEmpty()) {
                    list = dao.selectNationalMedicines(param.getFuzzyName(), "%%");
                    if (null == list || list.isEmpty()) {
                        return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
                    }
                }
            } else {
                list = dao.selectInjuryMedicines(param.getFuzzyName());
                if (null == list || list.isEmpty()) {
                    return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
                }
            }
            return ResultVoUtil.success(list);
        } else if (type == NationalMatchType.HERBAL){
            String name = param.getFuzzyName();
            if (name.contains("颗粒")) {
                String[] splits = param.getFuzzyName().split("（");
                splits = splits[0].split("\\(");
                name = splits[0].replaceAll("颗粒", "");
            }
            name = "%" + name.trim() + "%";
            List<SiCentralHerbal> list = param.getYbType() == 1 ? dao.selectNationalHerbals(name) : dao.selectInjuryHerbals(name);
            if (null == list || list.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
            }
            return ResultVoUtil.success(list);
        } else if (type == NationalMatchType.SERVICE) {
            String[] splits = param.getFuzzyName().split("外送");
            String name;
            if (splits.length == 1) {
                name = splits[0];
            } else {
                name = splits[0].substring(0, splits[0].length() - 1);
            }
            name = "%" + name + "%";
            List<SiCentralServices> list = param.getYbType() == 1 ? dao.selectNationalServices(name) : dao.selectInjuryServices(name);
            if (null == list || list.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
            }
            return ResultVoUtil.success(list);
        } else {
            List<SiCentralSuppliesMini> list;
            if (param.getYbType() == 1) {
                if (StringUtil.notBlank(param.getNationalCode())) {
                    list = dao.selectNationalSuppliesByCondition("code", param.getNationalCode().trim());
                } else if (StringUtil.notBlank(param.getApprovalNumber())) {
                    list = dao.selectNationalSuppliesByCondition("registration_record_no", param.getApprovalNumber().trim());
                } else {
                    String name = "%" + param.getFuzzyName() + "%";
                    list = dao.selectNationalSupplies(name);
                }
            } else {
                String name = "%" + param.getFuzzyName() + "%";
                list = dao.selectInjurySupplies(name);
            }

            if (null == list || list.isEmpty()) {
                return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, message);
            }
            return ResultVoUtil.success(list);
        }
    }

    public ResultVo<String> executeMatch(StandardLocalItem param) {
        String staffId = TokenUtil.getInstance().getTokenUserId();
        param.setOpStaff(staffId);
        param.setOpType(1);
        param.setId(SnowFlakeId.instance().nextId());
        if (param.getYbType() == 2) {
            if (param.getType() < NationalMatchType.SERVICE) {
                dao.matchInjuryCatalogue(param.getInjuryUniqueId(),param.getNationalCode(),param.getNationalName(),param.getCatalogueType(),
                        param.getFundType(),staffId,param.getCode(),"yp_zd_dict");
            } else {
                dao.matchInjuryCatalogue(param.getInjuryUniqueId(),param.getNationalCode(),param.getNationalName(),param.getCatalogueType(),
                        param.getFundType(),staffId,param.getCode(),"zd_charge_item");
            }
            dao.insertMatchLog(param);
            log.info("【操作员：{}】匹配工伤目录：{}", staffId, param);
            return ResultVoUtil.success("匹配成功。");
        }
        String selfpayProp = queryPsnPayProp(param.getNationalCode(), false);
        if (param.getType() < NationalMatchType.SERVICE) {
            dao.matchMedicineAndHerbal(param.getCode(), staffId, param.getNationalCode(), param.getNationalName(), selfpayProp);
        } else {
            ChargeItemMatch chargeItemMatch = dao.selectServiceAbout(param.getNationalCode());
            if (null == chargeItemMatch) {
                chargeItemMatch = new ChargeItemMatch();
                chargeItemMatch.setNationalCode(param.getNationalCode());
            }
            chargeItemMatch.setHisCode(param.getCode());
            chargeItemMatch.setStaffId(staffId);
            chargeItemMatch.setNationalName(param.getNationalName());
            chargeItemMatch.setSelfpayProp(selfpayProp);
            dao.matchServcieAndSupply(chargeItemMatch);
        }
        dao.insertMatchLog(param);
        log.info("【操作员：{}】匹配国家目录：{}", staffId, param);
        return ResultVoUtil.success("匹配成功。");
    }

    public ResultVo<String> cancelMatch(StandardLocalItem param) {
        String staffId = TokenUtil.getInstance().getTokenUserId();
        param.setOpStaff(staffId);
        param.setOpType(2);
        param.setId(SnowFlakeId.instance().nextId());
        if (param.getYbType() == 2) {
            if (param.getType() < NationalMatchType.SERVICE) {
                dao.cancelMatchInjuryCatalogue(staffId, param.getCode(), "yp_zd_dict");
            } else {
                dao.cancelMatchInjuryCatalogue(staffId, param.getCode(), "zd_charge_item");
            }
            dao.insertMatchLog(param);
            log.info("【操作员：{}】取消匹配工伤目录：{}", staffId, param);
            return ResultVoUtil.success("取消匹配成功。");
        }
        if (param.getType() < NationalMatchType.SERVICE) {
            dao.cancelMatchYp(param.getCode(), param.getSerial(), staffId);
        } else {
            dao.cancelMatchXm(param.getCode(), staffId);
        }
        dao.insertMatchLog(param);
        log.info("【操作员：{}】取消匹配国家目录：{}", staffId, param);
        return ResultVoUtil.success("取消匹配成功。");
    }

    public ResultVo<String> updateLocalItem(StandardLocalItem param) {
        String staffId = TokenUtil.getInstance().getTokenUserId();
        if (param.getType() < NationalMatchType.SERVICE) {
            dao.updateMedicine(param.getName(), staffId, param.getCode());
        } else if (param.getType() == NationalMatchType.SERVICE) {
            dao.updateServiceItem(param.getName(), param.getUnit(), param.getPrice(), staffId,
                    param.getStandardCode(), param.getDiscription(), param.getCode());
        } else {
            dao.updateSupply(param.getName(), staffId, param.getFactory(), param.getSpecification(), param.getCode());
        }
        log.info("【操作员：{}】修改项目：{}", staffId, param);
        return ResultVoUtil.success("修改成功。");
    }

    public String queryPsnPayProp(String hilistCode, boolean needUpdate) {
        JSONObject input = exec.makeTradeHeader(SiFunction.DOWNLOAD_MEDICAL_INSURANCE_PAY_FIRST_CATALOGUE);
        JSONObject data = new JSONObject();
        data.put("hilist_code", hilistCode);
        data.put("selfpay_prop_psn_type", "310");
        data.put("updt_time", "2018-01-01 00:00:00");
        data.put("page_num", 1);
        data.put("page_size", 100);
        input.getJSONObject("input").put("data", data);
        JSONObject result = exec.executeTrade(input, SiFunction.DOWNLOAD_MEDICAL_INSURANCE_PAY_FIRST_CATALOGUE);
        String psnPayProp = null;
        if (result.getIntValue("infcode") == 0) {
            JSONObject output = result.getJSONObject("output");
            JSONArray array = output.getJSONArray("data");
            String nowdate = DateUtil.formatDatetime(new Date());
            for (int i = 0; i < array.size(); i++) {
                JSONObject item = array.getJSONObject(i);
                String enddate = item.getString("enddate");
                if (DateUtil.shiJianDaXiao(nowdate, enddate, "<")) {
                    nowdate = enddate;
                    psnPayProp = item.getString("selfpay_prop");
                }
            }
        }
        if (needUpdate && null != psnPayProp) {
            dao.matchMedicineSelfPayProp(hilistCode, psnPayProp);
        }
        return psnPayProp;
    }

}
