package com.yihu.jw.base.service.order;

import com.alibaba.fastjson.JSONObject;
import com.yihu.jw.entity.base.patient.BasePatientDO;
import com.yihu.jw.entity.care.common.WxPayHttpLogDO;
import com.yihu.jw.entity.order.BusinessOrderDO;
import com.yihu.jw.entity.order.BusinessOrderRefundDO;
import com.yihu.jw.order.BusinessOrderService;
import com.yihu.jw.order.dao.BusinessOrderDao;
import com.yihu.jw.order.dao.BusinessOrderRefundDao;
import com.yihu.jw.patient.dao.BasePatientDao;
import com.yihu.jw.pay.dao.WxPayHttpLogDao;
import com.yihu.jw.pay.service.CloudCarePayService;
import com.yihu.jw.restmodel.ResponseContant;
import com.yihu.jw.restmodel.web.PageEnvelop;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * Created by Bing on 2021/7/1.
 */
@Service
public class PayService {
    private Logger log = LoggerFactory.getLogger(PayService.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private BusinessOrderDao businessOrderDao;
    @Autowired
    private BusinessOrderRefundDao businessOrderRefundDao;
    @Autowired
    private BasePatientDao patientDao;
    @Autowired
    private CloudCarePayService payService;
    @Autowired
    private BusinessOrderService businessOrderService;
    @Value("${wechat.id}")
    public String wechatId;
    @Autowired
    private WxPayHttpLogDao wxPayHttpLogDao;

    /**
     * 订单列表
     * @param name
     * @param orderNo
     * @param status
     * @param payType
     * @param orderType
     * @param orderCategory
     * @param page
     * @param pageSize
     * @return
     */
    public PageEnvelop getOrderList(String name,String orderNo,String status,String payType,Integer orderType,Integer orderCategory,
                                    Integer page,Integer pageSize){
        page = page>0?page-1:0;
        String sql = " select *,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') create_time from base_business_order_pay where 1=1 ";
        String sqlCount = "select count(id) from base_business_order_pay where 1=1 ";
        String fliter="";
        if (StringUtils.isNotBlank(name)){
            fliter += " and patient_name like '%"+name+"%' ";
        }
        if (StringUtils.isNotBlank(orderNo)){
            fliter += " and order_no = '"+orderNo+"' ";
        }
        if (StringUtils.isNotBlank(status)){
            fliter += " and status = "+status;
        }
        if (StringUtils.isNotBlank(payType)){
            fliter += " and pay_type = "+payType;
        }
        if (orderType != null){
            fliter +=" and order_type = "+orderType;
        }
        if (orderCategory != null){
            fliter +=" and order_category = "+orderCategory;
        }

        Long count = jdbcTemplate.queryForObject(sqlCount+fliter,Long.class);
        fliter += " Order by create_time desc limit "+page*pageSize+","+pageSize;
        List<Map<String,Object>> list = jdbcTemplate.queryForList(sql+fliter);

        return PageEnvelop.getSuccessListWithPage("查询成功",list,page,pageSize,count);
    }

    /**
     * 售后订单列表
     * @param name
     * @param orderNo
     * @param status
     * @param payType
     * @param orderType
     * @param orderCategory
     * @param page
     * @param pageSize
     * @return
     */
    public PageEnvelop getRefundOrderList(String name,String orderNo,String status,String payType,Integer orderType,Integer orderCategory,
                                    Integer page,Integer pageSize){
        page = page>0?page-1:0;
        String sql = " select pay.patient,pay.patient_name,pay.order_no,pay.order_type,pay.order_category,pay.relation_code, " +
                " pay.relation_name,pay.description payDescription,pay.pay_type,pay.pay_price,pay.yk_order_id,DATE_FORMAT(re.create_time,'%Y-%m-%d %H:%i:%S') create_time, " +
                " re.enclosure,re.refund_desc description,re.refuse_desc,re.`status` from base_business_order_pay pay inner JOIN base_business_order_refund re on  " +
                " pay.order_no = re.order_no where pay.status>=3  ";
        String sqlCount = "select count(re.id) from base_business_order_pay pay inner JOIN " +
                " base_business_order_refund re on pay.order_no = re.order_no where pay.status>=3 ";
        String fliter="";
        if (StringUtils.isNotBlank(name)){
            fliter += " and pay.patient_name like '%"+name+"%' ";
        }
        if (StringUtils.isNotBlank(orderNo)){
            fliter += " and pay.order_no = '"+orderNo+"' ";
        }
        if (StringUtils.isNotBlank(status)){
            fliter += " and pay.status = "+status;
        }
        if (StringUtils.isNotBlank(payType)){
            fliter += " and pay.pay_type = "+payType;
        }
        if (orderType != null){
            fliter +=" and pay.order_type = "+orderType;
        }
        if (orderCategory != null){
            fliter +=" and pay.order_category = "+orderCategory;
        }

        Long count = jdbcTemplate.queryForObject(sqlCount+fliter,Long.class);
        fliter += " Order by create_time desc limit "+page*pageSize+","+pageSize;
        List<Map<String,Object>> list = jdbcTemplate.queryForList(sql+fliter);

        return PageEnvelop.getSuccessListWithPage("查询成功",list,page,pageSize,count);
    }

    /**
     * 拒绝退款
     * @param orderNo
     * @param refuseDesc
     * @return
     */
    public JSONObject refuseRefund(String orderNo,String refuseDesc){
        JSONObject result = new JSONObject();
        BusinessOrderDO businessOrderDO = businessOrderDao.selectByOrderNo(orderNo);
        if ( null== businessOrderDO){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单不存在");
            return result;
        }
        BasePatientDO patientDO = patientDao.findById(businessOrderDO.getPatient());
        if (patientDO==null){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "患者不存在");
            return result;
        }
        if ( 3 != businessOrderDO.getStatus()){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单未申请退款或已退款，无法操作");
            return result;
        }
        BusinessOrderRefundDO businessOrderRefundDO = businessOrderRefundDao.selectByOrderNo(orderNo);
        if (null == businessOrderRefundDO){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单不存在");
            return result;
        }
        businessOrderDO.setStatus(4);
        businessOrderRefundDO.setStatus(4);
        businessOrderRefundDO.setRefuseDesc(refuseDesc);
        businessOrderDao.save(businessOrderDO);
        businessOrderRefundDao.save(businessOrderRefundDO);
        result.put(ResponseContant.resultFlag, ResponseContant.success);
        result.put(ResponseContant.resultMsg, "success");
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public JSONObject agreeRefund(String orderNo) throws Exception {
        JSONObject result = new JSONObject();
        BusinessOrderDO businessOrderDO = businessOrderDao.selectByOrderNo(orderNo);
        if ( null== businessOrderDO){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单不存在");
            return result;
        }
        if ( 3 != businessOrderDO.getStatus()){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单未申请退款或已退款，无法操作");
            return result;
        }
        BasePatientDO patientDO = patientDao.findById(businessOrderDO.getPatient());
        if (patientDO==null){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "患者不存在");
            return result;
        }
        BusinessOrderRefundDO businessOrderRefundDO = businessOrderRefundDao.selectByOrderNo(orderNo);
        if (null == businessOrderRefundDO){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单不存在");
            return result;
        }
        if (businessOrderRefundDO.getStatus()!=1){
            result.put(ResponseContant.resultFlag, ResponseContant.fail);
            result.put(ResponseContant.resultMsg, "订单已处理");
            return result;
        }
        businessOrderDO.setStatus(4);
        businessOrderRefundDO.setStatus(3);
        businessOrderDao.save(businessOrderDO);
        businessOrderRefundDao.save(businessOrderRefundDO);
        //退款流程
        Integer orderPrice = new BigDecimal(businessOrderRefundDO.getOrderPrice()*100).intValue();
        Integer refundPrice1 = new BigDecimal(businessOrderRefundDO.getRefundPrice()*100).intValue();
        Map<String,Object> map = businessOrderService.refund(wechatId,businessOrderRefundDO.getOrderNo(),businessOrderRefundDO.getOutRefundNo(),orderPrice.toString(),refundPrice1.toString(),businessOrderRefundDO.getRefundDesc());
        log.info("map"+map);
        addHttpLog("1",businessOrderDO.getOrderNo(),null,map.toString());
        if (!map.get("return_code").toString().equalsIgnoreCase("SUCCESS")){
            //退款申请提交成功
            throw new Exception(map.get("return_msg").toString());
        }
        result.put(ResponseContant.resultFlag, ResponseContant.success);
        result.put(ResponseContant.resultMsg, "success");
        return result;
    }

    /**
     * 添加支付日志
     * @param type
     * @param orderNo
     * @param res
     * @param req
     */
    public void addHttpLog(String type,String orderNo,String res,String req){
        WxPayHttpLogDO logDO = new WxPayHttpLogDO();
        logDO.setType(type);
        logDO.setOrderNo(orderNo);
        logDO.setOrderReq(req);
        logDO.setOrderRes(res);
        wxPayHttpLogDao.save(logDO);
    }

}
