package com.wzj.soopin.transaction.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.transaction.domain.bo.WithdrawBO;
import com.wzj.soopin.member.domain.po.MemberAccount;
import com.wzj.soopin.member.domain.po.AccountBill;
import com.wzj.soopin.transaction.domain.po.Withdraw;
import com.wzj.soopin.member.enums.AccountBillChangeTypeEnum;
import com.wzj.soopin.member.enums.AccountBillSourceEnum;
import com.wzj.soopin.transaction.enums.WithdrawAuditStatus;
import com.wzj.soopin.transaction.enums.WithdrawStatus;
import com.wzj.soopin.transaction.mapper.WithdrawMapper;
import com.wzj.soopin.member.service.*;
import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO;
import com.wzj.soopin.transaction.service.IAccountBillService;
import com.wzj.soopin.transaction.service.IWithdrawService;
import com.wzj.soopin.transaction.service.IEasypayService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysTenantAccount;
import org.dromara.system.service.ISysTenantAccountService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 会员封禁
 *
 * @author zcc
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class WithdrawServiceImpl extends ServiceImpl<WithdrawMapper, Withdraw> implements IWithdrawService {

    private final IMemberAccountService memberAccountService;

    private final ISysTenantAccountService sysTenantAccountService;


    /**
     * 易生账户充值服务
     */
    private final IEasypayService easypayService;

    private final IAccountBillService accountBillService;

    @Override
    public boolean audit(WithdrawBO bo) {
        Withdraw withdraw = getById(bo.getId());
        if (withdraw == null) {
            throw new RuntimeException("提现申请不存在");
        }
        if (!Objects.equals(WithdrawAuditStatus.PENDING.getCode(), withdraw.getAuditStatus())) {
            throw new RuntimeException("提现申请已处理");
        }
        //发起提现
        boolean chargeSuccess = easypayService.withdraw(withdraw.getMemberId(), withdraw.getMoney());
        if (!chargeSuccess) {
            throw new RuntimeException("提现失败");
        }
        withdraw = Withdraw.builder().id(bo.getId())
            .auditReason(bo.getAuditReason())
            .auditTime(LocalDateTime.now())
            .auditStatus(bo.getAuditStatus())
            .auditBy(LoginHelper.getUserId())
            .build();
        this.updateById(withdraw);
        return true;
    }

    @Override
    public boolean withdrawCallback(WithdrawBO withdraw) {
        MemberAccount memberAccount = memberAccountService.getMemberAccount(withdraw.getMemberId());
        BigDecimal balance = memberAccount.getWallet();
        ////提现成功后，更新会员账户余额
        //从易生取，别用自己计算的
        //// TODO: 2025/6/21  测试的时候用计算的 测试完用易生的
        BigDecimal finalBalance = balance.subtract(withdraw.getMoney());
        EasypayAccountVO easypayAccountVO = easypayService.getEasypayAccount(withdraw.getMemberId());
        memberAccountService.updateById(memberAccount.toBuilder().wallet(finalBalance).build());
        //生成账户变动记录bh
        AccountBill memberAccountChangeRecord = AccountBill.builder()
            .accountId(withdraw.getMemberId())
            .moneyBalance(finalBalance)
            .beforeBalance(balance)
            .afterBalance(easypayAccountVO.getBalance())
            .changeType(AccountBillChangeTypeEnum.OUT.getCode())
            .changeDesc("提现")
            .source(AccountBillSourceEnum.WITHDRAW.getCode()).build();
        accountBillService.save(memberAccountChangeRecord);

        return true;
    }

    @Override
    public boolean save(Withdraw entity) {
        entity.setStatus(WithdrawStatus.WAITING.getCode());
        return super.save(entity);
    }


    public boolean withdrawRevenue(Withdraw withdraw) {
        //调用三方支付平台获取用户余额
        // TODO: 2025/9/10  这个地方不能用null ，但是现在商户提现的业务不对，暂时没有提现业务
        SysTenantAccount tenantAccount = sysTenantAccountService.getByTenantId(null);
        if (tenantAccount == null) {
            throw new RuntimeException("用户不存在");
        }
        BigDecimal balance = tenantAccount.getRevenue();
        EasypayAccountVO easypayAccountVO = easypayService.getEasypayAccount(withdraw.getMemberId());

        if (easypayAccountVO == null) {
            throw new RuntimeException("账户余额获取失败");
        }
        //生成费用
        BigDecimal fee = withdraw.getMoney().multiply(new BigDecimal("0.01"));
        withdraw.setFee(fee);
        withdraw.setActualMoney(withdraw.getMoney().subtract(fee));


        save(withdraw);
        BigDecimal newBalance = balance.subtract(withdraw.getMoney());

        tenantAccount.setRevenue(newBalance);
        //锁定用户余额
        sysTenantAccountService.updateById(tenantAccount);

        //生成账单
        AccountBill memberAccountChangeRecord = AccountBill.builder()
            .accountId(withdraw.getMemberId())
            .moneyBalance(balance.subtract(withdraw.getMoney()))
            .beforeBalance(balance)
            .afterBalance(newBalance)
            .changeType(AccountBillChangeTypeEnum.OUT.getCode())
            .changeDesc("提现锁定")
            .source(AccountBillSourceEnum.WITHDRAW.getCode())
            .build();
        accountBillService.save(memberAccountChangeRecord);
        return true;
    }

    public boolean withdrawWallet(Withdraw withdraw) {
        MemberAccount memberAccount = memberAccountService.getMemberAccount(withdraw.getMemberId());
        if (memberAccount == null) {
            throw new RuntimeException("用户不存在");
        }
        //检查当前用于的账户余额是否充足
        BigDecimal balance = memberAccount.getWallet();
        if (balance==null||balance.compareTo(withdraw.getMoney()) < 0) {
            throw new RuntimeException("用户余额不足");
        }
        //生成费用
        BigDecimal fee = withdraw.getMoney().multiply(new BigDecimal("0.01"));
        withdraw.setFee(fee);
        withdraw.setActualMoney(withdraw.getMoney().subtract(fee));
        save(withdraw);

        BigDecimal newBalance = balance.subtract(withdraw.getMoney());
        //锁定用户余额
        memberAccountService.updateById(memberAccount.toBuilder().wallet(newBalance).build());

        //生成账单
        AccountBill memberAccountChangeRecord = AccountBill.builder()
            .accountId(withdraw.getMemberId())
            .moneyBalance(newBalance)
            .beforeBalance(balance)
            .afterBalance(newBalance)
            .changeType(AccountBillChangeTypeEnum.OUT.getCode())
            .changeDesc("提现锁定")
            .source(AccountBillSourceEnum.WITHDRAW.getCode())
            .build();
        accountBillService.save(memberAccountChangeRecord);
        return true;
    }
}
