package com.it.rattan.monisuo.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.rattan.monisuo.entity.AccountFund;
import com.it.rattan.monisuo.entity.OrderFund;
import com.it.rattan.monisuo.entity.User;
import com.it.rattan.monisuo.mapper.OrderFundMapper;
import com.it.rattan.monisuo.mapper.UserMapper;
import com.it.rattan.monisuo.util.OrderNoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 充提服务
 */
@Service
public class FundService {

    @Autowired
    private OrderFundMapper orderFundMapper;

    @Autowired
    private AssetService assetService;

    @Autowired
    private UserMapper userMapper;

    /**
     * 申请充值
     */
    @Transactional
    public Map<String, Object> deposit(Long userId, BigDecimal amount, String remark) {
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("充值金额必须大于0");
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        OrderFund order = new OrderFund();
        order.setOrderNo(OrderNoUtil.fundOrderNo());
        order.setUserId(userId);
        order.setUsername(user.getUsername());
        order.setType(1); // 充值
        order.setAmount(amount);
        order.setStatus(1); // 待审批
        order.setRemark(remark);
        order.setCreateTime(LocalDateTime.now());
        orderFundMapper.insert(order);

        Map<String, Object> result = new HashMap<>();
        result.put("orderNo", order.getOrderNo());
        result.put("amount", amount);
        result.put("status", order.getStatus());
        return result;
    }

    /**
     * 申请提现
     */
    @Transactional
    public Map<String, Object> withdraw(Long userId, BigDecimal amount, String remark) {
        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("提现金额必须大于0");
        }

        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查余额
        AccountFund fund = assetService.getOrCreateFundAccount(userId);
        if (fund.getBalance().compareTo(amount) < 0) {
            throw new RuntimeException("资金账户余额不足");
        }

        OrderFund order = new OrderFund();
        order.setOrderNo(OrderNoUtil.fundOrderNo());
        order.setUserId(userId);
        order.setUsername(user.getUsername());
        order.setType(2); // 提现
        order.setAmount(amount);
        order.setStatus(1); // 待审批
        order.setRemark(remark);
        order.setCreateTime(LocalDateTime.now());
        orderFundMapper.insert(order);

        Map<String, Object> result = new HashMap<>();
        result.put("orderNo", order.getOrderNo());
        result.put("amount", amount);
        result.put("status", order.getStatus());
        return result;
    }

    /**
     * 取消订单
     */
    @Transactional
    public void cancel(Long userId, String orderNo) {
        LambdaQueryWrapper<OrderFund> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderFund::getUserId, userId)
                .eq(OrderFund::getOrderNo, orderNo)
                .eq(OrderFund::getStatus, 1); // 仅待审批可取消

        OrderFund order = orderFundMapper.selectOne(wrapper);
        if (order == null) {
            throw new RuntimeException("订单不存在或状态不可取消");
        }

        order.setStatus(4); // 已取消
        order.setUpdateTime(LocalDateTime.now());
        orderFundMapper.updateById(order);
    }

    /**
     * 获取充提记录
     */
    public IPage<OrderFund> getOrders(Long userId, Integer type, int pageNum, int pageSize) {
        LambdaQueryWrapper<OrderFund> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderFund::getUserId, userId);
        if (type != null && type > 0) {
            wrapper.eq(OrderFund::getType, type);
        }
        wrapper.orderByDesc(OrderFund::getCreateTime);

        Page<OrderFund> page = new Page<>(pageNum, pageSize);
        return orderFundMapper.selectPage(page, wrapper);
    }

    /**
     * 获取待审批订单数量
     */
    public int getPendingCount() {
        return orderFundMapper.countPending();
    }

    /**
     * 管理员审批
     */
    @Transactional
    public void approve(Long adminId, String adminName, String orderNo, Integer status,
                        String rejectReason, String adminRemark) {
        OrderFund order = orderFundMapper.selectOne(
                new LambdaQueryWrapper<OrderFund>().eq(OrderFund::getOrderNo, orderNo));

        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        if (order.getStatus() != 1) {
            throw new RuntimeException("订单已处理");
        }

        if (status == 2) {
            // 审批通过
            AccountFund fund = assetService.getOrCreateFundAccount(order.getUserId());

            if (order.getType() == 1) {
                // 充值：增加余额
                fund.setBalance(fund.getBalance().add(order.getAmount()));
                fund.setTotalDeposit(fund.getTotalDeposit().add(order.getAmount()));
            } else {
                // 提现：扣减余额
                if (fund.getBalance().compareTo(order.getAmount()) < 0) {
                    throw new RuntimeException("用户余额不足");
                }
                fund.setBalance(fund.getBalance().subtract(order.getAmount()));
                fund.setTotalWithdraw(fund.getTotalWithdraw().add(order.getAmount()));
            }

            fund.setUpdateTime(LocalDateTime.now());

            // 更新账户
            LambdaUpdateWrapper<AccountFund> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(AccountFund::getUserId, order.getUserId())
                    .set(AccountFund::getBalance, fund.getBalance())
                    .set(AccountFund::getTotalDeposit, fund.getTotalDeposit())
                    .set(AccountFund::getTotalWithdraw, fund.getTotalWithdraw())
                    .set(AccountFund::getUpdateTime, LocalDateTime.now());
            assetService.updateFundAccount(updateWrapper);

            // 记录流水
            int flowType = order.getType() == 1 ? 1 : 2;
            String remark = order.getType() == 1 ? "充值" : "提现";
            assetService.createFlow(order.getUserId(), flowType, order.getAmount(),
                    fund.getBalance().subtract(order.getAmount()),
                    fund.getBalance(), "USDT", orderNo, remark);

        } else if (status == 3) {
            // 审批驳回
            if (rejectReason == null || rejectReason.isEmpty()) {
                throw new RuntimeException("请填写驳回原因");
            }
            order.setRejectReason(rejectReason);
        }

        order.setStatus(status);
        order.setApproveAdminId(adminId);
        order.setApproveAdminName(adminName);
        order.setApproveTime(LocalDateTime.now());
        order.setAdminRemark(adminRemark);
        order.setUpdateTime(LocalDateTime.now());
        orderFundMapper.updateById(order);
    }

    /**
     * 获取待审批订单列表
     */
    public IPage<OrderFund> getPendingOrders(int pageNum, int pageSize) {
        LambdaQueryWrapper<OrderFund> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderFund::getStatus, 1)
                .orderByAsc(OrderFund::getCreateTime);

        Page<OrderFund> page = new Page<>(pageNum, pageSize);
        return orderFundMapper.selectPage(page, wrapper);
    }

    /**
     * 获取所有充提订单(管理员)
     */
    public IPage<OrderFund> getAllOrders(Integer type, Integer status, int pageNum, int pageSize) {
        LambdaQueryWrapper<OrderFund> wrapper = new LambdaQueryWrapper<>();
        if (type != null && type > 0) {
            wrapper.eq(OrderFund::getType, type);
        }
        if (status != null && status > 0) {
            wrapper.eq(OrderFund::getStatus, status);
        }
        wrapper.orderByDesc(OrderFund::getCreateTime);

        Page<OrderFund> page = new Page<>(pageNum, pageSize);
        return orderFundMapper.selectPage(page, wrapper);
    }
}
