package com.haha.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.haha.common.constant.OrderConstants;
import com.haha.common.enums.PaymentChannel;
import com.haha.common.exception.BusinessException;
import com.haha.common.utils.EntityLabelUtils;
import com.haha.entity.Device;
import com.haha.entity.Order;
import com.haha.entity.Shop;
import com.haha.mapper.DeviceMapper;
import com.haha.mapper.OrderMapper;
import com.haha.mapper.ShopMapper;
import com.haha.service.OrderService;
import com.haha.service.payment.PaymentService;
import com.haha.service.payment.RefundResult;
import com.haha.service.payment.payscore.PayScoreResult;
import com.haha.service.payment.payscore.PayScoreService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final DeviceMapper deviceMapper;
    private final ShopMapper shopMapper;
    
    @Autowired
    @Lazy
    private PaymentService paymentService;

    @Autowired
    @Lazy
    private PayScoreService payScoreService;

    @Override
    public IPage<Order> getPage(int page, int pageSize, String orderNo, String deviceId, 
                                 String payStatus, Integer status, String startDate, String endDate) {
        // 确保分页参数有效（MyBatis-Plus 要求页码从 1 开始）
        if (page < 1) {
            page = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 10;  // 默认每页 10 条，最大 100 条
        }
        
        log.info("订单分页查询：page={}, pageSize={}, orderNo={}, deviceId={}", page, pageSize, orderNo, deviceId);
        
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        
        // 构建查询条件
        wrapper.like(orderNo != null && !orderNo.isEmpty(), Order::getOrderNo, orderNo)
               .like(deviceId != null && !deviceId.isEmpty(), Order::getDeviceId, deviceId)
               .eq(payStatus != null && !payStatus.isEmpty(), Order::getPayStatus, payStatus)
               .eq(status != null, Order::getStatus, status);

        // 时间范围查询
        if (startDate != null && !startDate.isEmpty()) {
            LocalDateTime startDateTime = LocalDate.parse(startDate).atStartOfDay();
            wrapper.ge(Order::getCreateTime, startDateTime);
        }
        if (endDate != null && !endDate.isEmpty()) {
            LocalDateTime endDateTime = LocalDate.parse(endDate).atTime(LocalTime.MAX);
            wrapper.le(Order::getCreateTime, endDateTime);
        }

        // 按创建时间倒序
        wrapper.orderByDesc(Order::getCreateTime);

        // 分页查询
        IPage<Order> orderPage = this.page(new Page<>(page, pageSize), wrapper);
        
        // 填充标签字段和关联信息
        orderPage.getRecords().forEach(this::fillOrderLabels);
        
        return orderPage;
    }

    @Override
    public Order getDetailById(Long id) {
        Order order = this.getById(id);
        if (order == null) {
            return null;
        }
        fillOrderLabels(order);
        return order;
    }

    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();

        // 总订单数
        long totalOrders = this.count();
        statistics.put("totalOrders", totalOrders);

        // 今日订单数
        long todayOrders = this.lambdaQuery()
                .ge(Order::getCreateTime, todayStart)
                .count();
        statistics.put("todayOrders", todayOrders);

        // 各状态订单数
        long unpaidOrders = this.lambdaQuery()
                .eq(Order::getPayStatus, OrderConstants.PAY_STATUS_UNPAID)
                .count();
        statistics.put("unpaidOrders", unpaidOrders);

        long completedOrders = this.lambdaQuery()
                .eq(Order::getStatus, OrderConstants.STATUS_COMPLETED)
                .count();
        statistics.put("completedOrders", completedOrders);

        long cancelledOrders = this.lambdaQuery()
                .eq(Order::getStatus, OrderConstants.STATUS_CANCELLED)
                .count();
        statistics.put("cancelledOrders", cancelledOrders);

        long refundOrders = this.lambdaQuery()
                .eq(Order::getPayStatus, OrderConstants.PAY_STATUS_REFUND)
                .count();
        statistics.put("refundOrders", refundOrders);

        // 总销售额（使用SQL聚合优化性能）
        BigDecimal totalAmount = baseMapper.sumCompletedOrderAmount(null);
        statistics.put("totalAmount", totalAmount != null ? totalAmount.setScale(2, RoundingMode.HALF_UP).toString() : "0.00");

        // 今日销售额
        BigDecimal todayAmount = baseMapper.sumCompletedOrderAmount(todayStart);
        statistics.put("todayAmount", todayAmount != null ? todayAmount.setScale(2, RoundingMode.HALF_UP).toString() : "0.00");

        // 平均订单金额
        BigDecimal averageAmount = completedOrders > 0 && totalAmount != null 
            ? totalAmount.divide(BigDecimal.valueOf(completedOrders), 2, RoundingMode.HALF_UP) 
            : BigDecimal.ZERO;
        statistics.put("averageAmount", averageAmount.toString());

        return statistics;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean refund(Long orderId, String reason) {
        // 委托给 PaymentService 处理退款
        // PaymentService.refund() 内部已经处理了：
        // - 订单状态校验
        // - 调用第三方退款 API
        // - 更新退款状态和支付状态
        RefundResult result = paymentService.refund(orderId, reason);
        return result.isSuccess();
    }

    @Override
    public List<Order> getOrderListByUserId(Long userId, Integer status) {
        if (status != null) {
            return lambdaQuery().eq(Order::getUserId, userId).eq(Order::getStatus, status).list();
        } else {
            return lambdaQuery().eq(Order::getUserId, userId).list();
        }
    }

    @Override
    public boolean cancelOrder(Long orderId) {
        return lambdaUpdate().eq(Order::getId, orderId).set(Order::getStatus, OrderConstants.STATUS_CANCELLED).update();
    }

    @Override
    public boolean updateOrderStatus(Long orderId, Integer status) {
        return lambdaUpdate().eq(Order::getId, orderId).set(Order::getStatus, status).update();
    }

    @Override
    public Order getOrderByOutTradeNo(String outTradeNo) {
        return lambdaQuery().eq(Order::getOutTradeNo, outTradeNo).one();
    }

    @Override
    public Order getOrderBydeviceId(String deviceId) {
        return lambdaQuery().eq(Order::getDeviceId, deviceId).orderByDesc(Order::getCreateTime).one();
    }

    @Override
    public boolean updatePayStatus(String orderNo, String payStatus) {
        return lambdaUpdate().eq(Order::getOrderNo, orderNo).set(Order::getPayStatus, payStatus).update();
    }

    @Override
    @Transactional
    public Order createOrderFromRecognition(String activityId, String deviceId, String userId,
                                             String skuListStr, String resourceInfoStr, BigDecimal confidence) {
        // 1. 计算订单金额（从 skuListStr 解析 JSONArray，遍历计算 price * quantity）
        BigDecimal totalAmount = BigDecimal.ZERO;
        JSONArray skuList = null;
        if (skuListStr != null && !skuListStr.isEmpty()) {
            skuList = JSON.parseArray(skuListStr);
            if (skuList != null) {
                for (int i = 0; i < skuList.size(); i++) {
                    JSONObject sku = skuList.getJSONObject(i);
                    BigDecimal price = sku.getBigDecimal("price");
                    Integer quantity = sku.getInteger("quantity");
                    if (price != null && quantity != null) {
                        totalAmount = totalAmount.add(price.multiply(BigDecimal.valueOf(quantity)));
                    }
                }
                totalAmount = totalAmount.setScale(2, RoundingMode.HALF_UP);
            }
        }

        // 2. 解析视频URL
        String videoUrl = null;
        if (resourceInfoStr != null && !resourceInfoStr.isEmpty()) {
            JSONObject resourceInfo = JSON.parseObject(resourceInfoStr);
            videoUrl = resourceInfo.getString("video_url");
        }

        // 3. 创建订单（仅在有用户、设备和金额时）
        if (userId != null && deviceId != null && totalAmount.compareTo(BigDecimal.ZERO) > 0) {
            Order order = new Order();
            order.setActivityId(activityId);
            order.setUserId(Long.parseLong(userId));
            order.setDeviceId(deviceId);
            order.setTotalAmount(totalAmount);
            order.setItems(skuListStr);
            order.setStatus(OrderConstants.STATUS_PENDING_PAYMENT);
            order.setPayStatus(OrderConstants.PAY_STATUS_UNPAID);
            order.setCreateTime(LocalDateTime.now());
            if (videoUrl != null) {
                order.setVideoUrl(videoUrl);
            }
            if (confidence != null) {
                order.setConfidence(confidence);
            }

            boolean saved = this.save(order);
            if (saved) {
                log.info("订单创建成功 - 订单ID: {}, 用户: {}, 金额: {}", order.getId(), userId, totalAmount);
                return order;
            } else {
                log.error("订单创建失败 - 用户: {}, 设备: {}", userId, deviceId);
                return null;
            }
        } else {
            log.warn("订单创建跳过 - 缺少必要参数: userId={}, deviceId={}, amount={}", userId, deviceId, totalAmount);
            return null;
        }
    }

    /**
     * 填充订单标签字段
     */
    private void fillOrderLabels(Order order) {
        if (order.getPayStatus() != null) {
            var payLabel = EntityLabelUtils.getPayStatusLabel(order.getPayStatus());
            order.setPayStatusLabel(payLabel.getLabel());
        }
        if (order.getStatus() != null) {
            var statusLabel = EntityLabelUtils.getStatusLabel("order", order.getStatus());
            order.setStatusLabel(statusLabel.getLabel());
        }
        
        // 如果 payType 为空但 payChannel 有值，从 payChannel 获取描述
        if (order.getPayType() == null || order.getPayType().isEmpty()) {
            if (order.getPayChannel() != null && !order.getPayChannel().isEmpty()) {
                PaymentChannel channel = PaymentChannel.fromCode(order.getPayChannel());
                if (channel != null) {
                    order.setPayType(channel.getDescription());
                }
            } else if (order.getOutTradeNo() != null && !order.getOutTradeNo().isEmpty()) {
                order.setPayType("微信支付"); // 兼容旧数据
            } else if ("PAID".equals(order.getPayStatus())) {
                order.setPayType("免费");
            }
        }
        
        // 根据 deviceId 查询设备信息，获取门店名称
        if (order.getDeviceId() != null && !order.getDeviceId().isEmpty()) {
            try {
                // 通过 deviceId 查询设备
                Device device = deviceMapper.selectByDeviceId(order.getDeviceId());
                if (device != null) {
                    order.setShopId(device.getShopId());
                    // 通过 shopId 查询门店名称
                    if (device.getShopId() != null) {
                        Shop shop = shopMapper.selectById(device.getShopId());
                        if (shop != null) {
                            order.setShopName(shop.getName());
                            order.setStoreName(shop.getName());
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("获取订单关联门店信息失败: orderId={}, deviceId={}", order.getId(), order.getDeviceId(), e);
            }
        }
    }

    @Override
    @Transactional
    public Order createOrderWithPayScore(String activityId, String deviceId, String userId,
                                          String skuListStr, String resourceInfoStr, BigDecimal confidence,
                                          String openId) {
        Order order = createOrderFromRecognition(activityId, deviceId, userId, 
                skuListStr, resourceInfoStr, confidence);
        
        if (order == null) {
            return null;
        }

        if (openId == null || openId.isEmpty()) {
            log.warn("[支付分集成] openId为空，跳过支付分服务订单创建 - orderId: {}", order.getId());
            return order;
        }

        try {
            PayScoreResult result = payScoreService.createPayScoreOrder(order.getId(), openId);
            
            if (result.isSuccess()) {
                log.info("[支付分集成] 支付分服务订单创建成功 - orderId: {}, outOrderNo: {}", 
                        order.getId(), result.getOutOrderNo());
                order.setPayScoreOrderId(result.getOutOrderNo());
                order.setPayScoreState(result.getState());
                order.setPayChannel("wechat_payscore");
                order.setPayType("微信支付分");
                this.updateById(order);
            } else {
                log.warn("[支付分集成] 支付分服务订单创建失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        order.getId(), result.getErrorCode(), result.getErrorMsg());
            }
        } catch (Exception e) {
            log.error("[支付分集成] 支付分服务订单创建异常 - orderId: {}", order.getId(), e);
        }

        return order;
    }

    @Override
    @Transactional
    public boolean completeOrderWithPayScore(Long orderId, BigDecimal totalAmount) {
        Order order = this.getById(orderId);
        if (order == null) {
            log.error("[支付分集成] 订单不存在 - orderId: {}", orderId);
            return false;
        }

        if (order.getPayScoreOrderId() == null) {
            log.warn("[支付分集成] 订单未创建支付分服务订单，直接更新状态 - orderId: {}", orderId);
            order.setTotalAmount(totalAmount);
            order.setPayStatus(OrderConstants.PAY_STATUS_PAID);
            order.setStatus(OrderConstants.STATUS_COMPLETED);
            order.setPayTime(LocalDateTime.now());
            return this.updateById(order);
        }

        try {
            PayScoreResult result = payScoreService.completePayScoreOrder(orderId, totalAmount, null);
            
            if (result.isSuccess()) {
                log.info("[支付分集成] 支付分完结成功 - orderId: {}, state: {}", orderId, result.getState());
                return true;
            } else {
                log.error("[支付分集成] 支付分完结失败 - orderId: {}, errorCode: {}, errorMsg: {}", 
                        orderId, result.getErrorCode(), result.getErrorMsg());
                return false;
            }
        } catch (Exception e) {
            log.error("[支付分集成] 支付分完结异常 - orderId: {}", orderId, e);
            return false;
        }
    }
}
