package com.haha.service.impl;

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.enums.ReplenishmentOrderStatusEnum;
import com.haha.common.exception.BusinessException;
import com.haha.entity.ReplenishmentOrder;
import com.haha.entity.ReplenishmentOrderItem;
import com.haha.entity.dto.ReplenishmentOrderCreateDTO;
import com.haha.entity.dto.ReplenishmentOrderQueryDTO;
import com.haha.entity.dto.ReplenishmentOrderUpdateDTO;
import com.haha.mapper.ReplenishmentOrderItemMapper;
import com.haha.mapper.ReplenishmentOrderMapper;
import com.haha.service.ReplenishmentOrderService;
// TODO: 企得宝 ERP SDK - 暂未对接，后续接入时取消注释
// import com.qdb.sdk.QdbClient;
// import com.qdb.sdk.model.request.OrderGoods;
// import com.qdb.sdk.model.request.OrderSaveRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * 补货单服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ReplenishmentOrderServiceImpl extends ServiceImpl<ReplenishmentOrderMapper, ReplenishmentOrder>
        implements ReplenishmentOrderService {

    private final ReplenishmentOrderMapper orderMapper;
    private final ReplenishmentOrderItemMapper orderItemMapper;

    // TODO: 企得宝 ERP SDK - 暂未对接，后续接入时取消注释
    // @Autowired(required = false)
    // private QdbClient qdbClient;

    @Override
    public IPage<ReplenishmentOrder> getPage(ReplenishmentOrderQueryDTO queryDTO) {
        queryDTO.validate();

        LambdaQueryWrapper<ReplenishmentOrder> wrapper = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(queryDTO.getOrderNo())) {
            wrapper.like(ReplenishmentOrder::getOrderNo, queryDTO.getOrderNo());
        }
        if (StringUtils.hasText(queryDTO.getDeviceId())) {
            wrapper.eq(ReplenishmentOrder::getDeviceId, queryDTO.getDeviceId());
        }
        if (queryDTO.getShopId() != null) {
            wrapper.eq(ReplenishmentOrder::getShopId, queryDTO.getShopId());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(ReplenishmentOrder::getStatus, queryDTO.getStatus());
        }
        if (queryDTO.getCreatorId() != null) {
            wrapper.eq(ReplenishmentOrder::getCreatorId, queryDTO.getCreatorId());
        }
        if (StringUtils.hasText(queryDTO.getStartTime())) {
            wrapper.ge(ReplenishmentOrder::getCreateTime,
                    LocalDate.parse(queryDTO.getStartTime()).atStartOfDay());
        }
        if (StringUtils.hasText(queryDTO.getEndTime())) {
            wrapper.le(ReplenishmentOrder::getCreateTime,
                    LocalDate.parse(queryDTO.getEndTime()).atTime(23, 59, 59));
        }

        wrapper.orderByDesc(ReplenishmentOrder::getCreateTime);

        Page<ReplenishmentOrder> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        IPage<ReplenishmentOrder> result = page(page, wrapper);

        for (ReplenishmentOrder order : result.getRecords()) {
            fillStatusLabel(order);
            int count = orderItemMapper.selectByOrderId(order.getId()).size();
            order.setItemCount(count);
        }

        return result;
    }

    @Override
    public ReplenishmentOrder getDetailWithItems(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        fillStatusLabel(order);
        return order;
    }

    @Override
    public List<ReplenishmentOrderItem> getItems(Long orderId) {
        return orderItemMapper.selectByOrderId(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder createOrder(ReplenishmentOrderCreateDTO dto, Long creatorId, String creatorName) {
        ReplenishmentOrder order = new ReplenishmentOrder();
        order.setOrderNo(generateOrderNo());
        order.setDeviceId(dto.getDeviceId());
        order.setShopId(dto.getShopId());
        order.setStatus(ReplenishmentOrderStatusEnum.DRAFT.getCode());
        order.setSupplierName(dto.getSupplierName());
        order.setWarehouseName(dto.getWarehouseName());
        order.setExpectedArrivalTime(dto.getExpectedArrivalTime());
        order.setRemark(dto.getRemark());
        order.setCreatorId(creatorId);
        order.setCreatorName(creatorName);
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());

        int totalQuantity = 0;
        BigDecimal totalAmount = BigDecimal.ZERO;
        List<ReplenishmentOrderItem> items = new ArrayList<>();

        for (ReplenishmentOrderCreateDTO.ReplenishmentOrderItemDTO itemDto : dto.getItems()) {
            ReplenishmentOrderItem item = new ReplenishmentOrderItem();
            item.setDeviceId(dto.getDeviceId());
            item.setProductId(itemDto.getProductId());
            item.setProductCode(itemDto.getProductCode());
            item.setProductName(itemDto.getProductName());
            item.setPlannedQuantity(itemDto.getPlannedQuantity());
            item.setUnitPrice(itemDto.getUnitPrice());
            item.setShelfNum(itemDto.getShelfNum());
            item.setPosition(itemDto.getPosition());

            if (itemDto.getUnitPrice() != null) {
                BigDecimal itemTotal = itemDto.getUnitPrice()
                        .multiply(BigDecimal.valueOf(itemDto.getPlannedQuantity()));
                item.setTotalPrice(itemTotal);
                totalAmount = totalAmount.add(itemTotal);
            }
            totalQuantity += itemDto.getPlannedQuantity();
            items.add(item);
        }

        order.setTotalQuantity(totalQuantity);
        order.setTotalAmount(totalAmount);

        save(order);

        for (ReplenishmentOrderItem item : items) {
            item.setOrderId(order.getId());
            item.setCreateTime(LocalDateTime.now());
            orderItemMapper.insert(item);
        }

        log.info("创建补货单: orderNo={}, deviceId={}, items={}", order.getOrderNo(), dto.getDeviceId(), items.size());

        fillStatusLabel(order);
        order.setItemCount(items.size());
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder updateOrder(ReplenishmentOrderUpdateDTO dto) {
        ReplenishmentOrder order = getById(dto.getId());
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可编辑");
        }

        if (dto.getSupplierName() != null) {
            order.setSupplierName(dto.getSupplierName());
        }
        if (dto.getWarehouseName() != null) {
            order.setWarehouseName(dto.getWarehouseName());
        }
        if (dto.getExpectedArrivalTime() != null) {
            order.setExpectedArrivalTime(dto.getExpectedArrivalTime());
        }
        if (dto.getRemark() != null) {
            order.setRemark(dto.getRemark());
        }
        order.setUpdateTime(LocalDateTime.now());

        if (dto.getItems() != null && !dto.getItems().isEmpty()) {
            orderItemMapper.deleteByOrderId(dto.getId());

            int totalQuantity = 0;
            BigDecimal totalAmount = BigDecimal.ZERO;

            for (ReplenishmentOrderCreateDTO.ReplenishmentOrderItemDTO itemDto : dto.getItems()) {
                ReplenishmentOrderItem item = new ReplenishmentOrderItem();
                item.setOrderId(dto.getId());
                item.setDeviceId(order.getDeviceId());
                item.setProductId(itemDto.getProductId());
                item.setProductCode(itemDto.getProductCode());
                item.setProductName(itemDto.getProductName());
                item.setPlannedQuantity(itemDto.getPlannedQuantity());
                item.setUnitPrice(itemDto.getUnitPrice());
                item.setShelfNum(itemDto.getShelfNum());
                item.setPosition(itemDto.getPosition());

                if (itemDto.getUnitPrice() != null) {
                    BigDecimal itemTotal = itemDto.getUnitPrice()
                            .multiply(BigDecimal.valueOf(itemDto.getPlannedQuantity()));
                    item.setTotalPrice(itemTotal);
                    totalAmount = totalAmount.add(itemTotal);
                }
                totalQuantity += itemDto.getPlannedQuantity();
                item.setCreateTime(LocalDateTime.now());
                orderItemMapper.insert(item);
            }

            order.setTotalQuantity(totalQuantity);
            order.setTotalAmount(totalAmount);
        }

        updateById(order);

        log.info("更新补货单: id={}, orderNo={}", dto.getId(), order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可删除");
        }

        orderItemMapper.deleteByOrderId(id);
        removeById(id);

        log.info("删除补货单: id={}, orderNo={}", id, order.getOrderNo());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder submitOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.DRAFT.getCode()) {
            throw new BusinessException(400, "仅草稿状态的补货单可提交");
        }

        order.setStatus(ReplenishmentOrderStatusEnum.SUBMITTED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("提交补货单: id={}, orderNo={}", id, order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder syncToErp(Long id) {
        // TODO: 企得宝 ERP SDK - 暂未对接，后续接入时实现
        log.warn("syncToErp 暂未实现: id={}", id);
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder completeOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        if (order.getStatus() != ReplenishmentOrderStatusEnum.SYNCED_TO_ERP.getCode()) {
            throw new BusinessException(400, "仅已同步ERP的补货单可完成");
        }

        order.setStatus(ReplenishmentOrderStatusEnum.COMPLETED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("完成补货单: id={}, orderNo={}", id, order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReplenishmentOrder cancelOrder(Long id) {
        ReplenishmentOrder order = getById(id);
        if (order == null) {
            throw new BusinessException(404, "补货单不存在");
        }
        int status = order.getStatus();
        if (status != ReplenishmentOrderStatusEnum.DRAFT.getCode()
                && status != ReplenishmentOrderStatusEnum.SUBMITTED.getCode()) {
            throw new BusinessException(400, "仅草稿或已提交状态的补货单可取消");
        }

        order.setStatus(ReplenishmentOrderStatusEnum.CANCELLED.getCode());
        order.setUpdateTime(LocalDateTime.now());
        updateById(order);

        log.info("取消补货单: id={}, orderNo={}", id, order.getOrderNo());

        fillStatusLabel(order);
        return order;
    }

    /**
     * 生成补货单号：RO + yyyyMMdd + 4位序号
     */
    private String generateOrderNo() {
        String datePrefix = "RO" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String maxNo = orderMapper.selectMaxOrderNoToday();
        int seq = 1;
        if (maxNo != null && maxNo.startsWith(datePrefix)) {
            try {
                seq = Integer.parseInt(maxNo.substring(maxNo.length() - 4)) + 1;
            } catch (NumberFormatException e) {
                log.warn("解析补货单号失败: {}", maxNo);
            }
        }
        return datePrefix + String.format("%04d", seq);
    }

    private void fillStatusLabel(ReplenishmentOrder order) {
        if (order.getStatus() != null) {
            var statusEnum = ReplenishmentOrderStatusEnum.getLabelByCode(order.getStatus());
            order.setStatusLabel(statusEnum.getLabel());
            order.setStatusColor(statusEnum.getColor());
        }
    }
}
