package com.zg.project.Inventory.AutoInventory.service.impl;

import com.zg.common.utils.PageUtils;
import com.zg.framework.web.page.TableDataInfo;
import com.zg.project.Inventory.domain.dto.SodQueryDTO;
import com.zg.project.Inventory.domain.entity.InventoryMatchScan;
import com.zg.project.Inventory.domain.entity.Sod;
import com.zg.project.Inventory.domain.vo.ChartDataVO;
import com.zg.project.Inventory.domain.vo.PcdeCntVO;
import com.zg.project.Inventory.domain.vo.SodVO;
import com.zg.project.Inventory.AutoInventory.mapper.InventoryMatchScanMapper;
import com.zg.project.Inventory.AutoInventory.mapper.SodMapper;
import com.zg.project.Inventory.AutoInventory.service.ISodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;



@Service
public class SodServiceImpl implements ISodService {

    @Autowired
    private SodMapper sodMapper;

    @Autowired
    private InventoryMatchScanMapper matchScanMapper;

    @Override
    public List<SodVO> selectByPcdeList(SodQueryDTO dto) {
        return sodMapper.selectByPcdeList(dto);
    }

    @Override
    public Map<String, Object> matchWithStatus(SodQueryDTO dto) {
        int pageNum = dto.getPageNum();
        int pageSize = dto.getPageSize();
        List<String> pcdeIds = dto.getIds();

        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1 || pageSize > 1000) pageSize = 10;

        // 一、查询三类数据（不分页，插入数据库用）
        List<Sod> matchedAll = sodMapper.getByFycde1List(pcdeIds);
        matchedAll.forEach(sod -> sod.setStatus("0"));
        // 二、查询未匹配数据
        List<Sod> missedAll = sodMapper.getMissedFycde1s(pcdeIds);
        missedAll.forEach(sod -> sod.setStatus("1"));
        // 三、查询误扫数据
        List<String> errorIds = pcdeIds.stream()
                .filter(id -> Boolean.FALSE.equals(sodMapper.existsByFycde1(id)))
                .collect(Collectors.toList());

        List<Sod> errorAll = errorIds.stream()
                .map(id -> new Sod().setFycde1(id).setStatus("2"))
                .collect(Collectors.toList());

        // 二、插入全部数据
        String nowStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String tmeStr = dto.getTme();
        String deviceId = dto.getDeviceId();
        int scanType = dto.getScanType() != null ? dto.getScanType() : 0;

        List<InventoryMatchScan> toSave = new ArrayList<>();
        matchedAll.forEach(sod ->
                toSave.add(buildScanRecord(dto.getTaskName(),sod.getFycde1(), "0", deviceId, tmeStr, nowStr, scanType)));

        missedAll.forEach(sod ->
                toSave.add(buildScanRecord(dto.getTaskName(),sod.getFycde1(), "1", deviceId, tmeStr, nowStr, scanType)));

        errorAll.forEach(sod ->
                toSave.add(buildScanRecord(dto.getTaskName(),sod.getFycde1(), "2", deviceId, tmeStr, nowStr, scanType)));

        if (!toSave.isEmpty()) {
            matchScanMapper.insertBatch(toSave);
        }

        // 三、分页展示数据（只用于返回）
        PageUtils.startPage(pageNum, pageSize);
        List<Sod> matchedPage = sodMapper.getByFycde1List(pcdeIds);
        matchedPage.forEach(sod -> sod.setStatus("0"));

        PageUtils.startPage(pageNum, pageSize);
        List<Sod> missedPage = sodMapper.getMissedFycde1s(pcdeIds);
        missedPage.forEach(sod -> sod.setStatus("1"));

        int totalErrors = errorAll.size();
        int start = (pageNum - 1) * pageSize;
        int end = Math.min(start + pageSize, totalErrors);

        List<Sod> errorPage = new ArrayList<>();
        if (start < totalErrors && start >= 0) {
            errorPage = errorAll.subList(start, end);
        }

        // 四、封装返回结构
        TableDataInfo errorTable = new TableDataInfo();
        errorTable.setRows(errorPage);
        errorTable.setTotal(totalErrors);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("matched", PageUtils.getDataTable(matchedPage));
        resultMap.put("missed", PageUtils.getDataTable(missedPage));
        resultMap.put("error", errorTable);

        return resultMap;

    }

    private InventoryMatchScan buildScanRecord(String taskName,String pcde, String status,
                                               String deviceId, String tme, String createdAt, int scanType) {
        InventoryMatchScan record = new InventoryMatchScan();
        record.setPcde(pcde);
        record.setTaskName(taskName);
        record.setStatus(status);
        record.setDeviceId(deviceId);
        record.setTme(tme);
        record.setScanType(scanType);
        record.setCreatedAt(createdAt);
        return record;
    }

    @Override
    public ChartDataVO matchWithAll(SodQueryDTO dto) {

        List<String> ids = dto.getIds();
        if (ids == null || ids.isEmpty()) {
            // 没传扫描 ID，直接返回空
            return new ChartDataVO(Collections.emptyList(),
                    Collections.emptyList(),
                    0L);
        }

        // ① 查询统计结果
        List<PcdeCntVO> rows = sodMapper.selectPcdeCntByFycde1(ids);

        // ② 组装前端需要的数组
        List<String> pcdeList = new ArrayList<>(rows.size());
        List<Long> fycdeCntList = new ArrayList<>(rows.size());

        for (PcdeCntVO r : rows) {
            pcdeList.add(r.getPcde());
            fycdeCntList.add(r.getCnt());
        }

        return new ChartDataVO(pcdeList, fycdeCntList, (long) rows.size());
    }

    @Override
    public Map<String, Object> getAll() {
        List<Sod> sodList = sodMapper.getAll();
        Map<String, Object> resultMap = new HashMap<>();

        // 1. 所属仓库 -> 存放位置 -> 数量
        Map<String, Map<String, Object>> warehouseStats = sodList.stream()
                .collect(Collectors.groupingBy(
                        s -> s.getWh() == null ? "" : s.getWh(),
                        LinkedHashMap::new,
                        Collectors.collectingAndThen(Collectors.toList(), list -> {
                            Map<String, Object> map = new HashMap<>();
                            long locationCount = list.stream()
                                    .map(s -> s.getPcde() == null ? "" : s.getPcde())
                                    .distinct()
                                    .count();
                            map.put("locationCount", locationCount);
                            map.put("itemCount", list.size());
                            return map;
                        })
                ));
        resultMap.put("warehouseStats", warehouseStats);

        // 2. 项目定义号 -> 封装 des_pro + erpid + count
        List<Map<String, Object>> projectStats = sodList.stream()
                .collect(Collectors.groupingBy(
                        s -> s.getErpid() == null ? "" : s.getErpid(),
                        LinkedHashMap::new,
                        Collectors.collectingAndThen(Collectors.toList(), list -> {
                            Sod first = list.get(0);
                            Map<String, Object> map = new HashMap<>();
                            map.put("erpid", first.getErpid() == null ? "" : first.getErpid());
                            map.put("des_pro", first.getDesPro() == null ? "" : first.getDesPro());
                            map.put("count", list.size());
                            return map;
                        })
                ))
                .values()
                .stream()
                .collect(Collectors.toList());

        resultMap.put("projectStats", projectStats);

        // 3. 库存类型 -> 数量
        Map<String, Long> typeCountMap = sodList.stream()
                .collect(Collectors.groupingBy(
                        s -> s.getWtpe() == null ? "" : s.getWtpe(),
                        Collectors.counting()
                ));
        resultMap.put("typeStats", typeCountMap);

        return resultMap;
    }

}