package com.jpsoft.shinestar.modules.base.service.impl;

import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jpsoft.shinestar.config.ParkingConfig;
import com.jpsoft.shinestar.modules.base.dao.ParkingRecordDAO;
import com.jpsoft.shinestar.modules.base.dto.ParkingDetailDTO;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.ParkingChannelService;
import com.jpsoft.shinestar.modules.base.service.ParkingCouponService;
import com.jpsoft.shinestar.modules.base.service.ParkingInfoService;
import com.jpsoft.shinestar.modules.base.service.ParkingRecordService;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.ParkApiUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 墨鱼_mo
 * @date 2020-4-14 9:38
 */
@Transactional
@Component(value = "parkingRecordService")
public class ParkingRecordServiceImpl implements ParkingRecordService {

    @Resource(name = "parkingRecordDAO")
    private ParkingRecordDAO parkingRecordDAO;

    @Autowired
    private ParkingInfoService parkingInfoService;

    @Autowired
    private ParkingCouponService parkingCouponService;

    @Autowired
    private ParkingChannelService parkingChannelService;

    @Autowired
    private ParkApiUtil parkApiUtil;

    @Autowired
    private ParkingConfig parkingConfig;

    @Override
    public void insert(ParkingRecord parkingRecord) {
        parkingRecordDAO.insert(parkingRecord);
    }

    @Override
    public ParkingRecord get(String id) {
        return parkingRecordDAO.findById(id);
    }

    @Override
    public void update(ParkingRecord parkingRecord) {
        parkingRecordDAO.update(parkingRecord);
    }

    @Override
    public ParkingRecord findBySerialNumber(String outTradeNo) {
        return parkingRecordDAO.findBySerialNumber(outTradeNo);
    }

    @Override
    public ParkingRecord findByOrderNumber(String orderNumber) {
        return parkingRecordDAO.findByOrderNumber(orderNumber);
    }

    @Override
    public Page<ParkingRecord> pageSearch(Map<String, Object> searchParams, int pageNumber, int pageSize, boolean count, List<Sort> sortList) {
        Page<ParkingRecord> page = PageHelper.startPage(pageNumber, pageSize, count).doSelectPage(() -> {
            parkingRecordDAO.search(searchParams, sortList);
        });

        return page;
    }

    @Override
    public ParkingDetailDTO findByCarNumber(String carNumber, ParkingMerchant parkingMerchant, Long parkId) throws Exception {

        if (parkId == null) {
            List<ParkingInfo> parkingInfoList = parkingInfoService.findByCompanyIdNotParentId(parkingMerchant.getCompanyId());
            if (parkingInfoList.size() == 0) {
                throw new Exception("物业停车场信息有误");
            }
            parkId = parkingInfoList.get(0).getParkId();
        }


        HashMap<String, Object> map = new HashMap<>();

        map.put("access_type", "scan_center_pay");
        map.put("carnum", carNumber);
        map.put("parkid", parkId);
        net.sf.json.JSONObject jsonObject = parkApiUtil.httpRequestSecond(parkingConfig.getInterfaceUrl() + "/zld/parkapi/query_price", "POST", map);

        Integer state = jsonObject.getInt("state");
        if (state != 1) {
            throw new Exception(jsonObject.getString("errmsg"));
        }

        ParkingRecord parkingRecord = findByOrderNumber(jsonObject.getString("parking_order_id"));

        if (parkingRecord == null) {
            ParkingRecord parkingRecord1 = new ParkingRecord();
            parkingRecord1.setId(UUID.randomUUID().toString());
            parkingRecord1.setParkId(jsonObject.getLong("park_id"));
            parkingRecord1.setCarNum(jsonObject.getString("car_num"));
            parkingRecord1.setInParkingTime(DateUtil.parse(jsonObject.getString("intime")));
            parkingRecord1.setPayStatus(10);
            parkingRecord1.setSerialNumber(jsonObject.getString("order_id"));
            parkingRecord1.setProductTheme("停车费");
            parkingRecord1.setCreateTime(new Date());
            parkingRecord1.setCarType(jsonObject.getString("cartype"));
            parkingRecord1.setOrderNumber(jsonObject.getString("parking_order_id"));
            insert(parkingRecord1);
            parkingRecord = parkingRecord1;
        } else {
            parkingRecord.setSerialNumber(jsonObject.getString("order_id"));
            update(parkingRecord);
        }

        ParkingCoupon parkingCoupon = parkingCouponService.findByParkingRecordIdAndStatus(parkingRecord.getId(), false);

        ParkingDetailDTO parkingDetailDTO = new ParkingDetailDTO();
        parkingDetailDTO.setId(parkingRecord.getId());
        parkingDetailDTO.setCarNumber(carNumber);
        if (parkingMerchant != null) {
            parkingDetailDTO.setMerchantName(parkingMerchant.getMerchantName());
            parkingDetailDTO.setDiscountMoney(parkingMerchant.getReduce());
        } else {
            if (parkingCoupon != null) {
                parkingDetailDTO.setDiscountMoney(parkingCoupon.getReduce());
            } else {
                parkingDetailDTO.setDiscountMoney(0);
            }
        }

        parkingDetailDTO.setParkingName(jsonObject.getString("park_name"));
        parkingDetailDTO.setInParkingTime(jsonObject.getString("intime"));
        parkingDetailDTO.setParkingTime(jsonObject.getString("park_times_string"));


        /*if (parkingCoupon != null){
            parkingDetailDTO.setDiscountMoney(parkingCoupon.getReduce());
        }else {
            parkingDetailDTO.setDiscountMoney(0);
        }*/

        parkingDetailDTO.setPrice(jsonObject.getInt("price"));
        parkingDetailDTO.setTotal(parkingDetailDTO.getDiscountMoney() + parkingDetailDTO.getPrice());
        return parkingDetailDTO;
    }

    @Override
    public void payNotify(String parkingRecordId) throws Exception {

        ParkingRecord parkingRecord = get(parkingRecordId);
        HashMap<String, Object> map = new HashMap<>();

        map.put("out_trade_no", parkingRecord.getSerialNumber());
        map.put("pay_trade_no", parkingRecord.getTransactionNumber());
        map.put("total_amount", parkingRecord.getPayAmount().toString());
        if (StringUtils.isNotBlank(parkingRecord.getOutChannel())) {
            map.put("out_channel_id", parkingRecord.getOutChannelId());
        }
        Integer payChannel = 1;
        if ("alipay".equals(parkingRecord.getPayType())) {
            payChannel = 2;
        }
        map.put("pay_channel", payChannel);
        map.put("pay_status", 1);

        net.sf.json.JSONObject jsonObject = parkApiUtil.httpRequestSecond(parkingConfig.getInterfaceUrl() + "/zld/parkapi/pay_notify", "POST", map);

        Integer state = jsonObject.getInt("state");
        if (state != 1) {
            throw new Exception(jsonObject.getString("errmsg"));
        }

        //查看使用有优惠券
        ParkingCoupon parkingCoupon = parkingCouponService.findByParkingRecordIdAndStatus(parkingRecordId, false);
        if (parkingCoupon != null) {
            parkingCoupon.setUseStatus(true);
            parkingCoupon.setUseTime(new Date());
            parkingCoupon.setUseQuote(parkingCoupon.getReduce());
            parkingCouponService.update(parkingCoupon);
        }

    }

    @Override
    public ParkingDetailDTO findByChannel(String channelId, ParkingMerchant parkingMerchant, Long parkId) throws Exception {
        if (parkId == null) {
            List<ParkingInfo> parkingInfoList = parkingInfoService.findByCompanyIdNotParentId(parkingMerchant.getCompanyId());
            if (parkingInfoList.size() == 0) {
                throw new Exception("物业停车场信息有误");
            }
            parkId = parkingInfoList.get(0).getParkId();
        }

        ParkingChannel parkingChannel = parkingChannelService.get(channelId);


        HashMap<String, Object> map = new HashMap<>();

        map.put("access_type", "scan_out_pay");
        map.put("channel_id", parkingChannel.getChannelId());
        map.put("parkid", parkId);
        net.sf.json.JSONObject jsonObject = parkApiUtil.httpRequestSecond(parkingConfig.getInterfaceUrl() + "/zld/parkapi/query_price", "POST", map);

        Integer state = jsonObject.getInt("state");
        if (state != 1) {
            throw new Exception(jsonObject.getString("errmsg"));
        }

        String carNumber = jsonObject.getString("car_num");

        ParkingRecord parkingRecord = findByOrderNumber(jsonObject.getString("parking_order_id"));

        if (parkingRecord == null) {
            ParkingRecord parkingRecord1 = new ParkingRecord();
            parkingRecord1.setId(UUID.randomUUID().toString());
            parkingRecord1.setParkId(jsonObject.getLong("park_id"));
            parkingRecord1.setCarNum(jsonObject.getString("car_num"));
            parkingRecord1.setInParkingTime(DateUtil.parse(jsonObject.getString("intime")));
            parkingRecord1.setPayStatus(10);
            parkingRecord1.setSerialNumber(jsonObject.getString("order_id"));
            parkingRecord1.setProductTheme("停车费");
            parkingRecord1.setCreateTime(new Date());
            parkingRecord1.setCarType(jsonObject.getString("cartype"));
            parkingRecord1.setOrderNumber(jsonObject.getString("parking_order_id"));
            parkingRecord1.setOutChannelId(channelId);
            insert(parkingRecord1);
            parkingRecord = parkingRecord1;
        } else {
            parkingRecord.setSerialNumber(jsonObject.getString("order_id"));
            parkingRecord.setOutChannelId(channelId);
            update(parkingRecord);
        }

        ParkingCoupon parkingCoupon = parkingCouponService.findByParkingRecordIdAndStatus(parkingRecord.getId(), false);

        ParkingDetailDTO parkingDetailDTO = new ParkingDetailDTO();
        parkingDetailDTO.setId(parkingRecord.getId());
        parkingDetailDTO.setCarNumber(carNumber);
        if (parkingMerchant != null) {
            parkingDetailDTO.setMerchantName(parkingMerchant.getMerchantName());
        }

        parkingDetailDTO.setParkingName(jsonObject.getString("park_name"));
        parkingDetailDTO.setInParkingTime(jsonObject.getString("intime"));
        parkingDetailDTO.setParkingTime(jsonObject.getString("park_times_string"));
        if (parkingCoupon != null) {
            parkingDetailDTO.setDiscountMoney(parkingCoupon.getReduce());
        } else {
            parkingDetailDTO.setDiscountMoney(0);
        }

        parkingDetailDTO.setPrice(jsonObject.getInt("price"));
        parkingDetailDTO.setTotal(parkingDetailDTO.getDiscountMoney() + parkingDetailDTO.getPrice());
        return parkingDetailDTO;
    }
}
