package com.ruoyi.web.work.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.work.api.util.AppUtil;
import com.ruoyi.web.work.domain.Pay;
import com.ruoyi.web.work.domain.Platform;
import com.ruoyi.web.work.domain.User;
import com.ruoyi.web.work.domain.dto.PayAuditDto;
import com.ruoyi.web.work.domain.dto.PayCashOutDto;
import com.ruoyi.web.work.mapper.PayMapper;
import com.ruoyi.web.work.service.IPayService;
import com.ruoyi.web.work.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.rmi.ServerException;
import java.util.Date;
import java.util.List;

/**
 * @author lsw
 * @date 2024-07-01
 */
@Service
public class PayServiceImpl extends ServiceImpl<PayMapper, Pay> implements IPayService {
    @Autowired
    private PayMapper payMapper;

    @Autowired
    IUserService userService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private Environment env;

    @Override
    public List<Pay> selectList(Pay pay) {
        return payMapper.selectList(pay);
    }

    @Override
    public Pay selectByNums(String nums) {
        return payMapper.selectByNums(nums);
    }

    @Transactional
    @Override
    public AjaxResult cashOut(PayCashOutDto dto) throws ServerException {
        Platform platform = redisCache.getCacheObject(CacheConstants.APP_PLATFORM);
        User user = userService.getById(AppUtil.getUser().getId());
        if (dto.getWay() == 0 && StringUtils.isEmpty(user.getBankAccount())) {
            return AjaxResult.error("银行卡信息未完善,无法提现");
        }
        if (dto.getMoney().compareTo(platform.getCashOutMoney()) < 0) {
            return AjaxResult.error("最少提现金额：" + platform.getCashOutMoney() + "起");
        }
        if (dto.getMoney().compareTo(user.getMoney()) > 0) {
            return AjaxResult.error("提现金额超过账户余额");
        }
        //服务费
        BigDecimal serviceMoney = platform.getCashOutService().divide(new BigDecimal("100")).multiply(dto.getMoney()).setScale(2, RoundingMode.HALF_UP);
        //实际到账
        BigDecimal realMoney = dto.getMoney().subtract(serviceMoney).setScale(2, RoundingMode.HALF_UP);
        if (!serviceMoney.equals(dto.getServiceMoney()) || !realMoney.equals(dto.getRealMoney())) {
            return AjaxResult.error("提现金额异常");
        }
        //保存提现记录
        Pay pay = new Pay();
        pay.setUserId(AppUtil.getUser().getId());
        pay.setMoney(dto.getMoney());
        pay.setState(0);
        pay.setType(2);
        pay.setServiceMoney(serviceMoney);
        pay.setRate(platform.getCashOutService());
        pay.setWay(dto.getWay());
        pay.setTitle("余额提现");
        pay.setVersion(System.currentTimeMillis());
        pay.setNums(StringUtils.generateNumber());
        if (!save(pay)) {
            throw new ServerException("提现申请失败,请联系平台");
        }
        //更新账户余额
        user.setMoney(user.getMoney().subtract(dto.getMoney()));
        if (!userService.updateById(user)) {
            throw new ServerException("更新账户余额失败,请联系平台");
        }
        return AjaxResult.success();
    }

    @Transactional
    @Override
    public AjaxResult audit(PayAuditDto dto) throws ServerException {
        Pay pay = getById(dto.getId());
        if (pay == null || pay.getType() != 2) {
            return AjaxResult.error("提现信息不存在");
        }
        if (pay.getState() == 1) {
            return AjaxResult.error("不能重复操作");
        }
        pay.setState(dto.getState());
        pay.setMsg(dto.getMsg());
        pay.setCompleteTime(new Date());
        if (!updateById(pay)) {
            throw new ServerException("提现失败,请联系平台");
        }
        //提现驳回需要退回到用户账户余额
        if (dto.getState() == 2) {
            User user = userService.getById(pay.getUserId());
            user.setMoney(user.getMoney().add(pay.getMoney()));
            if (!userService.updateById(user)) {
                throw new ServerException("更新用户账户余额失败,请联系平台");
            }
        }
        sendMessage(pay);
        return AjaxResult.success();
    }

    @Override
    public void sendMessage(Pay pay) {
        JSONObject jsonObject = JSONUtil.parseObj(HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + env.getProperty("wx.appid") + "&secret=" + env.getProperty("wx.appSecret")));
        JSONObject body = new JSONObject();
        body.set("appid", env.getProperty("wx.appid"));
        JSONObject content = new JSONObject();
        //提现成功通知
        if (pay.getState() == 1) {
            User user = userService.getById(pay.getUserId());
            body.set("touser", user.getOpenId());
            body.set("template_id", "PtdKbqfzmpvGsJPx_YekDX4-cljbhOXcvoUB3XJaVLg");
            body.set("page", "pages/user/money/index");
            content.set("amount3", new JSONObject().set("value", pay.getMoney() + "元"));//提现金额
            content.set("character_string4", new JSONObject().set("value", pay.getNums()));//交易单号
            content.set("time2", new JSONObject().set("value", DateUtils.getTime())); //提现时间
        }
        //提现失败通知
        if (pay.getState() == 2) {
            User user = userService.getById(pay.getUserId());
            body.set("touser", user.getOpenId());
            body.set("template_id", "NIqSQq0j765o9Iz9gMiSelnuxMgPIPeCnk3lvEnWJlo");
            body.set("page", "pages/user/money/index");
            content.set("amount3", new JSONObject().set("value", pay.getMoney() + "元"));//提现金额
            content.set("character_string4", new JSONObject().set("value", pay.getNums()));//交易单号
            content.set("thing5", new JSONObject().set("value", pay.getMsg())); //失败原因
            content.set("time2", new JSONObject().set("value", DateUtils.getTime())); //提现时间
        }
        body.set("data", content);
        String result = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + jsonObject.getStr("access_token"), body.toString());
        System.out.println("body：" + body);
        System.out.println("小程序订阅消息：" + result);
    }
}
