package com.boco.nbd.wios.wx.service;

import cn.hutool.core.lang.Assert;
import com.boco.nbd.wios.manage.entity.bo.OrderInstallItemVo;
import com.boco.nbd.wios.manage.entity.bo.OrderVo;
import com.boco.nbd.wios.manage.entity.bo.UserPayBill;
import com.boco.nbd.wios.manage.entity.bo.UserPayBillVo;
import com.boco.nbd.wios.manage.entity.cams.enums.OrderStatus;
import com.boco.nbd.wios.manage.mapper.def.OrderInstallItemDao;
import com.boco.nbd.wios.manage.service.impl.InvoiceService;
import com.boco.nbd.wios.manage.service.impl.OrderScoreService;
import com.boco.nbd.wios.manage.service.impl.OrderService;
import com.boco.nbd.wios.manage.service.impl.UserPayBillService;
import com.boco.nbd.wios.manage.util.NetUtil;
import com.boco.nbd.wios.manage.util.SpringContextUtil;
import com.boco.nbd.wios.wx.vo.WxBillVO;
import com.boco.nbd.wios.wx.vo.WxItemVO;
import com.boco.nbd.wios.wx.vo.WxOrderVO;
import com.ihidea.core.support.exception.ServiceException;
import com.ihidea.core.util.DateUtilsEx;
import com.ihidea.core.util.JSONUtilsEx;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author kevin
 * @create 2020/11/30 11:50
 */
@Service
public class WxOrderService {

    @Autowired
    private OrderInstallItemDao orderInstallItemDao;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderScoreService orderScoreService;

    @Autowired
    private UserPayBillService userPayBillService;

    @Autowired
    private InvoiceService invoiceService;

    public List<WxOrderVO> getList(String camsPhone) {
        if(StringUtils.isBlank(camsPhone)){
            return null;
        }
        List<OrderVo> orderList = orderService.selectByCamsPhone(camsPhone);
        if(CollectionUtils.isNotEmpty(orderList)) {
            List<WxOrderVO> returnList = new ArrayList<>();
            for (OrderVo ov : orderList) {
                returnList.add(convertOrder(ov));
            }
            return returnList;
        }
        return null;
    }

    public WxOrderVO convertOrder(OrderVo ov){
        WxOrderVO order = new WxOrderVO();
        order.setUserName(ov.getUserName());
        order.setOrderId(ov.getId());
        order.setAddress(ov.getAddress());
        order.setCreateDate(DateUtilsEx.formatToString(ov.getCreateTime(), "yyyy-MM-dd"));
        order.setStatus(transformStatus(ov.getStatus()));
        order.setHasOrderScore(ov.getHasOrderScore());
        return order;
    }

    public Integer transformStatus(int sourceStatus) {
        List<Integer> statusList = new ArrayList<>();
        statusList.add(OrderStatus.SURVEY_DISPATCHED.getType());
        statusList.add(OrderStatus.SURVEY_RESERVING.getType());
        statusList.add(OrderStatus.SURVEY_RESERVED.getType());

        statusList.add(OrderStatus.SURVEYING.getType());
        statusList.add(OrderStatus.SURVEY_FINISH.getType());
        statusList.add(OrderStatus.SURVEY_EXAMINING.getType());
        statusList.add(OrderStatus.SURVEY_EXAMINE_SUCCESS.getType());
        statusList.add(OrderStatus.SURVEY_RECTIFYING.getType());
        statusList.add(OrderStatus.SURVEY_RECTIFIED_EXAMINING.getType());

        statusList.add(OrderStatus.INSTALL_RESERVED.getType());
        statusList.add(OrderStatus.INSTALL_CHANGE_EXAMINING.getType());
        statusList.add(OrderStatus.INSTALL_CHANGE_EXAMINE_FAIL.getType());
        statusList.add(OrderStatus.INSTALL_CHANGE_EXAMINE_SUCCESS.getType());
        statusList.add(OrderStatus.INSTALLING.getType());
        // 进行中
        if (statusList.contains(sourceStatus)) {
            return 1;
        }

        // 已完成
        return 5;
    }

    /**
     * 获取工单详情
     * @param orderId
     * @return
     */
    public WxOrderVO getDetail(String orderId) {
        OrderVo order=orderService.selectOwnOrderById(orderId);
        if(order!=null){
            WxOrderVO vo=convertOrder(order);
            vo.setHasOrderScore(orderScoreService.isOrderScore(orderId));
            UserPayBill bill=userPayBillService.getByRefId(orderId);
            if(bill!=null){
                vo.setHasGenBill(true);
                vo.setBillAmount(bill.getAmount());
            }else{
                vo.setHasGenBill(false);
            }
            return vo;
        }
        return null;
    }

    public List<WxBillVO> getBillList(String camsPhone) {
        if(StringUtils.isBlank(camsPhone)){
            return null;
        }
        UserPayBill entity=new UserPayBill();
        entity.setUserPhone(camsPhone);
        List<UserPayBillVo> billList = userPayBillService.selectList(entity);
        if(CollectionUtils.isNotEmpty(billList)) {
            List<WxBillVO> returnList = new ArrayList<>();
            for (UserPayBillVo bill : billList) {
                returnList.add(convertBill(bill));
            }
            return returnList;
        }
        return null;
    }

    public WxBillVO convertBill(UserPayBill bill){
        WxBillVO vo = new WxBillVO();
        vo.setId(bill.getId());
        vo.setOrderId(bill.getRefId());
        vo.setBillAmount(bill.getAmount());
        vo.setCreateDate(DateUtilsEx.formatToString(bill.getCreateTime(), "yyyy-MM-dd"));
        vo.setStatus(bill.getStatus());
        return vo;
    }

    public WxBillVO getBillDetail(String orderId) {
        WxBillVO vo = getBill(orderId);
        if(vo!=null){
            OrderVo order = orderService.selectOwnOrderById(orderId);
            if(order!=null){
                vo.setAddress(order.getAddress());
            }

            List<WxItemVO> itemList=new ArrayList<>();
            List<OrderInstallItemVo> installItemList = orderInstallItemDao.selectByOrderIdAndType(orderId, 2);
            if(CollectionUtils.isNotEmpty(installItemList)){
                installItemList.forEach((item) -> {
                    WxItemVO wxItem=new WxItemVO();
                    wxItem.setId(item.getId());
                    wxItem.setName(item.getItemName());
                    wxItem.setFee(item.getFee());
                    itemList.add(wxItem);
                });
            }
            vo.setPredictItems(itemList);
            return vo;
        }

        return null;
    }

    public WxBillVO getBill(String orderId) {
        if(StringUtils.isBlank(orderId)){
            return null;
        }

        UserPayBill bill=userPayBillService.getByRefId(orderId);
        if(bill!=null){
            WxBillVO vo = convertBill(bill);

            if(StringUtils.isNotBlank(bill.getInfo())){
                Map<String, String> feeMap= JSONUtilsEx.deserialize(bill.getInfo(), Map.class);
                vo.setPredictTotalFee(StringUtils.isNotBlank(feeMap.get("predictTotalFee")) ? new BigDecimal(feeMap.get("predictTotalFee")) : BigDecimal.ZERO);
                vo.setExpandFee(StringUtils.isNotBlank(feeMap.get("expandFee")) ? new BigDecimal(feeMap.get("expandFee")) : BigDecimal.ZERO);
            }

            if(bill.getStatus() == 1){
                vo.setHasInvoice(invoiceService.hasInvoiceByBillId(bill.getId()));
            }else{
                vo.setHasInvoice(0);
            }

            return vo;
        }
        return null;
    }

    public Map<String, String> billPay(String orderId, String openId){
        if(StringUtils.isBlank(orderId)){
            return null;
        }

        Assert.notBlank(openId, "OPENID不能为空");
        UserPayBill bill=userPayBillService.getByRefId(orderId);
        if(bill!=null){
            Assert.isTrue(bill.getStatus() == 0, "账单已支付");
            return WeixinPayCore.getJSPayParam(bill.getId(), "建筑服务安装费("+orderId+")", bill.getAmount(), NetUtil.getIpAddr(SpringContextUtil.getRequest()), openId);
        }
        throw new ServiceException("安装订单不存在");
    }
}