package com.erp.tenant.service.order.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.erp.tenant.dto.order.OrderDetailResponse;
import com.erp.tenant.dto.order.OrderDetailResponse.*;
import com.erp.tenant.entity.order.Order;
import com.erp.tenant.entity.order.OrderItem;
import com.erp.tenant.repository.order.OrderRepository;
import com.erp.tenant.repository.order.OrderItemRepository;
import com.erp.tenant.service.order.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 租户端订单服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final OrderRepository orderRepository;
    private final OrderItemRepository orderItemRepository;

    private static final DateTimeFormatter DT_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    public IPage<Order> getOrderPage(Long tenantId, String platform, String erpStatus,
                                     Long warehouseId, String keyword,
                                     String startDate, String endDate,
                                     int page, int pageSize) {
        return orderRepository.findPage(
                new Page<>(page, pageSize),
                tenantId, platform, erpStatus, warehouseId, keyword, startDate, endDate
        );
    }

    @Override
    public OrderDetailResponse getOrderDetail(Long tenantId, Long orderId) {
        Order order = orderRepository.findById(orderId, tenantId);
        if (order == null) {
            return null;
        }

        List<OrderItem> items = orderItemRepository.findByOrderId(orderId);

        OrderDTO orderDTO = OrderDTO.builder()
                .id(order.getId())
                .orderSn(order.getOrderSn())
                .platformOrderSn(order.getPlatformOrderSn())
                .platform(order.getPlatform())
                .shopName(order.getShopName())
                .erpStatus(order.getErpStatus())
                .erpStatusText(order.getErpStatusText())
                .orderStatus(order.getOrderStatus())
                .deliveryStatus(order.getDeliveryStatus())
                .receiverName(order.getReceiverName())
                .receiverPhone(order.getReceiverPhone())
                .receiverProvince(order.getReceiverProvince())
                .receiverCity(order.getReceiverCity())
                .receiverDistrict(order.getReceiverDistrict())
                .receiverAddress(order.getReceiverAddress())
                .warehouseId(order.getWarehouseId())
                .warehouseName(order.getWarehouseName())
                .logisticsCompany(order.getLogisticsCompany())
                .logisticsNo(order.getLogisticsNo())
                .totalAmount(order.getTotalAmount())
                .goodsAmount(order.getGoodsAmount())
                .freight(order.getFreight())
                .discountAmount(order.getDiscountAmount())
                .paymentTime(order.getPaymentTime() != null ? order.getPaymentTime().format(DT_FORMAT) : null)
                .shippedAt(order.getShippedAt() != null ? order.getShippedAt().format(DT_FORMAT) : null)
                .approvedAt(order.getApprovedAt() != null ? order.getApprovedAt().format(DT_FORMAT) : null)
                .rejectedAt(order.getRejectedAt() != null ? order.getRejectedAt().format(DT_FORMAT) : null)
                .rejectReason(order.getRejectReason())
                .remark(order.getRemark())
                .adminRemark(order.getAdminRemark())
                .createdAt(order.getCreatedAt() != null ? order.getCreatedAt().format(DT_FORMAT) : null)
                .updatedAt(order.getUpdatedAt() != null ? order.getUpdatedAt().format(DT_FORMAT) : null)
                .items(items.stream().map(this::toOrderItemDTO).collect(Collectors.toList()))
                .freezeRecords(Collections.emptyList()) // TODO: freeze records
                .logs(Collections.emptyList()) // TODO: logs
                .tracking(Collections.emptyList()) // TODO: tracking
                .build();

        return OrderDetailResponse.builder().order(orderDTO).build();
    }

    @Override
    @Transactional
    public boolean approveOrder(Long tenantId, Long orderId, Long operatorId) {
        Order order = orderRepository.findById(orderId, tenantId);
        if (order == null) {
            return false;
        }
        if (!Order.ERP_STATUS_PENDING.equals(order.getErpStatus())) {
            log.warn("订单状态不允许审核: orderId={}, status={}", orderId, order.getErpStatus());
            return false;
        }
        int rows = orderRepository.approveOrder(orderId, tenantId, operatorId);
        return rows > 0;
    }

    @Override
    @Transactional
    public boolean rejectOrder(Long tenantId, Long orderId, Long operatorId, String reason) {
        Order order = orderRepository.findById(orderId, tenantId);
        if (order == null) {
            return false;
        }
        String currentStatus = order.getErpStatus();
        if (!Order.ERP_STATUS_PENDING.equals(currentStatus) && !Order.ERP_STATUS_APPROVED.equals(currentStatus)) {
            log.warn("订单状态不允许驳回: orderId={}, status={}", orderId, currentStatus);
            return false;
        }
        int rows = orderRepository.rejectOrder(orderId, tenantId, operatorId, reason);
        return rows > 0;
    }

    @Override
    @Transactional
    public boolean pushToWarehouse(Long tenantId, Long orderId) {
        Order order = orderRepository.findById(orderId, tenantId);
        if (order == null || !Order.ERP_STATUS_APPROVED.equals(order.getErpStatus())) {
            return false;
        }
        // TODO: call cloud WMS and update status
        orderRepository.updateErpStatus(orderId, tenantId, Order.ERP_STATUS_SHIPPED);
        return true;
    }

    @Override
    public String maskPhone(String phone) {
        if (phone == null || phone.length() != 11) {
            return phone;
        }
        return phone.substring(0, 3) + "****" + phone.substring(7);
    }

    private OrderItemDTO toOrderItemDTO(OrderItem item) {
        return OrderItemDTO.builder()
                .id(item.getId())
                .skuCode(item.getErpSku())
                .goodsName(item.getGoodsName())
                .spec(item.getSpec())
                .quantity(item.getQuantity())
                .price(item.getPrice())
                .subtotal(item.getSubtotal())
                .build();
    }
}
