package com.ywt.mg.services;

import com.ywt.mg.core.PagedList;
import com.ywt.mg.core.SqlHelper;
import com.ywt.mg.core.utils.*;
import com.ywt.mg.domain.entities.OrderPayment;
import com.ywt.mg.domain.models.ConstantDef;
import com.ywt.mg.domain.models.ExcelDataMap;
import com.ywt.mg.domain.models.enums.PaymentStatusEnum;
import com.ywt.mg.domain.models.enums.TerminalEnum;
import com.ywt.mg.domain.models.pojo.ExcelCollectPojo;
import com.ywt.mg.params.deposit.DepositOrderInfo;
import com.ywt.mg.params.deposit.QueryDepositListRequest;
import com.ywt.mg.params.offline.DownloadOfflineListNewRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DepositService {

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

    @Autowired
    private SqlHelper sqlHelper;


    @Autowired
    private HospitalCacheService hospitalCacheService;

    @Autowired
    private OrderPaymentService orderPaymentService;

    @Autowired
    private DownloadRecordService downloadRecordService;


    private PagedList<DepositOrderInfo> queryDepositPageList(QueryDepositListRequest request) {
        List<Object> paramList = new ArrayList<>();
        StringBuilder sqlBuilder = new StringBuilder(" d.medical_card_id = m.id and d.deleted = 0 and d.payment_status = 2 ");

        String orderNo = request.getOrderNo();
        if (!Checker.isNull(orderNo)) {
            sqlBuilder.append(" and ( d.order_no = ? ) ");
            paramList.add(orderNo.trim());
        }
        String patientName = request.getPatientName();
        if (!Checker.isNull(patientName)) {
            sqlBuilder.append(" and ( m.patient_name = ? ) ");
            paramList.add(patientName.trim());
        }
        String patientMobile = request.getPatientMobile();
        if (!Checker.isNull(patientMobile)) {
            sqlBuilder.append(" and ( m.mobile = ? ) ");
            paramList.add(patientMobile.trim());
        }

        String terminal = request.getTerminal();
        if (!Checker.isNull(terminal)) {
            int terminalId = Integer.parseInt(terminal);
            sqlBuilder.append(" and ( d.terminal = ? )");
            paramList.add(terminalId);
        }
        String paymentTimeStart = request.getPaymentTimeStart();
        String paymentTimeEnd = request.getPaymentTimeEnd();
        try {
            if (!Checker.isNull(paymentTimeStart)) {
                sqlBuilder.append(" and d.payment_time >= ? ");
                Date date = FormatUtil.stringToDateDayTimeStart(paymentTimeStart);
                paramList.add(date);
            }
            if (!Checker.isNull(paymentTimeEnd)) {
                sqlBuilder.append(" and d.payment_time <= ? ");
                Date date = FormatUtil.stringToDateDayTimeEnd(paymentTimeEnd);
                paramList.add(date);
            }
        } catch (ParseException e) {
            logger.error("DepositService#queryDepositPageList(): paymentTimeStart:{} \t paymentTimeEnd:{} \t message:{}", paymentTimeStart, paymentTimeEnd, e.getMessage(), e);
        }
        int hospitalId = request.getHospitalId();
        if (hospitalId != -1) {
            sqlBuilder.append(" and m.hospital_id = ").append(hospitalId);
        }
        String transactionId = request.getTransactionId();
        try {
            // 处理交易流水号，考虑到性能，直接采用全匹配到方式
            if (!Checker.isNull(transactionId)) {
                OrderPayment orderPayment = orderPaymentService.getOrderPaymentByTransactionId(transactionId);
                if (!Checker.isNone(orderPayment)) {
                    sqlBuilder.append(" and d.order_id = ").append(orderPayment.getOrderId());
                } else {
                    sqlBuilder.append(" and d.order_id = -1 ");
                }
            }
        } catch (Exception e) {
            logger.error("DepositService#queryDepositPageList(transactionId={} ):\n {} ", transactionId, e.getMessage(), e);
        }

        // 对账时间
        String billStartTime = request.getBillStartTime();
        String billEndTime = request.getBillEndTime();
        try {
            if (!Checker.isNull(billEndTime)) {
                sqlBuilder.append(" and ( d.payment_time < ? )");
                Date date = FormatUtil.stringToDateDayTimeEnd(billEndTime);
                paramList.add(date);
            }
            if (!Checker.isNull(billStartTime)) {
                sqlBuilder.append(" and ( d.payment_time >= ? )");
                Date date = FormatUtil.stringToDateDayTimeStart(billStartTime);
                paramList.add(date);
            }
        } catch (Exception e) {
            logger.error("DepositService#queryDepositPageList(): billStartTime:{} \t billEndTime:{} \t message:{}", billStartTime, billEndTime, e.getMessage(), e);
        }

        String fields = "  d.id as depositId, d.user_id as userId, d.medical_card_id as medicalCardId, d.adm_no as admNo, d.order_id as orderId, " +
                "d.order_no as orderNo, d.amount as amount, d.payment_status as paymentStatus, d.payment_no as paymentNo, d.payment_time as paymentTime, " +
                "d.sync_his_status as syncHisStatus, d.create_time as createTime, m.hospital_id as hospitalId, m.patient_name as patientName, m.mobile as patientMobile," +
                " m.card_no as cardNo, d.terminal as terminal ";
        return sqlHelper.getMultipleTablePagedList(request.getPageIndex(), request.getPageSize(), fields, " deposit d, medical_card m ", sqlBuilder.toString(), " d.id desc", paramList.toArray(), DepositOrderInfo.class);
    }

    public void downloadDepositList(int downloadRecordId, String fileName, QueryDepositListRequest request) {
        try {

//            String[] title = new String[]{"订单号", "支付流水号", "交易流水号", "医院", "来源", "患者姓名", "手机号", "诊疗卡号", "支付金额", "支付方式", "同步状态", "支付时间"};
            int hosp = Checker.getIntegerValue(request.getHosp());
            int hospitalId = Checker.getIntegerValue(request.getHospitalId());
            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[] columns = new String[]{col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10,
                    col11};
            if (hosp > 0) {
                columns = new String[]{col0, col1, col2, col4, col5, col6, col7, col8, col9, col10,
                        col11};
            }
            PagedList<DepositOrderInfo> list = queryDepositPageList(request);
            ExcelDataMap map = new ExcelDataMap(columns);
            if (!Checker.isNone(list.getItems())) {
                // 得到支付的记录日志（需要从 order_payment 获取 transaction_id 字段）
                List<OrderPayment> orderPaymentList = orderPaymentService.getOrderPaymentListByDepositList(list.getItems());
//                for (DepositOrderInfo p : list.getItems()) {
//                    hospitalId = Checker.getIntegerValue(p.getHospitalId());
//                    String hospitalName = hospitalCacheService.getCacheHospitalNameByHospitalId(hospitalId);
//                    String transactionId = orderPaymentService.getTransactionIdByOrderId(orderPaymentList, Checker.getIntegerValue(p.getOrderId()));
//                    String amount = FormatUtil.intShrink100ToStr(p.getAmount());
//                    int terminalId = Checker.getIntegerValue(p.getTerminal());
//                    String paymentChannel = PaymentChannelUtil.paymentChannel(terminalId);
//                    String paymentStatus = getSyncHisStatusStr(Checker.getIntegerValue(p.getSyncHisStatus()));
//                    String paymentTime = FormatUtil.createTimeFormatList(p.getPaymentTime());
//                    String terminal = "";
//                    if (!Checker.isNone(p.getTerminal())) {
//                        terminal = TerminalEnum.valueOf(p.getTerminal()).getDisplayName();
//                    }
//                    ;
//
//                    if (request.getHospitalId() > 1) {
////                        bodyStr = new String[]{p.getOrderNo(), p.getPaymentNo(), transactionId, terminal, p.getPatientName(),
////                                p.getPatientMobile(), p.getCardNo(), amount, paymentChannel, paymentStatus, paymentTime};
//                        map.getStringListSafely(col0).add(p.getOrderNo());
//                        map.getStringListSafely(col1).add(p.getPaymentNo());
//                        map.getStringListSafely(col2).add(transactionId);
//                        map.getStringListSafely(col4).add(terminal);
//                        map.getStringListSafely(col5).add(p.getPatientName());
//                        map.getStringListSafely(col6).add(p.getPatientMobile());
//                        map.getStringListSafely(col7).add(p.getCardNo());
//                        map.getStringListSafely(col8).add(amount);
//                        map.getStringListSafely(col9).add(terminal);
//                        map.getStringListSafely(col10).add(paymentChannel);
//                        map.getStringListSafely(col11).add(paymentStatus);
//                    } else {
//                        // "订单号", "支付流水号", "交易流水号", "医院", "患者姓名", "手机号", "诊疗卡号", "支付金额", "支付方式", "同步状态", "支付时间"
//                        map.getStringListSafely(col0).add(p.getOrderNo());
//                        map.getStringListSafely(col1).add(p.getPaymentNo());
//                        map.getStringListSafely(col2).add(transactionId);
//                        map.getStringListSafely(col3).add(hospitalName);
//                        map.getStringListSafely(col4).add(terminal);
//                        map.getStringListSafely(col5).add(p.getPatientName());
//                        map.getStringListSafely(col6).add(p.getPatientMobile());
//                        map.getStringListSafely(col7).add(p.getCardNo());
//                        map.getStringListSafely(col8).add(amount);
//                        map.getStringListSafely(col9).add(terminal);
//                        map.getStringListSafely(col10).add(paymentChannel);
//                        map.getStringListSafely(col11).add(paymentStatus);
////                    String[] bodyStr = new String[]{p.getOrderNo(), p.getPaymentNo(), transactionId, hospitalName, terminal, p.getPatientName(),
////                            p.getPatientMobile(), p.getCardNo(), amount, paymentChannel, paymentStatus, paymentTime};
//                    }
//                }
                map = setExcelDataMap(orderPaymentList, list, map, hospitalId, hosp, request,
                        col0,
                        col1,
                        col2,
                        col3,
                        col4,
                        col5,
                        col6,
                        col7,
                        col8,
                        col9,
                        col10,
                        col11);
                int size = list.getTotalPage();
                if (size > 1) {
                    for (int i = 2; i <= size; i++) {
                        request.setPageIndex(i);
                        list = queryDepositPageList(request);
                        orderPaymentList = orderPaymentService.getOrderPaymentListByDepositList(list.getItems());
                        map = setExcelDataMap(orderPaymentList, list, map, hospitalId, hosp, request,
                                col0,
                                col1,
                                col2,
                                col3,
                                col4,
                                col5,
                                col6,
                                col7,
                                col8,
                                col9,
                                col10,
                                col11);

                    }
                }

            }
            List<ExcelCollectPojo> itemList = new ArrayList<>();
            downloadRecordService.createFileAndUploadOssAndSaveToDataBase(fileName, downloadRecordId, map, itemList);
        } catch (Exception e) {
            logger.error("/deposit/downloadDepositList(): {}", e.getMessage(), e);
            e.printStackTrace();
        }
    }

    /**
     * @param syncHisStatus 支付到his的状态，0-待同步，1-同步处理中，2-同步成功，3-同步失败
     * @return 返回同步状态
     */
    private String getSyncHisStatusStr(int syncHisStatus) {
        switch (syncHisStatus) {
            case 1:
                return "同步处理中";
            case 2:
                return "同步成功";
            case 3:
                return "同步失败";
            default:
                return "待同步";
        }
    }

    private ExcelDataMap setExcelDataMap(List<OrderPayment> orderPaymentList, PagedList<DepositOrderInfo> list, ExcelDataMap map, int hospitalId, int hosp, QueryDepositListRequest request,
                                         String col0,
                                         String col1,
                                         String col2,
                                         String col3,
                                         String col4,
                                         String col5,
                                         String col6,
                                         String col7,
                                         String col8,
                                         String col9,
                                         String col10,
                                         String col11) {
        for (DepositOrderInfo p : list.getItems()) {
            hospitalId = Checker.getIntegerValue(p.getHospitalId());
            String hospitalName = hospitalCacheService.getCacheHospitalNameByHospitalId(hospitalId);
            String transactionId = Checker.getStringValue(orderPaymentService.getTransactionIdByOrderId(orderPaymentList, Checker.getIntegerValue(p.getOrderId())));
            String amount = FormatUtil.intShrink100ToStr(p.getAmount());
            int terminalId = Checker.getIntegerValue(p.getTerminal());
            String paymentChannel = PaymentChannelUtil.paymentChannel(terminalId);
            String paymentStatus = getSyncHisStatusStr(Checker.getIntegerValue(p.getSyncHisStatus()));
            String paymentTime = FormatUtil.createTimeFormatList(p.getPaymentTime());
            String terminal = "";
            if (!Checker.isNone(p.getTerminal())) {
                terminal = TerminalEnum.valueOf(p.getTerminal()).getDisplayName();
            }
            ;

            if (hosp > 0) {
//                        bodyStr = new String[]{p.getOrderNo(), p.getPaymentNo(), transactionId, terminal, p.getPatientName(),
//                                p.getPatientMobile(), p.getCardNo(), amount, paymentChannel, paymentStatus, paymentTime};
                map.getStringListSafely(col0).add(p.getOrderNo());
                map.getStringListSafely(col1).add(p.getPaymentNo());
                map.getStringListSafely(col2).add(transactionId);
                map.getStringListSafely(col4).add(terminal);
                map.getStringListSafely(col5).add(p.getPatientName());
                map.getStringListSafely(col6).add(p.getPatientMobile());
                map.getStringListSafely(col7).add(p.getCardNo());
                map.getStringListSafely(col8).add(amount);
                map.getStringListSafely(col9).add(paymentChannel);
                map.getStringListSafely(col10).add(paymentStatus);
                map.getStringListSafely(col11).add(paymentTime);
            } else {
                // "订单号", "支付流水号", "交易流水号", "医院", "患者姓名", "手机号", "诊疗卡号", "支付金额", "支付方式", "同步状态", "支付时间"
                map.getStringListSafely(col0).add(p.getOrderNo());
                map.getStringListSafely(col1).add(p.getPaymentNo());
                map.getStringListSafely(col2).add(transactionId);
                map.getStringListSafely(col3).add(hospitalName);
                map.getStringListSafely(col4).add(terminal);
                map.getStringListSafely(col5).add(p.getPatientName());
                map.getStringListSafely(col6).add(p.getPatientMobile());
                map.getStringListSafely(col7).add(p.getCardNo());
                map.getStringListSafely(col8).add(amount);
                map.getStringListSafely(col9).add(paymentChannel);
                map.getStringListSafely(col10).add(paymentStatus);
                map.getStringListSafely(col11).add(paymentTime);
//                    String[] bodyStr = new String[]{p.getOrderNo(), p.getPaymentNo(), transactionId, hospitalName, terminal, p.getPatientName(),
//                            p.getPatientMobile(), p.getCardNo(), amount, paymentChannel, paymentStatus, paymentTime};
            }
        }
        return map;
    }

    public void downloadDepositBillList(int downloadRecordId, String fileName, QueryDepositListRequest request) {
        try {
//            String[] titleStr = {"交易类型*", "系统参考号*", "交易金额*", "交易日期*", "订单号", "类型"};
            String col0 = "交易类型*";
            String col1 = "系统参考号*";
            String col2 = "交易金额*";
            String col3 = "交易日期*";
            String col4 = "订单号";
            String col5 = "类型";
            String[] columns = new String[]{col0, col1, col2, col3, col4, col5};

            PagedList<DepositOrderInfo> depositPageList = queryDepositPageList(request);
            ExcelDataMap map = new ExcelDataMap(columns);
            if (!Checker.isNone(depositPageList)) {
                // 得到支付的记录日志（需要从 order_payment 获取 transaction_id 字段）
                List<OrderPayment> orderPaymentList = orderPaymentService.getOrderPaymentListByDepositOrderInfoList(depositPageList.getItems());
                int size = depositPageList.getTotalPage();
                map = setBillDeposit(request, depositPageList, orderPaymentList, map,
                        col0,
                        col1,
                        col2,
                        col3,
                        col4,
                        col5);
                if (size > 1) {
                    for (int i = 2; i <= size; i++) {
                        request.setPageIndex(i);
                        depositPageList = queryDepositPageList(request);
                        orderPaymentList = orderPaymentService.getOrderPaymentListByDepositList(depositPageList.getItems());
                        map = setBillDeposit(request, depositPageList, orderPaymentList, map,
                                col0,
                                col1,
                                col2,
                                col3,
                                col4,
                                col5);
                    }
                }

            }
            List<ExcelCollectPojo> itemList = new ArrayList<>();
            downloadRecordService.createFileAndUploadOssAndSaveToDataBase(fileName, downloadRecordId, map, itemList);
        } catch (Exception e) {
            logger.error("/deposit/downloadDepositBillList(): {}", e.getMessage(), e);
            e.printStackTrace();
        }
    }


        private ExcelDataMap setBillDeposit (QueryDepositListRequest
        request, PagedList < DepositOrderInfo > depositPageList, List < OrderPayment > orderPaymentList, ExcelDataMap
        map,
                String col0,
                String col1,
                String col2,
                String col3,
                String col4,
                String col5
    ){
            Date billStartTime = DateUtil.stringToDate(request.getBillStartTime() + ConstantDef.BILL_TIME_START_FORMAT);
            Date billEndTime = DateUtil.stringToDate(request.getBillEndTime() + ConstantDef.BILL_TIME_END_FORMAT);
            for (DepositOrderInfo p : depositPageList.getItems()) {
                if (!Checker.isNone(p) && Checker.getIntegerValue(p.getPaymentStatus()) == PaymentStatusEnum.Success.getValue()
                        && !Checker.isNone(p.getPaymentTime())) {
                    // "交易类型*", "系统参考号*", "交易金额*", "交易日期*", "订单号", "类型"
                    Date paymentTime = Checker.getDateValue(p.getPaymentTime());
                    if (!Checker.isNone(paymentTime) && paymentTime.after(billStartTime) && paymentTime.before(billEndTime)) {
                        String type = ConstantDef.BILL_PAYMENT_STR;
                        // 交易流水号
                        String transactionId = "";
                        OrderPayment orderPayment = orderPaymentList.stream().filter(o -> o.getOrderId().intValue() == p.getOrderId().intValue()).findFirst().orElse(null);
                        if (orderPayment != null && !Checker.isNone(orderPayment.getTransactionId())) {
                            transactionId = Checker.getStringValue(orderPayment.getTransactionId());
                        }
                        // 交易金额
                        String totalStr = FormatUtil.intShrink100ToStr(p.getAmount());
                        // 交易时间
                        String paymentTimeStr = FormatUtil.createTimeFormatDetail(p.getPaymentTime());
                        // 订单号
                        String orderNo = Checker.getStringValue(p.getOrderNo());
                        // 类型
                        String typeStr = "住院押金订单";
//                    String[] bodyStr = {type, transactionId, totalStr, paymentTimeStr, orderNo, typeStr};
                        map.getStringListSafely(col0).add(type);
                        map.getStringListSafely(col1).add(transactionId);
                        map.getStringListSafely(col2).add(totalStr);
                        map.getStringListSafely(col3).add(paymentTimeStr);
                        map.getStringListSafely(col4).add(orderNo);
                        map.getStringListSafely(col5).add(typeStr);

                    }
                }
            }
            return map;

        }

    }
