package com.youchain.basicdata.service.impl;

import com.youchain.basicdata.domain.Area;
import com.youchain.basicdata.domain.Point;
import com.youchain.basicdata.repository.AreaRepository;
import com.youchain.basicdata.repository.PointRepository;
import com.youchain.basicdata.service.*;
import com.youchain.businessdata.inputJson.imports.PointImport;
import com.youchain.exception.BadRequestException;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ImportPointServiceImpl implements ImportPointService {

    private final PointRepository pointRepository;

    private final AreaRepository areaRepository;

    private final PointService pointService;

    private final AreaService areaService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importPoint(MultipartFile file) {
        // 根据模板类型进行不同的处理
        List<String> requiredColumns = Arrays.asList(
                "库位号",
                "库区",
                "存储类型",
                "品番",
                "库存下限",
                "纳所",
                "标签类型"
//                ,
//                "总分类型",
//                "关联总库位"
        );
        // 验证模板类型是否正确
        isValidTemplateType(file,requiredColumns);

        // 根据模板类型进行不同的处理
        baseImportTemplate(file);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importPointUpdate(MultipartFile file) {

        // 根据模板类型进行不同的处理
        List<String> requiredColumns = Arrays.asList(
                "序号"
        );
        // 验证模板类型是否正确
        List<String> headers=isValidTemplateType(file,requiredColumns);
        Map<String,Boolean> headersMap=new HashMap<>();
        for(String header:headers){
            headersMap.put(header,Boolean.TRUE);
        }
        // 根据模板类型进行不同的处理
        baseImportTemplateUpdate(file,headersMap);
    }

    // 处理标准模板
    @Transactional
    public void baseImportTemplate(MultipartFile file) {
        // 读取sheet数据
        List<PointImport> dataList = FastExcelUtil.readExcelData(file, PointImport.class, 0, 1);
        //批量导入
        importPointData(dataList);
    }

    // 处理更新导入模板
    @Transactional
    public void baseImportTemplateUpdate(MultipartFile file,Map<String,Boolean> headersMap) {
        // 读取sheet数据
        List<PointImport> dataList = FastExcelUtil.readExcelData(file, PointImport.class, 0, 1);
        //批量导入
        importPointDataUpdate(dataList,headersMap);
    }

    /**
     * 处理批量导入
     */
    private void importPointData(List<PointImport> dataList) {
        // TODO: 实现批量导入逻辑
        log.info("处理批量导入，数据条数: {}", dataList.size());

        //获取文件中所有的库位编码
        List<String> pointcodes = dataList.stream().map(PointImport::getCode).collect(Collectors.toList());
        pointcodes = pointcodes.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<String, Point> exitPointMap = validatePoint(pointcodes);
        List<Point> pointAll=pointRepository.findAll();
        for(Point p:pointAll){
            exitPointMap.put(p.getCode(),p);
        }

        //获取文件中所有的库区名称
        List<String> areaNames = dataList.stream().map(PointImport::getAreaName).collect(Collectors.toList());
        areaNames = areaNames.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<String, Area> exitAreaMap = validateArea(areaNames);

        for (PointImport data : dataList) {
            Point point = exitPointMap.get(data.getCode());
            if (point == null) {
                point=new Point();
                point.setCode(data.getCode());
                point.setDept(UserUtils.getDept());
                point.setCreateBy(SecurityUtils.getCurrentUsername());
                point.setCreateTime(new Timestamp(new Date().getTime()));
                point.setEnabled(Boolean.TRUE);
            }
            point.setArea(exitAreaMap.get(data.getAreaName()));
            String lx = data.getType();
            if (lx.equals("材管库位")) {
                lx = BaseStatus.CH;
            } else if (lx.equals("制造库位")) {
                lx = BaseStatus.ZZKW;
            }else if (lx.equals("缓存库位")) {
                lx = BaseStatus.HCKW;
            }
            point.setType(lx);
            point.setBeatCode(data.getNs());
            point.setDescription(data.getBqlx());
            point.setItemCode(data.getItemCode());
            point.setZflx(data.getZflx());
            point.setBqlx(data.getBqlx());
            point.setGlzkw(data.getGlzkw());
            point.setInvMin(Integer.parseInt(data.getKcxx()));
            pointRepository.save(point);
        }
    }

    /**
     * 处理批量更新导入
     */
    private void importPointDataUpdate(List<PointImport> dataList,Map<String,Boolean> headersMap) {
        // TODO: 实现批量导入逻辑
        log.info("处理批量导入，数据条数: {}", dataList.size());
        List<Point> pointList=pointRepository.findAll();
        Map<String, Point> pointCodeMap = new HashMap<>();
        Map<Long, Point> pointIdMap = new HashMap<>();
        for(Point point:pointList){
            pointCodeMap.put(point.getCode(),point);
            pointIdMap.put(point.getId(),point);
        }
        List<Area> areaList=areaRepository.findAll();
        Map<String, Area> areaCodeMap = new HashMap<>();
        Map<Long, Area> areaIdMap = new HashMap<>();
        for(Area area:areaList){
            areaCodeMap.put(area.getCode(),area);
            areaIdMap.put(area.getId(),area);
        }
        Map<String, String> pointTypeMap = new HashMap<>();
        pointTypeMap.put("材管库位",BaseStatus.CH);
        pointTypeMap.put("制造库位",BaseStatus.ZZKW);
        pointTypeMap.put("缓存库位",BaseStatus.HCKW);
        Map<String, String> bqTypeMap = new HashMap<>();
        bqTypeMap.put("中大物标签","中大物标签");
        bqTypeMap.put("小物标签","小物标签");
        bqTypeMap.put("自由货位标签","自由货位标签");
        for (PointImport data : dataList) {
            String code=data.getCode();
            String areaName=data.getAreaName();
            String type= data.getType();
            String kcxx= data.getKcxx();
            String itemCode= data.getItemCode();
            String ns= data.getNs();
            String bqlx= data.getBqlx();
            Point point = pointIdMap.get(data.getId());
            point.setUpdateDes("");
            if(point==null){
                throw new BadRequestException("库位不存在");
            }
            if(headersMap.containsKey("库位号")) {
                Point point2 = pointCodeMap.get(code);
                if(point2!=null){
                    throw new BadRequestException(code+"库位已存在，不能重复更新");
                }
                point.setUpdateDes(point.getCode()+"update"+code+"\n");
                point.setCode(code);
            }
            if(headersMap.containsKey("库区")) {
                Area area=areaCodeMap.get(areaName);
                if(area==null){
                    throw new BadRequestException("库区不存在");
                }
                point.setUpdateDes(point.getArea().getCode()+"update"+areaName+"\n");
                point.setArea(area);
            }
            if(headersMap.containsKey("存储类型")) {
                if(!pointTypeMap.containsKey(type)){
                    throw new BadRequestException("存储类型填写错误");
                }
                point.setType(pointTypeMap.get(type));
            }
            if(headersMap.containsKey("库存下限")) {
                point.setInvMin(Integer.parseInt(kcxx));
            }
            if(headersMap.containsKey("品番")) {
                point.setItemCode(itemCode);
            }
            if(headersMap.containsKey("纳所")) {
                point.setBeatCode(ns);
            }
            if(headersMap.containsKey("标签类型")) {
                if(!bqTypeMap.containsKey(bqlx)){
                    throw new BadRequestException("标签类型填写错误");
                }
                point.setType(bqTypeMap.get(bqlx));
            }
            pointRepository.save(point);
        }
    }

    //验证库位
    private Map<String, Point> validatePoint(List<String> codes) {
        Map<String, Point> existMap = pointService.queryByPointCodesToMap(codes);
        return existMap;
    }

    //验证库区
    private Map<String, Area> validateArea(List<String> names) {
        Map<String, Area> existMap = areaService.queryByAreaCodesToMap(names);
        if (existMap.isEmpty()) {
            throw new BadRequestException("库区不存在或已失效");
        }
        List<String> existCodes = new ArrayList(existMap.keySet());
        // 获取两个集合的非交集说明品番不存在或失效，直接提示
        List<String> difference = SmartStringUtil.getDifference(names, existCodes);
        if (CollectionUtils.isNotEmpty(difference)) {
            throw new BadRequestException(difference + "库区不存在或已失效");
        }
        return existMap;
    }

    //验证模板是否使用正确
    private List<String> isValidTemplateType(MultipartFile file,List<String> requiredColumns) {
        List<String> headers = FastExcelUtil.readHeadContent(file, 0, 0);
        if (!SmartStringUtil.containsAllIgnoreCase(requiredColumns, headers)) {
            throw new BadRequestException("标准导入模板不正确,请确认模板信息");
        }
        return headers;
    }


}
