package com.ywt.mg.services;

import com.ywt.mg.configs.ParameterConfigurer;
import com.ywt.mg.core.SqlHelper;
import com.ywt.mg.core.utils.Checker;
import com.ywt.mg.core.utils.FormatUtil;
import com.ywt.mg.core.utils.StringHelper;
import com.ywt.mg.core.utils.serializers.JsonSerializer;
import com.ywt.mg.domain.entities.DownloadRecord;
import com.ywt.mg.domain.entities.OfflineConsultation;
import com.ywt.mg.domain.models.ConstantDef;
import com.ywt.mg.domain.models.ExcelDataMap;
import com.ywt.mg.domain.models.enums.OfflineConsultationSourceEnum;
import com.ywt.mg.domain.models.enums.PaymentStatusEnum;
import com.ywt.mg.domain.models.enums.RefundStatusEnum;
import com.ywt.mg.domain.models.enums.SettlementStatusEnum;
import com.ywt.mg.domain.models.pojo.ExcelCollectPojo;
import com.ywt.mg.params.offline.DownloadOfflineListNewRequest;
import com.ywt.mg.web.common.FileSrv;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 会诊订单相关方法
 *
 * @author daiyihua
 */
@Service
public class OfflineNewService {

    private static Logger logger = LoggerFactory.getLogger(OfflineNewService.class);

    @Autowired
    private SqlHelper sqlHelper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private ParameterConfigurer parameterConfigurer;

    @Autowired
    private AuthService authService;

    @Autowired
    private HospitalCacheService hospitalCacheService;

    @Autowired
    private FileSrv fileSrv;

    @Autowired
    private DownloadRecordService downloadRecordService;

    @Autowired
    private RefundLogService refundLogService;


    public List<OfflineConsultation> queryDownloadOfflineList(DownloadOfflineListNewRequest request) {
        Map map = queryOfflineListCommon(request);
        String whereSql = (String) map.get(ConstantDef.KEY_WHERE_SQL);
        List paramList = (List) map.get(ConstantDef.KEY_PARAM_LIST);
        String sqlBuilder = "select * from offline_consultation where " + whereSql + "order by create_time desc";
        return jdbcTemplate.query(sqlBuilder, paramList.toArray(), new BeanPropertyRowMapper<>(OfflineConsultation.class));
    }


    public Map queryOfflineListCommon(DownloadOfflineListNewRequest request) {
        Map map = new HashMap();
        List<Object> paramList = new ArrayList<>();
        String whereSql = " ( 1=1 )";
        try {
            // 添加测试账号过滤
            String testAdminIds = parameterConfigurer.getTestAdminIds();
            String testDoctorIds = parameterConfigurer.getTestDoctorIds();
            String adminStr = "," + request.getCurrentAdminId() + ",";
            String testAdminIdsStr = "," + testAdminIds + ",";

            // 不是测试账号
            if (!(testAdminIdsStr.contains(adminStr))) {
                String[] testDoctorIdsArr = testDoctorIds.split(",");
                if (!Checker.isNone(testDoctorIdsArr)) {
                    String sqlSubFrom = "";
                    for (String doctorId : testDoctorIdsArr) {
                        sqlSubFrom += "doctor_id != " + doctorId + " and ";
                    }
                    sqlSubFrom = sqlSubFrom.substring(0, sqlSubFrom.lastIndexOf("and"));
                    whereSql += String.format(" and ((%s) or doctor_id is null)", sqlSubFrom);
                }
            }
            String orderNo = request.getOrderNo();
            if (!Checker.isNull(orderNo)) {
                whereSql += " and ( order_no like ?)";
                paramList.add("%" + orderNo.trim() + "%");
            }

            String patientName = request.getPatientName();
            if (!Checker.isNull(patientName)) {
                whereSql += " and ( real_name like ?)";
                paramList.add("%" + patientName.trim() + "%");
            }

            String patientMobile = request.getPatientMobile();
            if (!Checker.isNull(patientMobile)) {
                whereSql += " and ( mobile like ?)";
                paramList.add("%" + patientMobile + "%");
            }

            //status	1-已支付、2-已退费,3-已结算
            String status = request.getStatus();
            if (!Checker.isNull(status)) {
                int orderStatusInt = Integer.parseInt(status);
                if (orderStatusInt == 1) {
                    whereSql += " and ( payment_status = ? and (refund_status <> ? or refund_status is null) and (settlement_status <> ? or settlement_status is null) )";
                    paramList.add(PaymentStatusEnum.Success.getValue());
                    paramList.add(RefundStatusEnum.SUCCESS.getValue());
                    paramList.add(SettlementStatusEnum.SETTLED.getValue());
                } else if (orderStatusInt == 2) {
                    whereSql += " and ( refund_status = ?)";
                    paramList.add(RefundStatusEnum.SUCCESS.getValue());
                } else if (orderStatusInt == 3) {
                    whereSql += " and ( settlement_status = ? and (refund_status <> ? or refund_status is null))";
                    paramList.add(SettlementStatusEnum.SETTLED.getValue());
                    paramList.add(RefundStatusEnum.SUCCESS.getValue());
                }
            }
            //payment_status	tinyint	3	支付状态（0-待支付,1-支付处理中，2-支付成功，3-支付失败）
            String paymentStatus = request.getPaymentStatus();
            if (!Checker.isNull(paymentStatus)) {
                whereSql += " and ( payment_status = ?)";
                paramList.add(Integer.parseInt(paymentStatus));
            }

            String doctorName = request.getDoctorName();
            if (!Checker.isNull(doctorName)) {
                whereSql += " and ( doctor_name like ?  )";
                paramList.add("%" + doctorName.trim() + "%");
            }

            int searchHospitalId = request.getHospitalId();
            if (searchHospitalId > -1) {
                whereSql += " and ( hospital_id = ?  )";
                paramList.add(searchHospitalId);
            }

            String hisClinicCode = request.getHisClinicCode();
            if (!Checker.isNull(hisClinicCode)) {
                whereSql += " and ( his_clinic_code like ?  )";
                paramList.add("%" + hisClinicCode.trim() + "%");
            }

//            if (hospitalId != -1) {
//                whereSql += " and ( hospital_id = ?  )";
//                paramList.add(hospitalId);
//            }

            String formatDate = "yyyy-MM-dd";

            SimpleDateFormat format = new SimpleDateFormat(formatDate);
            String payTimeEnd = Checker.getStringValue(request.getPayTimeEnd());
            if (!Checker.isNull(payTimeEnd)) {
                whereSql += " and ( pay_time < ?)";
                Date date = format.parse(payTimeEnd);

                //把日期往后增加一天.整数往后推,负数往前移动
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, 1);
                //这个时间就是日期往后推一天的结果
                date = calendar.getTime();
                paramList.add(date);
            }
            String payTimeStart = Checker.getStringValue(request.getPayTimeStart());
            if (!Checker.isNull(payTimeStart)) {
                whereSql += " and ( pay_time >= ?)";
                Date date = format.parse(payTimeStart);
                paramList.add(date);
            }
            String refundTimeEnd = request.getRefundTimeEnd();
            if (!Checker.isNull(refundTimeEnd)) {
                whereSql += " and ( refund_time < ?)";
                Date date = format.parse(refundTimeEnd);

                //把日期往后增加一天.整数往后推,负数往前移动
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, 1);
                //这个时间就是日期往后推一天的结果
                date = calendar.getTime();
                paramList.add(date);
            }

            String createTimeEnd = Checker.getStringValue(request.getCreateEndTime());
            if (!Checker.isNull(createTimeEnd)) {
                whereSql += " and ( pay_time < ?)";
                Date date = format.parse(createTimeEnd);

                //把日期往后增加一天.整数往后推,负数往前移动
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                calendar.add(Calendar.DATE, 1);
                //这个时间就是日期往后推一天的结果
                date = calendar.getTime();
                paramList.add(date);
            }
            String createTimeStart = Checker.getStringValue(request.getCreateStartTime());
            if (!Checker.isNull(createTimeStart)) {
                whereSql += " and ( pay_time >= ?)";
                Date date = format.parse(createTimeStart);
                paramList.add(date);
            }


            String refundTimeStart = request.getRefundTimeStart();
            if (!Checker.isNull(refundTimeStart)) {
                whereSql += " and ( refund_time >= ?)";
                Date date = format.parse(refundTimeStart);
                paramList.add(date);
            }
            String source = request.getSource();
            if (!StringHelper.isNullOrWhiteSpace(source)) {
                whereSql += " and ( source = ?)";
                paramList.add(Integer.parseInt(source));
            }

            // 过滤掉删除和待支付的
            whereSql += " and ( deleted = 0  ) and (payment_status > ?) ";
            paramList.add(PaymentStatusEnum.Pending.getValue());

        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put(ConstantDef.KEY_WHERE_SQL, whereSql);
        map.put(ConstantDef.KEY_PARAM_LIST, paramList);
        return map;
    }

    /**
     * 得到线下就诊状态
     *
     * @param off {@link OfflineConsultation}
     * @return statusStr
     */
    public String getOfflineStatusStr(OfflineConsultation off) {
        if (!Checker.isNone(off)) {
            int refundStatus = Checker.getIntegerValue(off.getRefundStatus());
            if (refundStatus == RefundStatusEnum.SUCCESS.getValue()) {
                return "已退款";
            }
            int settlementStatus = Checker.getIntegerValue(off.getSettlementStatus());
            if (settlementStatus == SettlementStatusEnum.SETTLED.getValue()) {
                return SettlementStatusEnum.SETTLED.getDisplayName();
            }
            int payStatus = Checker.getIntegerValue(off.getPaymentStatus());
            if (payStatus == PaymentStatusEnum.Success.getValue()) {
                return "已支付";
            }

        }
        return "";
    }

    public void downloadOfflineListCommon(int downloadRecordId, String fileName, DownloadOfflineListNewRequest request) {
        try {
            // 单元格
            String col0 = "订单号";
            String col1 = "支付流水号";
            String col2 = "患者姓名";
            String col3 = "患者手机号";
            String col4 = "身份证号";
            String col5 = "医院流水号";
            String col6 = "医生姓名";
            String col7 = "科室";
            String col8 = "医院";
            String col9 = "诊查费";
            String col10 = "状态";
            String col11 = "支付状态";
            String col12 = "支付时间";
            String col13 = "退款时间";
            String col14 = "备注";
            String col15 = "来源";
            String[] columns = new String[]{col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10,
                    col11, col12, col13, col14, col15};
            // 按条件查找记录
            int hospitalId = -1;
            request.setHospitalId(hospitalId);
            List<OfflineConsultation> offlineList = queryDownloadOfflineList(request);
            int payTotal = 0, refundTotal = 0;
            ExcelDataMap map = new ExcelDataMap(columns);
            if (!Checker.isNone(offlineList)) {
                // 遍历
                for (OfflineConsultation v : offlineList) {
                    String orderNoStr = Checker.getStringValue(v.getOrderNo());
                    String paymentNoStr = Checker.getStringValue(v.getPaymentNo());
                    String patientNameNoStr = Checker.getStringValue(v.getRealName());
                    String patientMobileStr = Checker.getStringValue(v.getMobile());
                    String idNoStr = Checker.getStringValue(v.getIdNo());
                    String hisClinicCodeStr = Checker.getStringValue(v.getHisClinicCode() + "");
                    String doctorNameStr = Checker.getStringValue(v.getDoctorName());
                    String deptNameStr = Checker.getStringValue(v.getDeptName());
                    String hospitalNameStr = hospitalCacheService.getCacheHospitalNameByHospitalId(Checker.getIntegerValue(v.getHospitalId()));
                    String totalStr = FormatUtil.intShrink100ToStr(v.getTotal());
                    String orderStatusStr = getOfflineStatusStr(v);
                    String paymentStatusStr = PaymentStatusEnum.getPaymentStatus(Checker.getIntegerValue(v.getPaymentStatus())).getDisplayName();
                    String payTimeStr = FormatUtil.createTimeFormatList(v.getPayTime());
                    String refundTimeStr = FormatUtil.createTimeFormatList(v.getRefundTime());
                    String remarkStr = Checker.getStringValue(v.getRefundRemark());
                    String sourceStr = OfflineConsultationSourceEnum.getDisplayName(Checker.getIntegerValue(v.getSource()));
                    if (Checker.getIntegerValue(v.getPaymentStatus()) == PaymentStatusEnum.Success.getValue()) {
                        payTotal += Checker.getIntegerValue(v.getTotal());
                    }
                    if (Checker.getIntegerValue(v.getRefundStatus()) == RefundStatusEnum.SUCCESS.getValue()) {
                        refundTotal += Checker.getIntegerValue(v.getTotal());
                    }
                    map.getStringListSafely(col0).add(orderNoStr);
                    map.getStringListSafely(col1).add(paymentNoStr);
                    map.getStringListSafely(col2).add(patientNameNoStr);
                    map.getStringListSafely(col3).add(patientMobileStr);
                    map.getStringListSafely(col4).add(idNoStr);
                    map.getStringListSafely(col5).add(hisClinicCodeStr);
                    map.getStringListSafely(col6).add(doctorNameStr);
                    map.getStringListSafely(col7).add(deptNameStr);
                    map.getStringListSafely(col8).add(hospitalNameStr);
                    map.getStringListSafely(col9).add(totalStr);
                    map.getStringListSafely(col10).add(orderStatusStr);
                    map.getStringListSafely(col11).add(paymentStatusStr);
                    map.getStringListSafely(col12).add(payTimeStr);
                    map.getStringListSafely(col13).add(refundTimeStr);
                    map.getStringListSafely(col14).add(remarkStr);
                    map.getStringListSafely(col15).add(sourceStr);
                }
            }
            // 得到统计
            int size = offlineList.size();
            List<ExcelCollectPojo> itemList = getStatisticsData(size, payTotal, refundTotal);
            // 创建文件 并且上传到 OSS，最后保存到本地数据库
            downloadRecordService.createFileAndUploadOssAndSaveToDataBase(fileName, downloadRecordId, map, itemList);
        } catch (Exception e) {
            logger.error("/offline/downloadOfflineList(): {}", e.getMessage(), e);
            e.printStackTrace();
        }
    }

    /**
     * 获取统计数据
     *
     * @param size        隔行
     * @param payTotal    总金额
     * @param refundTotal 退款金额
     * @return {@link List<ExcelCollectPojo> }
     */
    private List<ExcelCollectPojo> getStatisticsData(int size, int payTotal, int refundTotal) {
        int startRows = size + 3;
        int startColumn = 3;

        List<ExcelCollectPojo> customExcelItemList = new ArrayList<>();
        customExcelItemList.add(new ExcelCollectPojo(startColumn + 1, startRows + 1, new String[]{"支付总额", FormatUtil.intShrink100ToStr(payTotal)}));
        customExcelItemList.add(new ExcelCollectPojo(startColumn + 1, startRows + 2, new String[]{"退款总额", FormatUtil.intShrink100ToStr(refundTotal)}));
        customExcelItemList.add(new ExcelCollectPojo(startColumn + 1, startRows + 3, new String[]{"实际支付金额", FormatUtil.intShrink100ToStr(payTotal - refundTotal)}));
        return customExcelItemList;
    }


}
