package thyyxxk.webserver.service.inpatient;

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.sidicts.MedType;
import thyyxxk.webserver.dao.his.inpatient.DictionaryDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.dictionary.CodeName;
import thyyxxk.webserver.entity.dictionary.SearchDataParam;
import thyyxxk.webserver.entity.medicalinsurance.inpatient.SpecialDiag;
import thyyxxk.webserver.utils.ListUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import java.util.List;
import java.util.Objects;

/**
 * @author dj
 */
@Slf4j
@Service
public class DictionaryService {
    private final DictionaryDao dao;

    @Autowired
    public DictionaryService(DictionaryDao dao) {
        this.dao = dao;
    }

    public ResultVo<String> increaseWeight(CodeName data) {
        if (data.getCode().equals("diag")) {
            dao.increaseWeight(data.getName());
        }
        return ResultVoUtil.success();
    }

    public ResultVo<List<CodeName>> executeSearch(SearchDataParam param) {
        switch (param.getTarget()) {
            case "physician":
                return ResultVoUtil.success(deepinPhysician(param.getMethod(), param.getContent(), param.isAccurateSearch()));
            case "diag":
                if (param.getMedType().equals("41") || param.getMedType().equals("42") || param.getMedType().equals("46")) {
                    return ResultVoUtil.success(deepinInjuryDiag(param.getMethod(), param.getContent()));
                }
                return ResultVoUtil.success(deepinDiag(param.getMethod(), param.getContent(), param.isAccurateSearch()));
            case "slwspcdiag":
                return ResultVoUtil.success(deepinSlwSpcDiag(param.getContent(), param.getPerstype()));
            case "injurydiag":
                return ResultVoUtil.success(deepinInjuryDiag(param.getMethod(), param.getContent()));
        }
        return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER);
    }

    private List<CodeName> deepinPhysician(String method, String content, boolean accurateSearch) {
        content = accurateSearch ? content + '%' : '%' + content + '%';
        if (method.equals("alpha")) {
            method = "py_code";
        }
        return dao.searchPhysician(method, content);
    }

    private List<CodeName> deepinDiag(String method, String content, boolean accurateSearch) {
        content = accurateSearch ? content + '%' : '%' + content + '%';
        if (method.equals("alpha")) {
            method = "py_code";
        } else if (method.equals("code")) {
            method = "diagnosis_code";
        } else {
            method = "diagnosis_name";
        }
        return dao.searchDiagnose(method, content);
    }

    private List<CodeName> deepinSlwSpcDiag(String content, Integer perstype) {
        content = "%" + content + "%";
        if (null == perstype) {
            perstype = 1;
        }
        String tableName = perstype == 1 ? "si_icd_employees_outpatient_chronic_idiopathic_disease"
                : "si_icd_residents_outpatient_chronic_idiopathic_disease";
        return dao.selectSlwSpcDiag(content, tableName);
    }

    private List<CodeName> deepinInjuryDiag(String method, String content) {
        content = "%" + content + "%";
        if (method.equals("alpha")) {
            method = "py_code";
        }
        return dao.selectInjurydiag(method, content);
    }

    public ResultVo<List<SpecialDiag>> getAllSpecialDiags(String medType) {
        String tableName = "si_hospitalization_single_disease";
        if (medType.equals("52")) {
            tableName = "si_icd_employees_maternity_hospitalization";
        }
        return ResultVoUtil.success(dao.selectAllSpecialDiags(tableName));
    }

    public ResultVo<List<CodeName>> getMaternDiagsForFrontSheet(SearchDataParam param) {
        String content = "%" + param.getContent() + "%";
        String method = "py_code";
        if (param.getMethod().equals("code")) {
            method = "new_code";
        } else if (param.getMethod().equals("name")) {
            method = "new_name";
        }
        return ResultVoUtil.success(dao.selectMatnDiagForFrontSheet(method, content));
    }

    public ResultVo<List<CodeName>> getSingleDssForFrontSheet(SearchDataParam param) {
        String content = "%" + param.getContent() + "%";
        String method = "py_code";
        if (param.getMethod().equals("code")) {
            method = "new_code";
        } else if (param.getMethod().equals("name")) {
            method = "new_name";
        }
        return ResultVoUtil.success(dao.selectSpcDssDiagForFrontSheet(method, content));
    }

    public ResultVo<List<CodeName>> getInjuryDssForFrontSheet(SearchDataParam param) {
        String content = "%" + param.getContent() + "%";
        String method = "py_code";
        if (!param.getMethod().equals("alpha")) {
            method = param.getMethod();
        }
        return ResultVoUtil.success(dao.selectInjuryDssDiagForFrontSheet(method, content));
    }

    public ResultVo<List<CodeName>> searchYbDiag(SearchDataParam param) {
        ResultVo<List<CodeName>> res;
        if (Objects.equals(MedType.SELF_PAY.getCode(), param.getMedType())) {
            String medType = dao.selectAccurateMedType(param.getPatNo(), param.getTimes());
            if (StringUtil.notBlank(medType)) {
                param.setMedType(medType);
            }
        }
        res = executeSearch(param);
        if (!Objects.equals(res.getCode(), ExceptionEnum.SUCCESS.getCode())) {
            return res;
        }
        if (ListUtil.isBlank(res.getData())) {
            return res;
        }
        List<CodeName> list = res.getData().subList((param.getPage() - 1) * 10,
                Math.min(res.getData().size(), param.getPage() * 10));
        return ResultVoUtil.success(list);
    }
}
