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.entity.Device;
import com.haha.entity.InventoryLog;
import com.haha.entity.dto.InventoryLogQueryDTO;
import com.haha.mapper.DeviceMapper;
import com.haha.mapper.InventoryLogMapper;
import com.haha.service.InventoryLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 库存变动日志服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InventoryLogServiceImpl extends ServiceImpl<InventoryLogMapper, InventoryLog>
        implements InventoryLogService {

    private final InventoryLogMapper inventoryLogMapper;

    private final DeviceMapper deviceMapper;

    @Override
    public IPage<InventoryLog> getPage(int page, int pageSize, InventoryLogQueryDTO queryDTO) {
        LambdaQueryWrapper<InventoryLog> wrapper = new LambdaQueryWrapper<>();

        // 设备ID筛选
        if (StringUtils.hasText(queryDTO.getDeviceId())) {
            wrapper.eq(InventoryLog::getDeviceId, queryDTO.getDeviceId());
        }

        // 商品编码筛选
        if (StringUtils.hasText(queryDTO.getProductCode())) {
            wrapper.eq(InventoryLog::getProductCode, queryDTO.getProductCode());
        }

        // 变动类型筛选
        if (queryDTO.getChangeType() != null) {
            wrapper.eq(InventoryLog::getChangeType, queryDTO.getChangeType());
        }

        // 订单号筛选
        if (StringUtils.hasText(queryDTO.getOrderId())) {
            wrapper.eq(InventoryLog::getOrderId, queryDTO.getOrderId());
        }

        // 时间范围
        if (StringUtils.hasText(queryDTO.getStartTime())) {
            wrapper.ge(InventoryLog::getCreateTime, LocalDateTime.parse(queryDTO.getStartTime() + "T00:00:00"));
        }
        if (StringUtils.hasText(queryDTO.getEndTime())) {
            wrapper.le(InventoryLog::getCreateTime, LocalDateTime.parse(queryDTO.getEndTime() + "T23:59:59"));
        }

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

        IPage<InventoryLog> result = page(new Page<>(page, pageSize), wrapper);
        fillDeviceNames(result.getRecords());
        return result;
    }

    private void fillDeviceNames(List<InventoryLog> records) {
        if (records == null || records.isEmpty()) return;
        List<String> ids = records.stream()
                .map(InventoryLog::getDeviceId)
                .filter(id -> id != null && !id.isEmpty())
                .distinct()
                .collect(java.util.stream.Collectors.toList());
        if (ids.isEmpty()) return;
        List<Device> devices = deviceMapper.selectList(
                new LambdaQueryWrapper<Device>().in(Device::getDeviceId, ids));
        if (devices == null) return;
        java.util.Map<String, String> nameMap = devices.stream()
                .collect(java.util.stream.Collectors.toMap(Device::getDeviceId, d -> d.getName() != null ? d.getName() : "", (a, b) -> a));
        for (InventoryLog r : records) {
            r.setDeviceName(nameMap.getOrDefault(r.getDeviceId(), ""));
        }
    }

    @Override
    public InventoryLog logChange(String deviceId, Long productId, String productCode, String productName,
                                  Integer changeType, Integer changeQuantity,
                                  Integer beforeStock, Integer afterStock,
                                  String orderId, String activityId,
                                  Long operatorId, String operatorName, String remark) {
        InventoryLog logRecord = new InventoryLog();
        logRecord.setDeviceId(deviceId);
        logRecord.setProductId(productId);
        logRecord.setProductCode(productCode);
        logRecord.setProductName(productName);
        logRecord.setChangeType(changeType);
        logRecord.setChangeQuantity(changeQuantity);
        logRecord.setBeforeStock(beforeStock);
        logRecord.setAfterStock(afterStock);
        logRecord.setOrderId(orderId);
        logRecord.setActivityId(activityId);
        logRecord.setOperatorId(operatorId);
        logRecord.setOperatorName(operatorName);
        logRecord.setRemark(remark);
        logRecord.setCreateTime(LocalDateTime.now());

        save(logRecord);

        log.info("库存变动日志: deviceId={}, productCode={}, type={}, quantity={}, before={}, after={}",
                deviceId, productCode, changeType, changeQuantity, beforeStock, afterStock);

        return logRecord;
    }

    @Override
    public List<Map<String, Object>> getChangeStatistics(String deviceId, String startTime, String endTime) {
        return inventoryLogMapper.selectChangeStatistics(deviceId, startTime, endTime);
    }

    @Override
    public List<Map<String, Object>> getByProductCode(String productCode, int limit) {
        return inventoryLogMapper.selectByProductCode(productCode, limit);
    }

    @Override
    public long countByOrderIdAndType(String orderId, Integer changeType) {
        return lambdaQuery()
                .eq(InventoryLog::getOrderId, orderId)
                .eq(InventoryLog::getChangeType, changeType)
                .count();
    }
}
