package com.sqx.modules.pay.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Query;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoney;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.invite.dao.InviteMoneyDao;
import com.sqx.modules.invite.entity.Invite;
import com.sqx.modules.invite.entity.InviteMoney;
import com.sqx.modules.message.dao.MessageInfoDao;
import com.sqx.modules.message.entity.MessageInfo;
import com.sqx.modules.pay.dao.CashOutDao;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.service.CashOutService;
import com.sqx.modules.utils.AmountCalUtils;
import com.sqx.modules.utils.excel.ExcelData;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weixin.popular.api.MessageAPI;
import weixin.popular.bean.message.templatemessage.TemplateMessage;
import weixin.popular.bean.message.templatemessage.TemplateMessageItem;
import weixin.popular.bean.message.templatemessage.TemplateMessageResult;
import weixin.popular.support.TokenManager;

import javax.websocket.SendResult;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 提现申请记录
 */
@Service
public class CashOutServiceImpl extends ServiceImpl<CashOutDao, CashOut> implements CashOutService {

    /**
     * 提现申请记录
     */
    @Autowired
    private CashOutDao cashOutDao;
    /**
     * 通用配置
     */
    @Autowired
    private CommonInfoService commonInfoService;
    /**
     * app用户
     */
    @Autowired
    private UserService userService;
    @Autowired
    private MessageInfoDao messageInfoDao;
    @Autowired
    private UserMoneyService userMoneyService;
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private InviteMoneyDao inviteMoneyDao;

    @Override
    public PageUtils selectCashOutList(Integer page, Integer limit,String userName ,String zhifubaoName, String zhifubao, String userId,  Integer state, Integer userType, String startTime, String endTime,String phone) {
        IPage<CashOut> cashOutIPage = baseMapper.selectCashOutPage(new Page<>(page, limit),userName,zhifubaoName, zhifubao, userId, state, userType, startTime, endTime, phone);
        return new PageUtils(cashOutIPage);
    }

    @Override
    public ExcelData excelPayDetails(String userName ,String zhifubaoName, String zhifubao, String userId,  Integer state, Integer userType,
                                     String startTime, String endTime,String phone) {
        List<CashOut> cashOutIPage = baseMapper.selectCashOutList( userName,zhifubaoName, zhifubao, userId, state, userType, startTime, endTime, phone);
        ExcelData data = new ExcelData();
        data.setName("提现列表");
        List<String> titles = new ArrayList();
        titles.add("编号");titles.add("用户类型");titles.add("手机号");titles.add("提现类型");titles.add("支付宝账号");titles.add("支付宝名称");
        titles.add("绑定银行卡姓名");titles.add("银行名称");titles.add("银行卡账号");titles.add("开户行地址");
        titles.add("提现金额");titles.add("状态");
        titles.add("拒绝原因");titles.add("申请时间");titles.add("转账/拒绝时间");titles.add("转账订单号");
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList();
        for(CashOut cashOut:cashOutIPage){
            List<Object> row = new ArrayList();
            row.add(cashOut.getId());
            if(cashOut.getUserType()==null || cashOut.getUserType()==1){
                row.add("用户");
            }else{
                row.add("技师");
            }
            row.add(cashOut.getPhone());
            if(cashOut.getClassify()==null || cashOut.getClassify()==1){
                row.add("支付宝");
            }else{
                row.add("银行卡");
            }
            row.add(cashOut.getZhifubao());row.add(cashOut.getZhifubaoName());
            row.add(cashOut.getBankCardUserName());row.add(cashOut.getBankCardName());
            row.add(cashOut.getBankCard());row.add(cashOut.getBankCardAddress());
            row.add(cashOut.getMoney());
            if(cashOut.getState()==-1){
                row.add("退款");
            }else if(cashOut.getState()==0){
                row.add("待转账");
            }else{
                row.add("成功");
            }
            row.add(cashOut.getRefund()==null?"":cashOut.getRefund());
            row.add(cashOut.getCreateAt());
            row.add(StringUtils.isEmpty(cashOut.getOutAt())?"":cashOut.getOutAt());
            row.add(cashOut.getOrderNumber());
            rows.add(row);
        }
        data.setRows(rows);
        return data;
    }


    @Override
    public CashOut selectById(Long id) {
        return cashOutDao.selectById(id);
    }

    @Override
    public int saveBody(CashOut cashOut) {
        return cashOutDao.insert(cashOut);
    }


    @Override
    public int update(CashOut cashOut) {
        return cashOutDao.updateById(cashOut);
    }


    @Override
    public void cashOutSuccess(UserEntity userByWxId, String date, String money, String payWay, String url) {
        if(userByWxId!=null){
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState(String.valueOf(5));
            messageInfo.setContent("您好，您的提现转账成功，请注意查收！提现金额【" + money + "元】！支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服");
            messageInfo.setTitle("提现成功通知");
            messageInfo.setUserName(userByWxId.getUserName());
            messageInfo.setUserId(String.valueOf(userByWxId.getUserId()));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date now = new Date();
            messageInfo.setCreateAt(sdf.format(now));
            messageInfo.setIsSee("0");
            messageInfoDao.insert(messageInfo);
            if (userByWxId.getClientid() != null) {
                userService.pushToSingle("提现成功通知", "您好，您的提现转账成功，请注意查收！提现金额【" + money + "元】！支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", userByWxId.getClientid());
            }
            /*CommonInfo three = commonInfoService.findOne(39);
            String apkey = "";
            if (three != null) {
                apkey = three.getValue();
            }
            if(StringUtils.isNotBlank(userByWxId.getOpenId())){
                LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
                data.put("first", new TemplateMessageItem("您好，您的提现转账成功，请注意查收", "#d71345"));
                data.put("keyword1", new TemplateMessageItem(money + " 元", "#d71345"));
                data.put("keyword2", new TemplateMessageItem(date, "#d71345"));
                data.put("remark", new TemplateMessageItem("支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", null));
                sendWxMessage(apkey, data, userByWxId.getOpenId(), url);
            }*/
        }

    }

    /**
     * 退款成功通知
     *
     * @param
     * @param date
     * @param money
     * @param url
     */
    @Override
    public void refundSuccess(UserEntity userByWxId, String date, String money, String url, String content) {
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setState(String.valueOf(5));
        messageInfo.setContent(content);
        messageInfo.setTitle("提现失败提醒");
        messageInfo.setUserName(userByWxId.getUserName());
        messageInfo.setUserId(String.valueOf(userByWxId.getUserId()));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();
        messageInfo.setCreateAt(sdf.format(now));
        messageInfo.setIsSee("0");
        messageInfoDao.insert(messageInfo);
        if (userByWxId.getClientid() != null) {
            userService.pushToSingle("提现失败提醒", content, userByWxId.getClientid());
        }
        /*CommonInfo three = commonInfoService.findOne(77);
        String apkey = "";
        if (three != null) {
            apkey = three.getValue();
        }
        if(StringUtils.isNotBlank(userByWxId.getOpenId())){
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("您好，您发起的提现失败了", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(money + " 元", "#d71345"));
            data.put("keyword2", new TemplateMessageItem(date, "#d71345"));
            data.put("keyword3", new TemplateMessageItem(content, "#d71345"));
            data.put("remark", new TemplateMessageItem("请您按照失败原因修改相关信息后，重新提现！", null));
            sendWxMessage(apkey, data, userByWxId.getOpenId(), url);
        }*/

    }

    @Override
    public Double selectCashOutSum(Long userId, Date startTime, Date endTime) {
        return cashOutDao.selectCashOutSum(userId, startTime, endTime);
    }

    @Override
    public Double sumMoney(String time, Integer flag) {
        return cashOutDao.sumMoney(time, flag);
    }

    @Override
    public Double sumMoneyMonthByUserId(String time, Long userId) {
        return cashOutDao.sumMoneyMonthByUserId(time, userId);
    }

    @Override
    public Integer countMoney(String time, Integer flag) {
        return cashOutDao.countMoney(time, flag);
    }

    @Override
    public Integer stayCount(String time, Integer flag) {
        return cashOutDao.stayCount(time, flag);
    }

    @Override
    public Double stayMoney(String time, Integer flag) {
        return cashOutDao.stayMoney(time, flag);
    }

    @Override
    public Integer selectCashCountByClassify(String time, Integer flag,Integer classify,Integer state) {
        return cashOutDao.selectCashCountByClassify(time, flag,classify,state);
    }

    @Override
    public Double selectCashMoneyByClassify(String time, Integer flag,Integer classify,Integer state) {
        return cashOutDao.selectCashMoneyByClassify(time, flag,classify,state);
    }

    @Override
    public void updateMayMoney(int i, Long userId, Double money) {
        cashOutDao.updateMayMoney(i, userId, money);
    }


    @Override
    public List<CashOut> selectCashOutLimit3() {
        return cashOutDao.selectCashOutLimit3();
    }


    @Override
    @Transactional
    public Result cashMoney(Long userId, Double money,Integer userType,Integer classify) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd");
        String nowDay = simpleDateFormat.format(new Date());
        String value = commonInfoService.findOne(334).getValue();
        if(StringUtils.isNotBlank(value)){
            boolean flag=true;
            for(String day:value.split(",")){
                if(nowDay.equals(day)){
                    flag=false;
                    break;
                }
            }
            if(flag){
                return Result.error("请在"+value+"号进行提现！");
            }
        }

        if (money == null || money <= 0.00) {
            return Result.error("请不要输入小于0的数字,请输入正确的提现金额！");
        }
        //最低提现金额
        CommonInfo one = commonInfoService.findOne(112);
        if (one != null && money < Double.parseDouble(one.getValue())) {
            return Result.error("输入金额不满足最低提现金额，请重新输入！");
        }
        //最高提现金额
        CommonInfo one2 = commonInfoService.findOne(153);
        if (one2 != null && money > Double.parseDouble(one2.getValue())) {
            return Result.error(-100, "输入金额过大，不能大于" + one2.getValue() + "，请重新输入！");
        }
        //手续费
        CommonInfo one1 = commonInfoService.findOne(152);

        //计算提现金额所需要的手续费  小于0.01 的按0.01来算
        Double mul = AmountCalUtils.mul(money, Double.parseDouble(one1.getValue()));
        if (mul < 0.01) {
            mul = 0.01;
        }
        //查询账户的余额
        UserMoney userMoney = userMoneyService.selectUserMoneyByUserId(userId);
        if(money>userMoney.getMoney().doubleValue()){
            return Result.error("金额不足，请输入正确的金额！");
        }
        UserEntity userEntity = userService.selectUserById(userId);
        CashOut cashOut = new CashOut();
        cashOut.setClassify(classify);
        if(classify==1){
            cashOut.setZhifubao(userEntity.getZhiFuBao());
            cashOut.setZhifubaoName(userEntity.getZhiFuBaoName());
        }else{
            cashOut.setBankCard(userEntity.getBankCard());
            cashOut.setBankCardName(userEntity.getBankCardName());
            cashOut.setBankCardUserName(userEntity.getBankCardUserName());
            cashOut.setBankCardAddress(userEntity.getBankCardAddress());
        }

        //提现判断金额是否足够
        Double moneySum = AmountCalUtils.add(new BigDecimal(money), new BigDecimal(mul)).doubleValue(); //金额=提现金额+手续费
        Double moneySub = AmountCalUtils.sub(new BigDecimal(money), new BigDecimal(mul)).doubleValue(); //金额=提现金额+手续费
        if ((userMoney.getMoney()).compareTo(BigDecimal.valueOf(moneySum)) > -1) { //用户金额足够
            //扣除可提现金额直接在数据库进行操作
            //增加金额操作记录
            userMoneyService.updateMoney(2,userId,moneySum);
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            //查询用户当前余额
            UserMoney userNowMoney = userMoneyService.selectUserMoneyByUserId(userId);
            //插入余额
            userMoneyDetails.setBalance(userNowMoney.getMoney());
            //插入操作类型为已操作用户余额
            userMoneyDetails.setManipulateType(2);
            userMoneyDetails.setUserId(userId);
            userMoneyDetails.setClassify(3);
            userMoneyDetails.setTitle("提现：" + money);
            userMoneyDetails.setContent("支付宝提现：" + money + "，手续费：" + mul );
            userMoneyDetails.setType(2);
            userMoneyDetails.setState(1);
            userMoneyDetails.setMoney(new BigDecimal(moneySum));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userMoneyDetails.setCreateTime(sdf.format(new Date()));
            userMoneyDetails.setBlRole(2);
            userMoneyDetails.setBlFlag(1);
            userMoneyDetailsService.save(userMoneyDetails);
            cashOut.setUserMoneyDetailId(userMoneyDetails.getId());
            cashOut.setState(0);
            cashOut.setMoney(money.toString());
            cashOut.setCreateAt(sdf.format(new Date()));
            cashOut.setUserId(userEntity.getUserId());
            cashOut.setRate(moneySum);
            cashOut.setOrderNumber(String.valueOf(System.currentTimeMillis()));
            cashOut.setUserType(userType);
            baseMapper.insert(cashOut);
            //扣除金额直接在数据库进行操作
            return Result.success("提现成功，将在三个工作日内到账，请耐心等待！");
        }else{
            //扣除可提现金额直接在数据库进行操作
            //增加金额操作记录
            userMoneyService.updateMoney(2,userId,money);
            UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
            //查询用户当前余额
            UserMoney userNowMoney = userMoneyService.selectUserMoneyByUserId(userId);
            //插入余额
            userMoneyDetails.setBalance(userNowMoney.getMoney());
            //插入操作类型为已操作用户余额
            userMoneyDetails.setManipulateType(2);
            userMoneyDetails.setUserId(userId);
            userMoneyDetails.setClassify(3);
            userMoneyDetails.setTitle("提现：" + moneySub);
            userMoneyDetails.setContent("支付宝提现：" + moneySub + "，手续费：" + mul );
            userMoneyDetails.setType(2);
            userMoneyDetails.setState(1);
            userMoneyDetails.setMoney(new BigDecimal(money));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            userMoneyDetails.setCreateTime(sdf.format(new Date()));
            userMoneyDetails.setBlRole(2);
            userMoneyDetails.setBlFlag(1);
            userMoneyDetailsService.save(userMoneyDetails);
            cashOut.setUserMoneyDetailId(userMoneyDetails.getId());
            cashOut.setState(0);
            cashOut.setMoney(moneySub.toString());
            cashOut.setCreateAt(sdf.format(new Date()));
            cashOut.setUserId(userEntity.getUserId());
            cashOut.setRate(money);
            cashOut.setOrderNumber(String.valueOf(System.currentTimeMillis()));
            cashOut.setUserType(userType);
            baseMapper.insert(cashOut);
            return Result.success("提现成功，将在三个工作日内到账，请耐心等待！");
        }
    }

}
