package com.zhentao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhentao.entity.*;
import com.zhentao.mapper.*;
import com.zhentao.service.PointsMallService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 积分商城服务实现类
 */
@Service
public class PointsMallServiceImpl implements PointsMallService {

    @Autowired
    private PointsProductMapper pointsProductMapper;

    @Autowired
    private PointsOrderMapper pointsOrderMapper;

    @Autowired
    private PointsDetailMapper pointsDetailMapper;

    @Autowired
    private PointRuleMapper pointRuleMapper;

    @Autowired
    private MatchmakerMapper matchmakerMapper;

    @Override
    public Map<String, Object> getProductList(Integer category, Integer pageNum, Integer pageSize) {
        Page<PointsProduct> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PointsProduct> wrapper = new LambdaQueryWrapper<>();

        // 只查询上架的商品
        wrapper.eq(PointsProduct::getStatus, 1);

        // 按分类筛选
        if (category != null && category > 0) {
            wrapper.eq(PointsProduct::getCategory, category);
        }

        // 按排序和创建时间排序
        wrapper.orderByDesc(PointsProduct::getSortOrder)
                .orderByDesc(PointsProduct::getCreateTime);

        Page<PointsProduct> result = pointsProductMapper.selectPage(page, wrapper);

        Map<String, Object> data = new HashMap<>();
        data.put("list", result.getRecords());
        data.put("total", result.getTotal());
        data.put("pageNum", pageNum);
        data.put("pageSize", pageSize);
        data.put("pages", result.getPages());

        return data;
    }

    @Override
    public List<PointsProduct> getRecommendProducts(Integer limit) {
        LambdaQueryWrapper<PointsProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointsProduct::getStatus, 1)
                .eq(PointsProduct::getIsRecommend, 1)
                .orderByDesc(PointsProduct::getSortOrder)
                .last("LIMIT " + (limit != null ? limit : 10));

        return pointsProductMapper.selectList(wrapper);
    }

    @Override
    public PointsProduct getProductDetail(Long productId) {
        return pointsProductMapper.selectById(productId);
    }

    @Override
    public Integer getPointsBalance(Long makerId) {
        Matchmaker matchmaker = matchmakerMapper.selectById(makerId);
        if (matchmaker == null) {
            return 0;
        }
        // 优先使用matchmakers表的points字段
        if (matchmaker.getPoints() != null) {
            return matchmaker.getPoints();
        }
        // 如果points字段为空，通过计算积分明细来获取余额
        LambdaQueryWrapper<PointsDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointsDetail::getMakerId, makerId);
        List<PointsDetail> details = pointsDetailMapper.selectList(wrapper);

        int balance = 0;
        for (PointsDetail detail : details) {
            balance += detail.getPoints();
        }
        return balance;
    }

    @Override
    public Map<String, Object> getPointsRecords(Long makerId, Integer pageNum, Integer pageSize) {
        Page<PointsDetail> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PointsDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointsDetail::getMakerId, makerId)
                .orderByDesc(PointsDetail::getCreateTime);

        Page<PointsDetail> result = pointsDetailMapper.selectPage(page, wrapper);

        Map<String, Object> data = new HashMap<>();
        data.put("list", result.getRecords());
        data.put("total", result.getTotal());
        data.put("pageNum", pageNum);
        data.put("pageSize", pageSize);

        return data;
    }

    @Override
    public List<PointRule> getPointRules() {
        LambdaQueryWrapper<PointRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointRule::getStatus, 1)
                .orderByAsc(PointRule::getRuleType);
        return pointRuleMapper.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PointsOrder exchangeProduct(Long makerId, Long productId, Integer quantity, String contactPhone) {
        // 1. 检查商品是否存在且上架
        PointsProduct product = pointsProductMapper.selectById(productId);
        if (product == null || product.getStatus() != 1) {
            throw new RuntimeException("商品不存在或已下架");
        }

        // 2. 检查库存
        if (product.getStock() < quantity) {
            throw new RuntimeException("商品库存不足");
        }

        // 3. 计算所需积分
        int totalPoints = product.getPointsPrice() * quantity;

        // 4. 检查积分余额
        Integer balance = getPointsBalance(makerId);
        if (balance < totalPoints) {
            throw new RuntimeException("积分余额不足，当前积分: " + balance + "，需要: " + totalPoints);
        }

        // 5. 扣减库存
        LambdaUpdateWrapper<PointsProduct> productUpdate = new LambdaUpdateWrapper<>();
        productUpdate.eq(PointsProduct::getId, productId)
                .ge(PointsProduct::getStock, quantity)
                .setSql("stock = stock - " + quantity);
        int updateCount = pointsProductMapper.update(null, productUpdate);
        if (updateCount == 0) {
            throw new RuntimeException("库存扣减失败，请重试");
        }

        // 6. 创建订单（状态为待审核）
        PointsOrder order = new PointsOrder();
        order.setOrderNo(generateOrderNo());
        order.setMakerId(makerId);
        order.setProductId(productId);
        order.setProductName(product.getName());
        order.setProductImage(product.getImageUrl());
        order.setPointsPrice(product.getPointsPrice());
        order.setQuantity(quantity);
        order.setTotalPoints(totalPoints);
        order.setStatus(0); // 0-待审核
        order.setReceiverPhone(contactPhone); // 联系电话
        order.setCreateTime(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
        order.setUpdateTime(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));

        pointsOrderMapper.insert(order);

        // 7. 记录积分变动(扣减)
        PointsDetail detail = new PointsDetail();
        detail.setMakerId(makerId);
        detail.setPoints(-totalPoints);
        detail.setReason("兑换商品: " + product.getName() + " x" + quantity);
        detail.setCreateTime(LocalDateTime.now());
        detail.setUpdateTime(LocalDateTime.now());

        pointsDetailMapper.insert(detail);

        // 8. 更新红娘积分余额
        LambdaUpdateWrapper<Matchmaker> makerUpdate = new LambdaUpdateWrapper<>();
        makerUpdate.eq(Matchmaker::getMatchmakerId, makerId)
                .setSql("points = IFNULL(points, 0) - " + totalPoints);
        matchmakerMapper.update(null, makerUpdate);

        return order;
    }

    @Override
    public Map<String, Object> getOrderList(Long makerId, Integer status, Integer pageNum, Integer pageSize) {
        Page<PointsOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PointsOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointsOrder::getMakerId, makerId);

        if (status != null && status >= 0) {
            wrapper.eq(PointsOrder::getStatus, status);
        }

        wrapper.orderByDesc(PointsOrder::getCreateTime);

        Page<PointsOrder> result = pointsOrderMapper.selectPage(page, wrapper);

        Map<String, Object> data = new HashMap<>();
        data.put("list", result.getRecords());
        data.put("total", result.getTotal());
        data.put("pageNum", pageNum);
        data.put("pageSize", pageSize);

        return data;
    }

    @Override
    public PointsOrder getOrderDetail(String orderNo) {
        LambdaQueryWrapper<PointsOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointsOrder::getOrderNo, orderNo);
        return pointsOrderMapper.selectOne(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addPoints(Long makerId, Integer ruleType, String reason) {
        // 1. 查询积分规则
        LambdaQueryWrapper<PointRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointRule::getRuleType, ruleType)
                .eq(PointRule::getStatus, 1);
        PointRule rule = pointRuleMapper.selectOne(wrapper);

        if (rule == null) {
            throw new RuntimeException("积分规则不存在");
        }

        int pointValue = rule.getPointValue();

        // 2. 记录积分变动
        PointsDetail detail = new PointsDetail();
        detail.setMakerId(makerId);
        detail.setPoints(pointValue);
        detail.setReason(reason != null ? reason : rule.getRuleName());
        detail.setCreateTime(LocalDateTime.now());
        detail.setUpdateTime(LocalDateTime.now());

        pointsDetailMapper.insert(detail);

        // 3. 更新红娘积分余额
        LambdaUpdateWrapper<Matchmaker> makerUpdate = new LambdaUpdateWrapper<>();
        makerUpdate.eq(Matchmaker::getMatchmakerId, makerId)
                .setSql("points = IFNULL(points, 0) + " + pointValue);
        matchmakerMapper.update(null, makerUpdate);

        return pointValue;
    }

    /**
     * 生成订单编号
     */
    private String generateOrderNo() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String timestamp = LocalDateTime.now().format(formatter);
        String random = String.format("%04d", new Random().nextInt(10000));
        return "PO" + timestamp + random;
    }
}
