/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.guosen.billRecord.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.aspectj.weaver.ast.Or;
import org.springblade.common.constant.SystemConstant;
import org.springblade.common.utils.SerializableUtil;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.guosen.activity.entity.Activity;
import org.springblade.modules.guosen.activity.service.IActivityService;
import org.springblade.modules.guosen.agenter.entity.Agenter;
import org.springblade.modules.guosen.agenter.service.IAgenterService;
import org.springblade.modules.guosen.agentertype.entity.AgenterType;
import org.springblade.modules.guosen.agentertype.service.IAgenterTypeService;
import org.springblade.modules.guosen.billRecord.dto.BillRecordDTO;
import org.springblade.modules.guosen.billRecord.entity.BillRecord;
import org.springblade.modules.guosen.billRecord.mapper.BillRecordMapper;
import org.springblade.modules.guosen.billRecord.service.IBillRecordService;
import org.springblade.modules.guosen.billRecord.vo.BillRecordVO;
import org.springblade.modules.guosen.billRecord.vo.OrderWebVO;
import org.springblade.modules.guosen.bussiness.entity.Bussiness;
import org.springblade.modules.guosen.bussinessInfo.entity.BussinessInfo;
import org.springblade.modules.guosen.bussinessInfo.service.IBussinessInfoService;
import org.springblade.modules.guosen.bussinessPurchaseRecord.service.IBussinessPurchaseRecordService;
import org.springblade.modules.guosen.loginUser.entity.LoginUser;
import org.springblade.modules.guosen.loginUser.service.ILoginUserService;
import org.springblade.modules.guosen.ordercommission.entity.OrderCommission;
import org.springblade.modules.guosen.ordercommission.service.IOrderCommissionService;
import org.springblade.modules.guosen.present.entity.Present;
import org.springblade.modules.guosen.present.service.IPresentService;
import org.springblade.modules.guosen.production.entity.Production;
import org.springblade.modules.guosen.production.service.IProductionService;
import org.springblade.modules.guosen.userPointsGoods.entity.UserPointsGoods;
import org.springblade.modules.guosen.userPointsGoods.service.IUserPointsGoodsService;
import org.springblade.modules.guosen.useragenter.entity.UserAgenter;
import org.springblade.modules.guosen.useragenter.service.IUserAgenterService;
import org.springblade.yeePay.entity.RechargeDto;
import org.springblade.yeePay.service.YeePayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

/**
 * 服务实现类
 *
 * @author BladeX
 * @since 2021-06-18
 */
@Service
public class BillRecordServiceImpl extends BaseServiceImpl<BillRecordMapper, BillRecord> implements IBillRecordService {

	@Resource
	private ILoginUserService loginUserService;

	@Resource
	private IActivityService activityService;

	@Resource
	private IPresentService presentService;

	@Resource
	private IProductionService productionService;

	@Resource
	private IUserPointsGoodsService userPointsGoodsService;
	@Autowired
	private IBussinessPurchaseRecordService bussinessPurchaseRecordService;
	@Autowired
	private YeePayService yeePayService;
	@Autowired
	private IBussinessInfoService bussinessInfoService;



	@Override
	public IPage<BillRecordVO> selectBillRecordPage(IPage<BillRecordVO> page, BillRecordVO billRecord) {
		return page.setRecords(baseMapper.selectBillRecordPage(page, billRecord));
	}


	@Override
	public boolean saveOrUpdate(BillRecord billRecord) {
		LoginUser loginUser = loginUserService.getById(billRecord.getUserId());
		Activity activity = activityService.getById(billRecord.getActivityId());
		Assert.notNull(activity,"活动不存在");
		Assert.notNull(loginUser,"支付用户不存在");
		boolean flag = billRecord.getId() == null ? this.save(billRecord) : this.updateById(billRecord);
		if(billRecord.getPayStatus() != SystemConstant.BillRecordPayStatus.PAYED.getValue()){//没有付款成功的都不参与费用
			return flag;
		}
		boolean recommendCommissionFlag = false;//推广分红结果
		boolean cityCommissionFlag= false;//城市分红结果
		//支付时若支付人有代理商需要分佣
		if (flag) {





		}



		return flag;
	}

	@Override
	public OrderWebVO getOrderDetail(String bankOrderId) {
		//查询支付成功的记录
		BillRecord billRecord = this.getOne(Condition.getQueryWrapper(new BillRecord()).lambda()
			.eq(BillRecord::getBankOrderId, bankOrderId)
			.eq(BillRecord::getPayStatus, 1));
		if (billRecord == null) {
			return null;
		}
		OrderWebVO orderWebVO = new OrderWebVO();

		orderWebVO.setPayPath(billRecord.getPayPath());
		orderWebVO.setActivityId(billRecord.getActivityId());

		Integer type = billRecord.getType();
		Long relationId = billRecord.getRelationId();

		if (type==1 || type ==2) {
			//打赏,获取礼物id
			Long presentId = billRecord.getPresentId();
			Present present = presentService.getById(presentId);
			Assert.notNull(present, "打赏的礼物为空");
			orderWebVO.setPresentName(present.getName());//礼物名称
			Integer presentCount = billRecord.getPresentCount();//礼物数量
			orderWebVO.setPresentCount(presentCount);
			orderWebVO.setType(0);

			//热力值
			BigDecimal of = BigDecimal.valueOf(presentCount);
			BigDecimal totalHotValue = present.getHotValue().multiply(of);
			BigDecimal totalPointsValue = present.getPointsValue().multiply(of);
			orderWebVO.setHotValue(totalHotValue);
			orderWebVO.setPointsValue(totalPointsValue);

			if (type == 1) {
				Production production = productionService.getById(relationId);
				Assert.notNull(present, "打赏的作品为空");
				Long userId = production.getUserId();
				LoginUser loginUser = loginUserService.getById(userId);
				String nickName = loginUser.getNickName();//打赏者
				orderWebVO.setReceiverName(nickName);
			}else{
				LoginUser loginUser = loginUserService.getById(relationId);
				String nickName = loginUser.getNickName();//打赏者
				orderWebVO.setReceiverName(nickName);
			}
		}

		if (type == 3) {
			//积分商城购买
			orderWebVO.setType(1);
			UserPointsGoods pointsGoods = userPointsGoodsService.getById(relationId);
			Assert.notNull(pointsGoods, "兑换的商品为空");
			orderWebVO.setPointsGoodsName(pointsGoods.getName());
		}
		return orderWebVO;
	}

	@Override
	public BigDecimal billStat(BillRecord billRecord) {
		Date createTime = billRecord.getCreateTime();
		String createTimeFormat = null;
		if(createTime != null){
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			createTimeFormat = sdf.format(createTime);
			billRecord.setCreateTime(null);
		}
		LambdaQueryWrapper<BillRecord> lambda = Condition.getQueryWrapper(billRecord).lambda();
		lambda.like(createTime != null, BillRecord::getCreateTime, createTimeFormat);
		lambda.eq(BillRecord::getPayStatus, SystemConstant.BillRecordPayStatus.PAYED.getValue());
		lambda.eq(BillRecord::getType, SystemConstant.BillRecordType.ADS.getValue());
		List<BillRecord> list = baseMapper.selectList(lambda);
		BigDecimal stat = list.stream().map(item -> item.getPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
		return stat;
	}

	@Override
	public R merchantRechargeOrder(Bussiness bussiness, BillRecordDTO billRecordDTO) {
		String requestNo = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
		billRecordDTO.setOrderId(requestNo);
		BigDecimal serviceRate = bussiness.getServiceRate();
		BigDecimal price = billRecordDTO.getPrice();
		BigDecimal bussinessFee = serviceRate.multiply(price).divide(new BigDecimal(1000));
		billRecordDTO.setBussinessFee(bussinessFee);
		billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.PAYING.getValue());
		boolean save = this.save(billRecordDTO);
		if(save){
			boolean purchase = bussinessPurchaseRecordService.purchase(billRecordDTO.getPurchaseList(), bussiness, billRecordDTO.getOrderId(), billRecordDTO.getId());
			if(purchase){
				BussinessInfo parentBussinessInfo = this.bussinessInfoService.getByBussinessId(bussiness.getParentBussinessId());
				RechargeDto rechargeDto = new RechargeDto();
				rechargeDto.setParentMerchantNo(parentBussinessInfo.getMerchantNo());
				rechargeDto.setAmount(price.doubleValue());
				rechargeDto.setMerchantNo(bussiness.getMerchantNo());
				rechargeDto.setPayType("B2B");
				rechargeDto.setBankCode(billRecordDTO.getBankCode());
				rechargeDto.setReturnUrl(billRecordDTO.getReturnUrl());
				rechargeDto.setRequestNo(requestNo);
				R result = yeePayService.merchantRechargeOrder(rechargeDto);
				if(!result.isSuccess()){
					billRecordDTO.setFailReason(result.getMsg());
					this.updateById(billRecordDTO);
					return result;
				}
				JSONObject data = JSONUtil.parseObj(result.getData());
				String returnCode = data.getStr("returnCode");
				String status = data.getStr("status");
				billRecordDTO.setThirdPayLog(JSONUtil.toJsonStr(data));
				if(StringUtil.isNotBlank(returnCode)){
					if(returnCode.equals("UA00000")){
						billRecordDTO.setThirdOrderNo(data.getStr("orderNo"));
						if(status.equals("INIT")){
							billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.HANDLING.getValue());
							this.updateById(billRecordDTO);
						}else if(status.equals("FAIL")){
							billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.FAIL.getValue());
							billRecordDTO.setFailReason(data.getStr("returnMsg"));
							this.updateById(billRecordDTO);
							return R.fail("采购失败：" + data.getStr("returnMsg"));
						}
						return R.data(data.getStr("payUrl"));
					}else{
						billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.FAIL.getValue());
						billRecordDTO.setFailReason(data.getStr("returnMsg"));
						this.updateById(billRecordDTO);
						return R.fail(data.getStr("returnMsg"));
					}
				}else{
					if(status.equals("INIT")){
						billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.HANDLING.getValue());
						this.updateById(billRecordDTO);
						return R.data(data.getStr("payUrl"));
					}else if(status.equals("FAIL")){
						billRecordDTO.setPayStatus(SystemConstant.BillRecordPayStatus.FAIL.getValue());
						billRecordDTO.setFailReason(data.getStr("returnMsg"));
						this.updateById(billRecordDTO);
						return R.fail("采购失败：" + data.getStr("returnMsg"));
					}
					return R.data(data.getStr("payUrl"));
				}
			}else{
				return R.fail("采购商品订单保存失败");
			}
		}else{
			return R.fail("采购账单保存失败");
		}
	}


}
