package com.maternalmall.service;

import com.maternalmall.common.BizException;
import com.maternalmall.domain.*;
import com.maternalmall.repository.*;
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 MallService {
    private final ProductRepository productRepository;
    private final CartItemRepository cartItemRepository;
    private final FavoriteRepository favoriteRepository;
    private final OrdersRepository ordersRepository;
    private final OrderItemRepository orderItemRepository;
    private final ReviewRepository reviewRepository;
    private final LogisticsRecordRepository logisticsRecordRepository;
    private final InventoryRecordRepository inventoryRecordRepository;
    private final MerchantApplicationRepository merchantApplicationRepository;
    private final BannerRepository bannerRepository;
    private final UserRepository userRepository;

    public MallService(ProductRepository productRepository,
                       CartItemRepository cartItemRepository,
                       FavoriteRepository favoriteRepository,
                       OrdersRepository ordersRepository,
                       OrderItemRepository orderItemRepository,
                       ReviewRepository reviewRepository,
                       LogisticsRecordRepository logisticsRecordRepository,
                       InventoryRecordRepository inventoryRecordRepository,
                       MerchantApplicationRepository merchantApplicationRepository,
                       BannerRepository bannerRepository,
                       UserRepository userRepository) {
        this.productRepository = productRepository;
        this.cartItemRepository = cartItemRepository;
        this.favoriteRepository = favoriteRepository;
        this.ordersRepository = ordersRepository;
        this.orderItemRepository = orderItemRepository;
        this.reviewRepository = reviewRepository;
        this.logisticsRecordRepository = logisticsRecordRepository;
        this.inventoryRecordRepository = inventoryRecordRepository;
        this.merchantApplicationRepository = merchantApplicationRepository;
        this.bannerRepository = bannerRepository;
        this.userRepository = userRepository;
    }

    public void requireRole(User user, UserRole role) {
        if (user.getRole() != role) {
            throw new BizException("无权限操作");
        }
    }

    public List<Product> searchProducts(String keyword) {
        return productRepository.findByApprovedTrueAndNameContainingIgnoreCase(keyword == null ? "" : keyword);
    }

    public Product getProduct(Long id) {
        return productRepository.findById(id).orElseThrow(() -> new BizException("商品不存在"));
    }

    public List<Banner> banners() {
        return bannerRepository.findByEnabledTrueOrderBySortNoAsc();
    }

    public List<CartItem> cartList(Long customerId) {
        return cartItemRepository.findByCustomerId(customerId);
    }

    public List<Map<String, Object>> cartViews(Long customerId) {
        List<CartItem> items = cartItemRepository.findByCustomerId(customerId);
        List<Map<String, Object>> views = new ArrayList<>();
        for (CartItem item : items) {
            Product p = getProduct(item.getProductId());
            Map<String, Object> row = new HashMap<>();
            row.put("productId", p.getId());
            row.put("productName", p.getName());
            row.put("category", p.getCategory());
            row.put("imageUrl", p.getImageUrl());
            row.put("unitPrice", p.getPrice());
            row.put("quantity", item.getQuantity());
            row.put("subtotal", p.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
            row.put("stock", p.getStock());
            views.add(row);
        }
        return views;
    }

    public CartItem addCart(Long customerId, Long productId, Integer quantity) {
        Product product = getProduct(productId);
        if (!product.getApproved()) {
            throw new BizException("商品未上架");
        }
        CartItem item = cartItemRepository.findByCustomerIdAndProductId(customerId, productId).orElseGet(CartItem::new);
        item.setCustomerId(customerId);
        item.setProductId(productId);
        item.setQuantity((item.getQuantity() == null ? 0 : item.getQuantity()) + quantity);
        return cartItemRepository.save(item);
    }

    public void removeCart(Long customerId, Long productId) {
        cartItemRepository.deleteByCustomerIdAndProductId(customerId, productId);
    }

    public List<Favorite> favoriteList(Long customerId) {
        return favoriteRepository.findByCustomerId(customerId);
    }

    public List<Map<String, Object>> favoriteViews(Long customerId) {
        List<Favorite> favorites = favoriteRepository.findByCustomerId(customerId);
        List<Map<String, Object>> views = new ArrayList<>();
        for (Favorite favorite : favorites) {
            Product p = getProduct(favorite.getProductId());
            Map<String, Object> row = new HashMap<>();
            row.put("productId", p.getId());
            row.put("productName", p.getName());
            row.put("category", p.getCategory());
            row.put("imageUrl", p.getImageUrl());
            row.put("unitPrice", p.getPrice());
            row.put("stock", p.getStock());
            views.add(row);
        }
        return views;
    }

    public Favorite addFavorite(Long customerId, Long productId) {
        favoriteRepository.findByCustomerIdAndProductId(customerId, productId).ifPresent(f -> {
            throw new BizException("已收藏");
        });
        Favorite favorite = new Favorite();
        favorite.setCustomerId(customerId);
        favorite.setProductId(productId);
        return favoriteRepository.save(favorite);
    }

    public void removeFavorite(Long customerId, Long productId) {
        favoriteRepository.deleteByCustomerIdAndProductId(customerId, productId);
    }

    @Transactional
    public Orders checkout(Long customerId, String address) {
        List<CartItem> cartItems = cartItemRepository.findByCustomerId(customerId);
        if (cartItems.isEmpty()) {
            throw new BizException("购物车为空");
        }
        Long merchantId = null;
        BigDecimal total = BigDecimal.ZERO;
        Orders order = new Orders();
        order.setOrderNo("MM" + System.currentTimeMillis());
        order.setCustomerId(customerId);
        order.setStatus(OrderStatus.PAID);
        order.setAddress(address);

        for (CartItem cartItem : cartItems) {
            Product product = getProduct(cartItem.getProductId());
            if (product.getStock() < cartItem.getQuantity()) {
                throw new BizException("库存不足: " + product.getName());
            }
            if (merchantId == null) {
                merchantId = product.getMerchantId();
            } else if (!merchantId.equals(product.getMerchantId())) {
                throw new BizException("当前基础版本仅支持单商家结算");
            }
            product.setStock(product.getStock() - cartItem.getQuantity());
            productRepository.save(product);

            InventoryRecord record = new InventoryRecord();
            record.setMerchantId(product.getMerchantId());
            record.setProductId(product.getId());
            record.setChangeQty(-cartItem.getQuantity());
            record.setNote("订单扣减库存");
            inventoryRecordRepository.save(record);

            BigDecimal line = product.getPrice().multiply(BigDecimal.valueOf(cartItem.getQuantity()));
            total = total.add(line);
        }
        order.setMerchantId(merchantId);
        order.setTotalAmount(total);
        ordersRepository.save(order);

        for (CartItem cartItem : cartItems) {
            Product product = getProduct(cartItem.getProductId());
            OrderItem item = new OrderItem();
            item.setOrderId(order.getId());
            item.setProductId(product.getId());
            item.setProductName(product.getName());
            item.setQuantity(cartItem.getQuantity());
            item.setUnitPrice(product.getPrice());
            item.setProductImage(product.getImageUrl());
            orderItemRepository.save(item);
        }
        cartItemRepository.deleteByCustomerId(customerId);
        return order;
    }

    @Transactional
    public Orders buyNow(Long customerId, Long productId, Integer quantity, String address) {
        if (quantity == null || quantity <= 0) {
            throw new BizException("购买数量必须大于0");
        }
        Product product = getProduct(productId);
        if (!Boolean.TRUE.equals(product.getApproved())) {
            throw new BizException("商品未上架");
        }
        if (product.getStock() < quantity) {
            throw new BizException("库存不足: " + product.getName());
        }

        product.setStock(product.getStock() - quantity);
        productRepository.save(product);

        InventoryRecord record = new InventoryRecord();
        record.setMerchantId(product.getMerchantId());
        record.setProductId(product.getId());
        record.setChangeQty(-quantity);
        record.setNote("立即购买扣减库存");
        inventoryRecordRepository.save(record);

        Orders order = new Orders();
        order.setOrderNo("MM" + System.currentTimeMillis());
        order.setCustomerId(customerId);
        order.setMerchantId(product.getMerchantId());
        order.setStatus(OrderStatus.PAID);
        order.setAddress(address);
        order.setTotalAmount(product.getPrice().multiply(BigDecimal.valueOf(quantity)));
        ordersRepository.save(order);

        OrderItem item = new OrderItem();
        item.setOrderId(order.getId());
        item.setProductId(product.getId());
        item.setProductName(product.getName());
        item.setQuantity(quantity);
        item.setUnitPrice(product.getPrice());
        item.setProductImage(product.getImageUrl());
        orderItemRepository.save(item);

        return order;
    }

    public List<Orders> customerOrders(Long customerId) {
        return ordersRepository.findByCustomerId(customerId);
    }

    public List<OrderItem> customerOrderItems(Long customerId, Long orderId) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        return orderItemRepository.findByOrderId(orderId);
    }

    public Orders customerUpdateAddress(Long customerId, Long orderId, String address) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        if (order.getStatus() == OrderStatus.SHIPPED || order.getStatus() == OrderStatus.COMPLETED) {
            throw new BizException("该状态不可修改地址");
        }
        order.setAddress(address);
        return ordersRepository.save(order);
    }

    public Orders customerRefund(Long customerId, Long orderId, String reason) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        order.setStatus(OrderStatus.REFUND_REQUESTED);
        order.setRefundReason(reason);
        return ordersRepository.save(order);
    }

    public void customerDeleteOrder(Long customerId, Long orderId) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        if (!(order.getStatus() == OrderStatus.COMPLETED || order.getStatus() == OrderStatus.REFUNDED || order.getStatus() == OrderStatus.CANCELLED)) {
            throw new BizException("当前状态不可删除");
        }
        ordersRepository.delete(order);
    }

    public List<LogisticsRecord> logisticsOfOrder(Long customerId, Long orderId) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        return logisticsRecordRepository.findByOrderId(orderId);
    }

    public Review addReview(Long customerId, Long orderId, Long productId, Integer rating, String content) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getCustomerId().equals(customerId)) {
            throw new BizException("无权限操作");
        }
        if (rating == null || rating < 1 || rating > 5) {
            throw new BizException("评分范围为1-5分");
        }
        if (!(order.getStatus() == OrderStatus.PAID
                || order.getStatus() == OrderStatus.SHIPPED
                || order.getStatus() == OrderStatus.COMPLETED
                || order.getStatus() == OrderStatus.REFUND_REQUESTED
                || order.getStatus() == OrderStatus.REFUNDED)) {
            throw new BizException("仅已购买商品可评价");
        }
        boolean ordered = orderItemRepository.findByOrderId(orderId)
                .stream()
                .anyMatch(i -> i.getProductId().equals(productId));
        if (!ordered) {
            throw new BizException("该商品不在订单内");
        }
        if (reviewRepository.existsByOrderIdAndProductIdAndCustomerId(orderId, productId, customerId)) {
            throw new BizException("该商品已评价");
        }
        Review review = new Review();
        review.setOrderId(orderId);
        review.setProductId(productId);
        review.setCustomerId(customerId);
        review.setRating(rating);
        review.setContent(content);
        return reviewRepository.save(review);
    }

    public Map<String, Object> merchantOverview(Long merchantId) {
        List<Orders> orders = ordersRepository.findByMerchantId(merchantId);
        BigDecimal sales = orders.stream()
                .filter(o -> o.getStatus() == OrderStatus.PAID || o.getStatus() == OrderStatus.SHIPPED || o.getStatus() == OrderStatus.COMPLETED)
                .map(Orders::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        Map<Long, Integer> hotMap = new HashMap<>();
        Map<String, Long> categoryCount = new HashMap<>();
        for (Orders order : orders) {
            for (OrderItem item : orderItemRepository.findByOrderId(order.getId())) {
                hotMap.put(item.getProductId(), hotMap.getOrDefault(item.getProductId(), 0) + item.getQuantity());
            }
        }
        for (Product p : productRepository.findByMerchantId(merchantId)) {
            String category = p.getCategory() == null ? "未分类" : p.getCategory();
            categoryCount.put(category, categoryCount.getOrDefault(category, 0L) + 1);
        }
        return Map.of(
                "orderCount", orders.size(),
                "salesAmount", sales,
                "hotProducts", hotMap,
                "categoryRatio", categoryCount,
                "notifications", List.of("请及时处理退款申请", "注意库存预警")
        );
    }

    public Product merchantSaveProduct(Long merchantId, Product body) {
        Product product = body;
        if (product.getId() != null) {
            Product old = productRepository.findById(product.getId()).orElseThrow(() -> new BizException("商品不存在"));
            if (!old.getMerchantId().equals(merchantId)) {
                throw new BizException("无权限操作");
            }
        }
        product.setMerchantId(merchantId);
        if (product.getApproved() == null) {
            product.setApproved(false);
        }
        Product saved = productRepository.save(product);
        InventoryRecord record = new InventoryRecord();
        record.setMerchantId(merchantId);
        record.setProductId(saved.getId());
        record.setChangeQty(saved.getStock());
        record.setNote("商品上架或更新库存");
        inventoryRecordRepository.save(record);
        return saved;
    }

    public List<Product> merchantProducts(Long merchantId) {
        return productRepository.findByMerchantId(merchantId);
    }

    public void merchantDeleteProduct(Long merchantId, Long productId) {
        Product product = getProduct(productId);
        if (!product.getMerchantId().equals(merchantId)) {
            throw new BizException("无权限操作");
        }
        productRepository.delete(product);
    }

    public List<Orders> merchantOrders(Long merchantId) {
        return ordersRepository.findByMerchantId(merchantId);
    }

    public Orders merchantShip(Long merchantId, Long orderId, String note) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getMerchantId().equals(merchantId)) {
            throw new BizException("无权限操作");
        }
        order.setStatus(OrderStatus.SHIPPED);
        order.setLogisticsInfo(note);
        ordersRepository.save(order);

        LogisticsRecord record = new LogisticsRecord();
        record.setOrderId(orderId);
        record.setMerchantId(merchantId);
        record.setStatus("SHIPPED");
        record.setNote(note);
        logisticsRecordRepository.save(record);
        return order;
    }

    public Orders merchantProcessRefund(Long merchantId, Long orderId, boolean agree) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (!order.getMerchantId().equals(merchantId)) {
            throw new BizException("无权限操作");
        }
        if (order.getStatus() != OrderStatus.REFUND_REQUESTED) {
            throw new BizException("仅退款申请中的订单可处理");
        }
        order.setStatus(agree ? OrderStatus.REFUNDED : OrderStatus.PAID);
        return ordersRepository.save(order);
    }

    public List<Map<String, Object>> merchantReviews(Long merchantId) {
        List<Product> products = productRepository.findByMerchantId(merchantId);
        Set<Long> productIds = new HashSet<>();
        for (Product product : products) {
            productIds.add(product.getId());
        }
        List<Review> reviews = reviewRepository.findAll();
        Map<Long, Orders> orderMap = new HashMap<>();
        for (Orders order : ordersRepository.findAll()) {
            orderMap.put(order.getId(), order);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (Review r : reviews) {
            if (!productIds.contains(r.getProductId())) continue;
            Orders order = orderMap.get(r.getOrderId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", r.getId());
            row.put("orderId", r.getOrderId());
            row.put("orderNo", order == null ? "" : order.getOrderNo());
            row.put("productId", r.getProductId());
            row.put("productName", products.stream().filter(p -> p.getId().equals(r.getProductId())).findFirst().map(Product::getName).orElse(""));
            row.put("rating", r.getRating());
            row.put("content", r.getContent());
            row.put("createdAt", r.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public List<Map<String, Object>> merchantLogistics(Long merchantId) {
        List<LogisticsRecord> records = logisticsRecordRepository.findByMerchantId(merchantId);
        Map<Long, Orders> orderMap = new HashMap<>();
        for (Orders order : ordersRepository.findAll()) {
            orderMap.put(order.getId(), order);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (LogisticsRecord rec : records) {
            Orders order = orderMap.get(rec.getOrderId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", rec.getId());
            row.put("orderId", rec.getOrderId());
            row.put("orderNo", order == null ? "" : order.getOrderNo());
            row.put("status", rec.getStatus());
            row.put("note", rec.getNote());
            row.put("createdAt", rec.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public List<Map<String, Object>> merchantInventory(Long merchantId) {
        List<InventoryRecord> records = inventoryRecordRepository.findByMerchantId(merchantId);
        Map<Long, Product> productMap = new HashMap<>();
        for (Product product : productRepository.findByMerchantId(merchantId)) {
            productMap.put(product.getId(), product);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (InventoryRecord rec : records) {
            Product product = productMap.get(rec.getProductId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", rec.getId());
            row.put("productId", rec.getProductId());
            row.put("productName", product == null ? "" : product.getName());
            row.put("changeQty", rec.getChangeQty());
            row.put("note", rec.getNote());
            row.put("createdAt", rec.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public void merchantDeleteInventory(Long merchantId, Long id) {
        InventoryRecord rec = inventoryRecordRepository.findById(id).orElseThrow(() -> new BizException("记录不存在"));
        if (!rec.getMerchantId().equals(merchantId)) {
            throw new BizException("无权限操作");
        }
        inventoryRecordRepository.delete(rec);
    }

    public MerchantApplication applyMerchant(Long userId, String qualification) {
        User user = userRepository.findById(userId).orElseThrow(() -> new BizException("用户不存在"));
        if (user.getRole() != UserRole.CUSTOMER) {
            throw new BizException("仅顾客账号可提交入驻申请");
        }
        if (merchantApplicationRepository.existsByUserIdAndStatus(userId, "PENDING")) {
            throw new BizException("已有待审核申请，请勿重复提交");
        }
        MerchantApplication m = new MerchantApplication();
        m.setUserId(userId);
        m.setQualification(qualification);
        m.setStatus("PENDING");
        return merchantApplicationRepository.save(m);
    }

    public Map<String, Object> adminOverview() {
        List<Orders> orders = ordersRepository.findAll();
        BigDecimal sales = orders.stream().map(Orders::getTotalAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        Map<String, Long> categoryCount = new HashMap<>();
        Map<Long, Integer> hotMap = new HashMap<>();
        for (Product p : productRepository.findAll()) {
            String category = p.getCategory() == null ? "未分类" : p.getCategory();
            categoryCount.put(category, categoryCount.getOrDefault(category, 0L) + 1);
        }
        for (Orders order : orders) {
            for (OrderItem item : orderItemRepository.findByOrderId(order.getId())) {
                hotMap.put(item.getProductId(), hotMap.getOrDefault(item.getProductId(), 0) + item.getQuantity());
            }
        }
        return Map.of(
                "orderCount", orders.size(),
                "salesAmount", sales,
                "categoryRatio", categoryCount,
                "hotProducts", hotMap
        );
    }

    public List<Orders> adminOrders() {
        return ordersRepository.findAll();
    }

    public Orders adminUpdateOrder(Long orderId, String status, String logisticsInfo) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        try {
            order.setStatus(OrderStatus.valueOf(status));
        } catch (IllegalArgumentException e) {
            throw new BizException("订单状态不合法");
        }
        order.setLogisticsInfo(logisticsInfo);
        return ordersRepository.save(order);
    }

    public List<Map<String, Object>> adminRiskOrders() {
        List<Orders> orders = ordersRepository.findAll();
        List<Map<String, Object>> risks = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        for (Orders order : orders) {
            if (order.getTotalAmount().compareTo(new BigDecimal("5000")) >= 0) {
                risks.add(buildRisk(order, "HIGH_AMOUNT", "订单金额较高，请人工核查"));
            }
            if (order.getStatus() == OrderStatus.PAID && order.getCreatedAt() != null && order.getCreatedAt().isBefore(now.minusDays(2))) {
                risks.add(buildRisk(order, "SHIP_DELAY", "已支付超过48小时未发货"));
            }
            if (order.getStatus() == OrderStatus.SHIPPED && logisticsRecordRepository.findByOrderId(order.getId()).isEmpty()) {
                risks.add(buildRisk(order, "NO_LOGISTICS", "订单标记已发货但无物流轨迹"));
            }
            if (order.getStatus() == OrderStatus.REFUND_REQUESTED) {
                risks.add(buildRisk(order, "REFUND_PENDING", "退款申请待审核"));
            }
        }
        return risks;
    }

    private Map<String, Object> buildRisk(Orders order, String type, String reason) {
        Map<String, Object> row = new HashMap<>();
        row.put("orderId", order.getId());
        row.put("orderNo", order.getOrderNo());
        row.put("status", order.getStatus());
        row.put("totalAmount", order.getTotalAmount());
        row.put("customerId", order.getCustomerId());
        row.put("merchantId", order.getMerchantId());
        row.put("riskType", type);
        row.put("riskReason", reason);
        return row;
    }

    public Orders adminAuditRefund(Long orderId, boolean approve, String remark) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (order.getStatus() != OrderStatus.REFUND_REQUESTED) {
            throw new BizException("当前订单不在退款审核状态");
        }
        order.setStatus(approve ? OrderStatus.REFUNDED : OrderStatus.PAID);
        if (remark != null && !remark.trim().isEmpty()) {
            String old = order.getRefundReason() == null ? "" : order.getRefundReason();
            String merged = old.isBlank() ? remark.trim() : old + "；管理员备注：" + remark.trim();
            order.setRefundReason(merged);
        }
        Orders saved = ordersRepository.save(order);

        LogisticsRecord record = new LogisticsRecord();
        record.setOrderId(orderId);
        record.setMerchantId(order.getMerchantId());
        record.setStatus(approve ? "REFUND_APPROVED" : "REFUND_REJECTED");
        record.setNote((approve ? "管理员通过退款审核" : "管理员驳回退款申请") + (remark == null || remark.trim().isEmpty() ? "" : ("：" + remark.trim())));
        logisticsRecordRepository.save(record);
        return saved;
    }

    public Orders adminAuditShipment(Long orderId, boolean approved, String remark) {
        Orders order = ordersRepository.findById(orderId).orElseThrow(() -> new BizException("订单不存在"));
        if (order.getStatus() != OrderStatus.SHIPPED && order.getStatus() != OrderStatus.PAID) {
            throw new BizException("仅已支付或已发货订单可审核发货");
        }
        if (approved && order.getStatus() == OrderStatus.PAID) {
            order.setStatus(OrderStatus.SHIPPED);
        }
        if (!approved && order.getStatus() == OrderStatus.SHIPPED) {
            order.setStatus(OrderStatus.PAID);
        }
        if (remark != null && !remark.trim().isEmpty()) {
            order.setLogisticsInfo(remark.trim());
        }
        Orders saved = ordersRepository.save(order);

        LogisticsRecord record = new LogisticsRecord();
        record.setOrderId(orderId);
        record.setMerchantId(order.getMerchantId());
        record.setStatus(approved ? "SHIP_AUDIT_PASS" : "SHIP_AUDIT_REJECT");
        record.setNote((approved ? "管理员发货审核通过" : "管理员发货审核驳回") + (remark == null || remark.trim().isEmpty() ? "" : ("：" + remark.trim())));
        logisticsRecordRepository.save(record);
        return saved;
    }

    public List<Map<String, Object>> adminMerchantApplications() {
        List<MerchantApplication> apps = merchantApplicationRepository.findAll();
        List<Map<String, Object>> views = new ArrayList<>();
        Map<Long, User> userMap = new HashMap<>();
        for (User user : userRepository.findAll()) {
            userMap.put(user.getId(), user);
        }
        for (MerchantApplication app : apps) {
            User applicant = userMap.get(app.getUserId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", app.getId());
            row.put("userId", app.getUserId());
            row.put("applicantUsername", applicant == null ? "" : applicant.getUsername());
            row.put("applicantNickname", applicant == null ? "" : applicant.getNickname());
            row.put("qualification", app.getQualification());
            row.put("status", app.getStatus());
            row.put("remark", app.getRemark());
            views.add(row);
        }
        return views;
    }

    public MerchantApplication adminAuditApplication(Long id, String status, String remark) {
        MerchantApplication app = merchantApplicationRepository.findById(id).orElseThrow(() -> new BizException("申请不存在"));
        app.setStatus(status);
        app.setRemark(remark);
        merchantApplicationRepository.save(app);

        if ("APPROVED".equals(status)) {
            User user = userRepository.findById(app.getUserId()).orElseThrow(() -> new BizException("用户不存在"));
            user.setRole(UserRole.MERCHANT);
            userRepository.save(user);
        }
        return app;
    }

    public List<User> adminUsers() {
        return userRepository.findAll();
    }

    public User adminSaveUser(User user) {
        String username = user.getUsername() == null ? "" : user.getUsername().trim();
        String password = user.getPassword() == null ? "" : user.getPassword().trim();
        if (username.isEmpty()) {
            throw new BizException("用户名不能为空");
        }
        if (password.isEmpty()) {
            throw new BizException("密码不能为空");
        }

        if (user.getId() == null) {
            userRepository.findByUsername(username).ifPresent(u -> {
                throw new BizException("账号已存在");
            });
        } else {
            User existing = userRepository.findById(user.getId()).orElseThrow(() -> new BizException("用户不存在"));
            userRepository.findByUsername(username).ifPresent(u -> {
                if (!u.getId().equals(existing.getId())) {
                    throw new BizException("账号已存在");
                }
            });
        }

        user.setUsername(username);
        user.setPassword(password);
        if (user.getRole() == null) {
            user.setRole(UserRole.CUSTOMER);
        }
        if (user.getNickname() == null || user.getNickname().trim().isEmpty()) {
            user.setNickname(username);
        }
        if (user.getEnabled() == null) {
            user.setEnabled(true);
        }
        return userRepository.save(user);
    }

    public void adminDeleteUser(Long id) {
        userRepository.deleteById(id);
    }

    public List<Banner> adminBanners() {
        return bannerRepository.findAll();
    }

    public Banner adminSaveBanner(Banner banner) {
        return bannerRepository.save(banner);
    }

    public void adminDeleteBanner(Long id) {
        bannerRepository.deleteById(id);
    }

    public List<Product> adminProducts() {
        return productRepository.findAll();
    }

    public List<Map<String, Object>> adminProductViews() {
        List<Product> products = productRepository.findAll();
        Map<Long, User> userMap = new HashMap<>();
        for (User user : userRepository.findAll()) {
            userMap.put(user.getId(), user);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (Product p : products) {
            User merchant = userMap.get(p.getMerchantId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", p.getId());
            row.put("name", p.getName());
            row.put("category", p.getCategory());
            row.put("description", p.getDescription());
            row.put("price", p.getPrice());
            row.put("stock", p.getStock());
            row.put("imageUrl", p.getImageUrl());
            row.put("merchantId", p.getMerchantId());
            row.put("merchantUsername", merchant == null ? "" : merchant.getUsername());
            row.put("merchantName", merchant == null ? "" : merchant.getNickname());
            row.put("approved", p.getApproved());
            row.put("createdAt", p.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public Product adminSaveProduct(Product input) {
        if (input.getName() == null || input.getName().trim().isEmpty()) {
            throw new BizException("商品名称不能为空");
        }
        if (input.getMerchantId() == null) {
            throw new BizException("商家ID不能为空");
        }
        if (input.getPrice() == null || input.getStock() == null) {
            throw new BizException("商品价格或库存不能为空");
        }
        Product product = input;
        if (input.getId() != null) {
            product = productRepository.findById(input.getId()).orElseThrow(() -> new BizException("商品不存在"));
            product.setName(input.getName());
            product.setCategory(input.getCategory());
            product.setDescription(input.getDescription());
            product.setPrice(input.getPrice());
            product.setStock(input.getStock());
            product.setImageUrl(input.getImageUrl());
            product.setMerchantId(input.getMerchantId());
            product.setApproved(Boolean.TRUE.equals(input.getApproved()));
        } else {
            if (product.getApproved() == null) {
                product.setApproved(false);
            }
        }
        return productRepository.save(product);
    }

    public Product adminApproveProduct(Long productId, boolean approved) {
        Product product = productRepository.findById(productId).orElseThrow(() -> new BizException("商品不存在"));
        product.setApproved(approved);
        return productRepository.save(product);
    }

    public void adminDeleteProduct(Long id) {
        productRepository.deleteById(id);
    }

    public List<Map<String, Object>> adminReviews() {
        List<Review> reviews = reviewRepository.findAll();
        Map<Long, User> userMap = new HashMap<>();
        for (User user : userRepository.findAll()) {
            userMap.put(user.getId(), user);
        }
        Map<Long, Orders> orderMap = new HashMap<>();
        for (Orders order : ordersRepository.findAll()) {
            orderMap.put(order.getId(), order);
        }
        Map<Long, Product> productMap = new HashMap<>();
        for (Product product : productRepository.findAll()) {
            productMap.put(product.getId(), product);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (Review r : reviews) {
            User customer = userMap.get(r.getCustomerId());
            Orders order = orderMap.get(r.getOrderId());
            Product product = productMap.get(r.getProductId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", r.getId());
            row.put("orderId", r.getOrderId());
            row.put("orderNo", order == null ? "" : order.getOrderNo());
            row.put("productId", r.getProductId());
            row.put("productName", product == null ? "" : product.getName());
            row.put("customerId", r.getCustomerId());
            row.put("customerUsername", customer == null ? "" : customer.getUsername());
            row.put("rating", r.getRating());
            row.put("content", r.getContent());
            row.put("createdAt", r.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public List<Map<String, Object>> adminLogistics() {
        List<LogisticsRecord> records = logisticsRecordRepository.findAll();
        Map<Long, User> userMap = new HashMap<>();
        for (User user : userRepository.findAll()) {
            userMap.put(user.getId(), user);
        }
        Map<Long, Orders> orderMap = new HashMap<>();
        for (Orders order : ordersRepository.findAll()) {
            orderMap.put(order.getId(), order);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (LogisticsRecord rec : records) {
            User merchant = userMap.get(rec.getMerchantId());
            Orders order = orderMap.get(rec.getOrderId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", rec.getId());
            row.put("orderId", rec.getOrderId());
            row.put("orderNo", order == null ? "" : order.getOrderNo());
            row.put("merchantId", rec.getMerchantId());
            row.put("merchantUsername", merchant == null ? "" : merchant.getUsername());
            row.put("status", rec.getStatus());
            row.put("note", rec.getNote());
            row.put("createdAt", rec.getCreatedAt());
            views.add(row);
        }
        return views;
    }

    public List<Map<String, Object>> adminInventory() {
        List<InventoryRecord> records = inventoryRecordRepository.findAll();
        Map<Long, User> userMap = new HashMap<>();
        for (User user : userRepository.findAll()) {
            userMap.put(user.getId(), user);
        }
        Map<Long, Product> productMap = new HashMap<>();
        for (Product product : productRepository.findAll()) {
            productMap.put(product.getId(), product);
        }
        List<Map<String, Object>> views = new ArrayList<>();
        for (InventoryRecord rec : records) {
            User merchant = userMap.get(rec.getMerchantId());
            Product product = productMap.get(rec.getProductId());
            Map<String, Object> row = new HashMap<>();
            row.put("id", rec.getId());
            row.put("productId", rec.getProductId());
            row.put("productName", product == null ? "" : product.getName());
            row.put("merchantId", rec.getMerchantId());
            row.put("merchantUsername", merchant == null ? "" : merchant.getUsername());
            row.put("changeQty", rec.getChangeQty());
            row.put("note", rec.getNote());
            row.put("createdAt", rec.getCreatedAt());
            views.add(row);
        }
        return views;
    }
}
