package com.haha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.StockRecordStatus;
import com.haha.common.exception.BusinessException;
import com.haha.entity.Device;
import com.haha.entity.StockRecord;
import com.haha.entity.dto.StockRecordQueryDTO;
import com.haha.mapper.DeviceMapper;
import com.haha.mapper.StockRecordMapper;
import com.haha.service.StockRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

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

/**
 * 上货记录服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class StockRecordServiceImpl extends ServiceImpl<StockRecordMapper, StockRecord>
        implements StockRecordService {

    private final StockRecordMapper stockRecordMapper;

    private final DeviceMapper deviceMapper;

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

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

        // 上货员筛选
        if (queryDTO.getStockerId() != null) {
            wrapper.eq(StockRecord::getStockerId, queryDTO.getStockerId());
        }

        // 类型筛选
        if (queryDTO.getStockType() != null) {
            wrapper.eq(StockRecord::getStockType, queryDTO.getStockType());
        }

        // 状态筛选
        if (queryDTO.getStatus() != null) {
            wrapper.eq(StockRecord::getStatus, queryDTO.getStatus());
        }

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

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

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

    private void fillDeviceNames(List<StockRecord> records) {
        if (records == null || records.isEmpty()) return;
        List<String> ids = records.stream()
                .map(StockRecord::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 (StockRecord r : records) {
            r.setDeviceName(nameMap.getOrDefault(r.getDeviceId(), ""));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StockRecord createRecordV2(String deviceId, Integer stockType, Long replenisherId,
                                       String replenisherName, String replenisherPhone, String remark) {
        StockRecord record = new StockRecord();
        record.setDeviceId(deviceId);
        record.setStockType(stockType);
        // 复用 stockerId/stockerName/stockerPhone 字段存储补货员信息
        record.setStockerId(replenisherId);
        record.setStockerName(replenisherName);
        record.setStockerPhone(replenisherPhone);
        record.setStatus(StockRecordStatus.IN_PROGRESS.getCode());
        record.setTotalItems(0);
        record.setTotalQuantity(0);
        record.setRemark(remark);
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());

        save(record);

        log.info("创建上货记录(V2): id={}, deviceId={}, replenisherName={}", record.getId(), deviceId, replenisherName);

        return record;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startActivity(Long recordId) {
        StockRecord record = getById(recordId);
        if (record == null) {
            throw new BusinessException(404, "上货记录不存在");
        }

        record.setStatus(StockRecordStatus.IN_PROGRESS.getCode());
        record.setStartTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        updateById(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeActivity(Long recordId, Integer totalItems, Integer totalQuantity, String activityId) {
        StockRecord record = getById(recordId);
        if (record == null) {
            throw new BusinessException(404, "上货记录不存在");
        }

        record.setStatus(StockRecordStatus.COMPLETED.getCode());
        record.setActivityId(activityId);
        record.setTotalItems(totalItems);
        record.setTotalQuantity(totalQuantity);
        record.setEndTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        updateById(record);

        log.info("完成上货记录: id={}, totalItems={}, totalQuantity={}", recordId, totalItems, totalQuantity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelActivity(Long recordId) {
        StockRecord record = getById(recordId);
        if (record == null) {
            throw new BusinessException(404, "上货记录不存在");
        }

        record.setStatus(StockRecordStatus.CANCELLED.getCode());
        record.setEndTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        updateById(record);

        log.info("取消上货记录: id={}", recordId);
    }

    @Override
    public Map<String, Object> getStockerStatistics(Long stockerId, String startTime, String endTime) {
        return stockRecordMapper.selectStockerStatistics(stockerId, startTime, endTime);
    }

    @Override
    public Map<String, Object> getDetailWithDeviceName(Long id) {
        return stockRecordMapper.selectWithDeviceName(id);
    }
}
