package com.it.rattan.monisuo.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.rattan.monisuo.entity.*;
import com.it.rattan.monisuo.mapper.OrderTradeMapper;
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.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 交易服务
 */
@Service
public class TradeService {

    @Autowired
    private OrderTradeMapper orderTradeMapper;

    @Autowired
    private AssetService assetService;

    @Autowired
    private CoinService coinService;

    /**
     * 买入
     */
    @Transactional
    public Map<String, Object> buy(Long userId, String coinCode, BigDecimal price, BigDecimal quantity) {
        Coin coin = coinService.getCoinByCode(coinCode);
        if (coin == null) {
            throw new RuntimeException("币种不存在");
        }

        if (coin.getStatus() != 1) {
            throw new RuntimeException("该币种已下架");
        }

        // 计算金额
        BigDecimal amount = price.multiply(quantity).setScale(8, RoundingMode.DOWN);

        // 检查交易账户USDT余额
        AccountTrade usdtAccount = assetService.getOrCreateTradeAccount(userId, "USDT");
        if (usdtAccount.getQuantity().compareTo(amount) < 0) {
            throw new RuntimeException("交易账户USDT余额不足，请先划转资金");
        }

        // 扣减USDT
        usdtAccount.setQuantity(usdtAccount.getQuantity().subtract(amount));
        usdtAccount.setUpdateTime(LocalDateTime.now());

        // 增加持仓
        AccountTrade coinAccount = assetService.getOrCreateTradeAccount(userId, coinCode);
        BigDecimal oldTotal = coinAccount.getQuantity().multiply(coinAccount.getAvgPrice());
        BigDecimal newTotal = oldTotal.add(amount);
        BigDecimal newQuantity = coinAccount.getQuantity().add(quantity);

        coinAccount.setQuantity(newQuantity);
        if (newQuantity.compareTo(BigDecimal.ZERO) > 0) {
            coinAccount.setAvgPrice(newTotal.divide(newQuantity, 8, RoundingMode.DOWN));
        }
        coinAccount.setTotalBuy(coinAccount.getTotalBuy().add(quantity));
        coinAccount.setUpdateTime(LocalDateTime.now());

        // 创建订单
        OrderTrade order = new OrderTrade();
        order.setOrderNo(OrderNoUtil.tradeOrderNo());
        order.setUserId(userId);
        order.setCoinCode(coinCode.toUpperCase());
        order.setDirection(1); // 买入
        order.setOrderType(1); // 市价
        order.setPrice(price);
        order.setQuantity(quantity);
        order.setAmount(amount);
        order.setFee(BigDecimal.ZERO);
        order.setStatus(1); // 成功
        order.setCreateTime(LocalDateTime.now());
        orderTradeMapper.insert(order);

        // 记录流水
        assetService.createFlow(userId, 5, amount.negate(), usdtAccount.getQuantity().add(amount),
                usdtAccount.getQuantity(), "USDT", order.getOrderNo(),
                "买入" + coinCode + "，数量:" + quantity);

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

    /**
     * 卖出
     */
    @Transactional
    public Map<String, Object> sell(Long userId, String coinCode, BigDecimal price, BigDecimal quantity) {
        Coin coin = coinService.getCoinByCode(coinCode);
        if (coin == null) {
            throw new RuntimeException("币种不存在");
        }

        if (coin.getStatus() != 1) {
            throw new RuntimeException("该币种已下架");
        }

        // 检查持仓
        AccountTrade coinAccount = assetService.getOrCreateTradeAccount(userId, coinCode);
        if (coinAccount.getQuantity().compareTo(quantity) < 0) {
            throw new RuntimeException("持仓数量不足");
        }

        // 计算金额
        BigDecimal amount = price.multiply(quantity).setScale(8, RoundingMode.DOWN);

        // 扣减持仓
        coinAccount.setQuantity(coinAccount.getQuantity().subtract(quantity));
        coinAccount.setTotalSell(coinAccount.getTotalSell().add(quantity));
        coinAccount.setUpdateTime(LocalDateTime.now());

        // 增加USDT
        AccountTrade usdtAccount = assetService.getOrCreateTradeAccount(userId, "USDT");
        usdtAccount.setQuantity(usdtAccount.getQuantity().add(amount));
        usdtAccount.setUpdateTime(LocalDateTime.now());

        // 创建订单
        OrderTrade order = new OrderTrade();
        order.setOrderNo(OrderNoUtil.tradeOrderNo());
        order.setUserId(userId);
        order.setCoinCode(coinCode.toUpperCase());
        order.setDirection(2); // 卖出
        order.setOrderType(1); // 市价
        order.setPrice(price);
        order.setQuantity(quantity);
        order.setAmount(amount);
        order.setFee(BigDecimal.ZERO);
        order.setStatus(1); // 成功
        order.setCreateTime(LocalDateTime.now());
        orderTradeMapper.insert(order);

        // 记录流水
        assetService.createFlow(userId, 6, amount, usdtAccount.getQuantity().subtract(amount),
                usdtAccount.getQuantity(), "USDT", order.getOrderNo(),
                "卖出" + coinCode + "，数量:" + quantity);

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

    /**
     * 获取交易记录
     */
    public IPage<OrderTrade> getOrders(Long userId, String coinCode, Integer direction,
                                       int pageNum, int pageSize) {
        LambdaQueryWrapper<OrderTrade> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderTrade::getUserId, userId);
        if (coinCode != null && !coinCode.isEmpty()) {
            wrapper.eq(OrderTrade::getCoinCode, coinCode.toUpperCase());
        }
        if (direction != null && direction > 0) {
            wrapper.eq(OrderTrade::getDirection, direction);
        }
        wrapper.orderByDesc(OrderTrade::getCreateTime);

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

    /**
     * 获取订单详情
     */
    public OrderTrade getOrderDetail(Long userId, String orderNo) {
        LambdaQueryWrapper<OrderTrade> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderTrade::getUserId, userId)
                .eq(OrderTrade::getOrderNo, orderNo);
        return orderTradeMapper.selectOne(wrapper);
    }
}
