package net.vtstar.zhongtong.avi.equipment.service;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import net.vtstar.user.mybatis.provider.Operation;
import net.vtstar.user.mybatis.provider.OrderBy;
import net.vtstar.user.mybatis.provider.WhereFilter;
import net.vtstar.user.search.service.SearchService;
import net.vtstar.utils.asserts.ParamAssert;
import net.vtstar.zhongtong.avi.equipment.domain.EquipInfo;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopArea;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopLane;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopStation;
import net.vtstar.zhongtong.avi.equipment.mapper.BasicInfoMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.PaintshopAreaMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.PaintshopLaneMapper;
import net.vtstar.zhongtong.avi.equipment.mapper.PaintshopStationMapper;
import net.vtstar.zhongtong.avi.sqlserver.domain.MesWorkOrderInfo;
import net.vtstar.zhongtong.avi.sqlserver.mapper.MesWorkOrderMapper;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: xiadongwei
 * @Date: 2019/9/20 9:31
 */
@Slf4j
@Service
public class BasicInfoService {

    @Autowired
    private BasicInfoMapper basicInfoMapper;

    @Autowired
    private SearchService searchService;

    @Autowired
    private PaintshopStationMapper stationMapper;

    @Autowired
    private PaintshopAreaMapper paintshopAreaMapper;

    @Autowired
    private PaintshopLaneMapper paintshopLaneMapper;

    @Autowired
    private MesWorkOrderMapper mesWorkOrderMapper;

    private static final String SUFFIX_2003 = ".xls";
    private static final String SUFFIX_2007 = ".xlsx";

    /**
     * 分页查询设备
     */
    public List<EquipInfo> findPageEquip(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        return basicInfoMapper.findList(searchService.pageFilter2Filter(pageFilter), EquipInfo.class);
    }

    /**
     * 新增设备
     */
    public void createEquip(EquipInfo equipInfo) {
        Assert.notNull(equipInfo, "equipInfo 不能为null！");
        basicInfoMapper.insert(fieldValidEquip(equipInfo));
    }

    /**
     * 修改设备
     */
    public void updateEquip(EquipInfo equipInfo) {
        ParamAssert.notNull(equipInfo, "equipInfo 不能为 null！");
        ParamAssert.notNull(equipInfo.getId(), "EquipInfo ID 不能为 null！");
        basicInfoMapper.update(fieldValidEquip(equipInfo));
    }

    /**
     * 根据id逻辑删除设备
     */
    public void deleteEquipById(Long id) {
        EquipInfo equipInfo = basicInfoMapper.getById(id, EquipInfo.class);
        Assert.notNull(equipInfo, "数据不存在或已删除");
        basicInfoMapper.delete(equipInfo);
    }

    /**
     * 设备新增修改操作，参数校验
     *
     * @param equipInfo
     */
    private EquipInfo fieldValidEquip(EquipInfo equipInfo) {

        // 是否更新操作
        boolean isUpdate = (null != equipInfo.getId());

        if (isUpdate) {
            EquipInfo oldData = basicInfoMapper.getById(equipInfo.getId(), EquipInfo.class);
            ParamAssert.notNull(oldData, "数据不存在或已删除");
            List<EquipInfo> equipInfos = basicInfoMapper.findList(new WhereFilter() {{
                addFilter("workshop_code", Operation.EQUAL, equipInfo.getWorkshopCode());
                addFilter("equip_type", Operation.EQUAL, equipInfo.getEquipType());
                addFilter("equip_code", Operation.EQUAL, equipInfo.getEquipCode());
            }}, EquipInfo.class);
            ParamAssert.isTrue(CollectionUtils.isEmpty(equipInfos) || !oldData.getId().equals(equipInfos.get(0).getId()),
                    "存在车间/分类/编号完全相同的设备!");
            oldData.setWorkshopCode(equipInfo.getWorkshopCode());
            oldData.setWorkshopName(equipInfo.getWorkshopName());
            oldData.setEquipType(equipInfo.getEquipType());
            oldData.setEquipCode(equipInfo.getEquipCode());
            oldData.setAlias(equipInfo.getAlias());
            oldData.setEquipFactory(equipInfo.getEquipFactory());
            return oldData;
        }else{
            List<EquipInfo> equipInfos = basicInfoMapper.findList(new WhereFilter() {{
                addFilter("workshop_code", Operation.EQUAL, equipInfo.getWorkshopCode());
                addFilter("equip_type", Operation.EQUAL, equipInfo.getEquipType());
                addFilter("equip_code", Operation.EQUAL, equipInfo.getEquipCode());
            }}, EquipInfo.class);
            ParamAssert.isTrue(CollectionUtils.isEmpty(equipInfos), "存在车间/分类/编号完全相同的设备!");
            return equipInfo;
        }
    }

    /**
     * 分页查询工位
     */
    public List<PaintshopStation> findPageStation(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        return stationMapper.findList(searchService.pageFilter2Filter(pageFilter, new WhereFilter() {{
            addJoin(PaintshopStation.class, "area_id", PaintshopArea.class, "id");
            addJoin(PaintshopStation.class, "lane_id", PaintshopLane.class, "id");
            addOrderBy(PaintshopStation.class, "sequence", OrderBy.ASC);
        }}), PaintshopStation.class);
    }

    /**
     * 新增工位
     */
    public void createStation(PaintshopStation station) {
        Assert.notNull(station, "station 不能为null！");
        stationMapper.insert(fieldValidStation(station));
    }

    /**
     * 修改工位
     */
    public void updateStation(PaintshopStation station) {
        ParamAssert.notNull(station, "station 不能为 null！");
        ParamAssert.notNull(station.getId(), "工位 ID 不能为 null！");
        stationMapper.update(fieldValidStation(station));
    }

    /**
     * 根据id逻辑删除工位
     */
    public void deleteStationById(Long id) {
        PaintshopStation station = stationMapper.getById(id, EquipInfo.class);
        Assert.notNull(station, "数据不存在或已删除");
        stationMapper.delete(station);
    }

    /**
     * 设备新增修改操作，参数校验
     *
     * @param station
     */
    private PaintshopStation fieldValidStation(PaintshopStation station) {

        // 是否更新操作
        boolean isUpdate = (null != station.getId());

        if (isUpdate) {
            PaintshopStation oldData = stationMapper.getById(station.getId(), EquipInfo.class);
            ParamAssert.notNull(oldData, "数据不存在或已删除");
            List<PaintshopStation> stationList = stationMapper.findList(new WhereFilter() {{
                addFilter("workshop_code", Operation.EQUAL, station.getWorkshopCode());
                addFilter("area_id", Operation.EQUAL, station.getAreaId());
                addFilter("lane_id", Operation.EQUAL, station.getLaneId());
                addFilter("code", Operation.EQUAL, station.getCode());
            }}, PaintshopStation.class);
            ParamAssert.isTrue(CollectionUtils.isEmpty(stationList) || !oldData.getId().equals(stationList.get(0).getId()),
                    "存在车间/区域/车道/编号完全相同的设备!");
            oldData.setWorkshopCode(station.getWorkshopCode());
            oldData.setAreaId(station.getAreaId());
            oldData.setLaneId(station.getLaneId());
            oldData.setCode(station.getCode());
            oldData.setSequence(station.getSequence());
            oldData.setKeyStation(station.getKeyStation());
            return oldData;
        }else{
            List<PaintshopStation> equipInfos = stationMapper.findList(new WhereFilter() {{
                addFilter("workshop_code", Operation.EQUAL, station.getWorkshopCode());
                addFilter("area_id", Operation.EQUAL, station.getAreaId());
                addFilter("lane_id", Operation.EQUAL, station.getLaneId());
                addFilter("code", Operation.EQUAL, station.getCode());
            }}, PaintshopStation.class);
            ParamAssert.isTrue(CollectionUtils.isEmpty(equipInfos), "存在车间/区域/车道/编号完全相同的设备!");
            return station;
        }
    }

    public List<PaintshopArea> getPaintshopArea() {
       return paintshopAreaMapper.findList(new WhereFilter(), PaintshopArea.class);
    }

    public List<PaintshopLane> getPaintshopLane(Long areaId) {
        return paintshopLaneMapper.findList(new WhereFilter(){{
            addFilter("area_id", Operation.EQUAL, areaId);
        }}, PaintshopLane.class);
    }

    public Boolean resolveExcel(MultipartFile file) {
        List<MesWorkOrderInfo> list = new ArrayList<>();
        //获取文件的名字
        String originalFilename = file.getOriginalFilename();
        Workbook workbook = null;
        try {
            if (originalFilename.endsWith(SUFFIX_2003)) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else if (originalFilename.endsWith(SUFFIX_2007)) {
                workbook = new XSSFWorkbook(file.getInputStream());
            }
        } catch (Exception e) {
            log.error("读取文件错误: {}", e.getMessage());
            return false;
        }
        ParamAssert.notNull(workbook, "文件名 :" + originalFilename + "不符合EXCEL的格式要求!标准格式:.xls/.xlsx");
        //获取所有的工作表的的数量
        int numOfSheet = workbook.getNumberOfSheets();
        //遍历这个这些表
        for (int i = 0; i < numOfSheet; i++) {
            //获取一个sheet也就是一个工作簿
            Sheet sheet = workbook.getSheetAt(i);
            int lastRowNum = sheet.getLastRowNum();
            //从第一行开始第一行一般是标题
            for (int j = 1; j <= lastRowNum; j++) {
                Row row = sheet.getRow(j);
                if (null == row) {
                    continue;
                }
                MesWorkOrderInfo workOrder = new MesWorkOrderInfo();
                //车间计划工单号
                if (row.getCell(0) != null) {
                    row.getCell(0).setCellType(CellType.STRING);
                    String workOrderNo = row.getCell(0).getStringCellValue();
                    if (StringUtils.isEmpty(workOrderNo)){
                        continue;
                    }
                    workOrder.setWorkOrderNo(workOrderNo);
                }
                //车型
                if (row.getCell(1) != null) {
                    row.getCell(1).setCellType(CellType.STRING);
                    String vehicleModel = row.getCell(1).getStringCellValue();
                    if (null == vehicleModel){
                        continue;
                    }
                    workOrder.setVehicleModel(vehicleModel);
                }
                //单位
                if (row.getCell(2) != null) {
                    row.getCell(2).setCellType(CellType.STRING);
                    String unit = row.getCell(2).getStringCellValue();
                    workOrder.setUnit(unit);
                }
                //产线
                if (row.getCell(3) != null) {
                    row.getCell(3).setCellType(CellType.STRING);
                    String productionLine = row.getCell(3).getStringCellValue();
                    workOrder.setProductionLine(productionLine);
                }
                list.add(workOrder);
            }
        }
        if (CollectionUtils.isEmpty(list)){
            return false;
        }
        mesWorkOrderMapper.insertList(list);
        return true;
    }

    public List<MesWorkOrderInfo> getWorkOrder(JSONObject pageFilter) {
        PageHelper.startPage(pageFilter.getIntValue("pageNum"), pageFilter.getIntValue("pageSize"));
        return mesWorkOrderMapper.findList(searchService.pageFilter2Filter(pageFilter, new WhereFilter(){{
            addFilter("status", Operation.EQUAL, "4");
        }}), MesWorkOrderInfo.class);
    }
}
