package com.jsh.erp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.MaterialExtend;
import com.jsh.erp.datasource.entities.MaterialExtendExample;
import com.jsh.erp.datasource.entities.User;
import com.jsh.erp.datasource.mappers.MaterialExtendMapper;
import com.jsh.erp.datasource.mappers.MaterialExtendMapperEx;
import com.jsh.erp.datasource.vo.MaterialExtendVo4List;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.MaterialExtendService;
import com.jsh.erp.service.RedisService;
import com.jsh.erp.service.UserService;
import com.jsh.erp.utils.DateUtils;
import com.jsh.erp.utils.RandomHelper;
import com.jsh.erp.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class MaterialExtendServiceImpl extends ServiceImpl<MaterialExtendMapper, MaterialExtend> implements MaterialExtendService {
    private Logger logger = LoggerFactory.getLogger(MaterialExtendServiceImpl.class);

    @Resource
    private MaterialExtendMapper materialExtendMapper;
    @Resource
    private MaterialExtendMapperEx materialExtendMapperEx;
    @Resource
    private UserService userService;
    @Resource
    private RedisService redisService;

    @Override
    public MaterialExtend getMaterialExtend(long id)throws Exception {
        MaterialExtend result=null;
        try{
            result=materialExtendMapper.selectByPrimaryKey(id);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return result;
    }

    /**
     * 根据产品id查询产品价格拓展信息
     * @param materialId 产品id
     */
    @Override
    public List<MaterialExtendVo4List> getDetailList(Long materialId) {
        List<MaterialExtendVo4List> list=null;
        try{
            list = materialExtendMapperEx.getDetailList(materialId);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list;
    }

    @Override
    public List<MaterialExtend> getListByMIds(List<Long> idList) {
        List<MaterialExtend> meList = null;
        try{
            Long [] idArray= StringUtil.listToLongArray(idList);
            if(idArray!=null && idArray.length>0) {
                meList = materialExtendMapperEx.getListByMId(idArray);
            }
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return meList;
    }

    /**
     * 保存产品拓展记录
     * @param obj
     * @param sortList
     * @param materialId
     * @param type
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public String saveDetials(JSONObject obj, String sortList, Long materialId, String type) throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //获取商品拓展行参数集合
        JSONArray meArr = obj.getJSONArray("meList");
        //添加商品拓展集合
        JSONArray insertedJson = new JSONArray();
        //修改商品拓展集合
        JSONArray updatedJson = new JSONArray();
        //移除商品集合
        JSONArray deletedJson = obj.getJSONArray("meDeleteIdList");
        JSONArray sortJson = JSONArray.parseArray(sortList);
        //添加/修改行数据处理
        if (null != meArr) {
            if("insert".equals(type)){
                for (int i = 0; i < meArr.size(); i++) {
                    JSONObject tempJson = meArr.getJSONObject(i);
                    insertedJson.add(tempJson);
                }
            } else if("update".equals(type)){
                for (int i = 0; i < meArr.size(); i++) {
                    JSONObject tempJson = meArr.getJSONObject(i);
                    String tempId = tempJson.getString("id");
                    if(tempId.length()>19){
                        //id长度大于19，属于新增数据
                        insertedJson.add(tempJson);
                    } else {
                        updatedJson.add(tempJson);
                    }
                }
            }
        }
        //删除行数据处理
        if (null != deletedJson) {
            StringBuffer bf=new StringBuffer();
            for (int i = 0; i < deletedJson.size(); i++) {
                bf.append(deletedJson.getString(i));
                if(i<(deletedJson.size()-1)){
                    bf.append(",");
                }
            }
            //删除拓展行
            this.batchDeleteMaterialExtendByIds(bf.toString(), request);
        }

        //添加产品拓展行
        if (null != insertedJson) {
            for (int i = 0; i < insertedJson.size(); i++) {
                //商品拓展
                MaterialExtend materialExtend = new MaterialExtend();
                JSONObject tempInsertedJson = JSONObject.parseObject(insertedJson.getString(i));
                //设置商品id
                materialExtend.setMaterialId(materialId);
                //设置商品单位
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityUnit"))) {
                    materialExtend.setCommodityUnit(tempInsertedJson.getString("commodityUnit"));
                }
                //设置商品属性
                if (tempInsertedJson.get("sku")!=null) {
                    materialExtend.setSku(tempInsertedJson.getString("sku"));
                }
                //设置采购价格
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("purchaseDecimal"))) {
                    materialExtend.setPurchaseDecimal(tempInsertedJson.getBigDecimal("purchaseDecimal"));
                }
                //设置零售价格
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("commodityDecimal"))) {
                    materialExtend.setCommodityDecimal(tempInsertedJson.getBigDecimal("commodityDecimal"));
                }
                //设置销售价格
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("wholesaleDecimal"))) {
                    materialExtend.setWholesaleDecimal(tempInsertedJson.getBigDecimal("wholesaleDecimal"));
                }
                //设置最低售价
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("lowDecimal"))) {
                    materialExtend.setLowDecimal(tempInsertedJson.getBigDecimal("lowDecimal"));
                }
                //设置生产日期
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("productionDate"))) {
                    materialExtend.setProductionDate(tempInsertedJson.getDate("productionDate"));
                }
                //设置保质期天数
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("expiryNum"))) {
                    materialExtend.setExpiryNum(tempInsertedJson.getInteger("expiryNum"));
                }
                //设置供应商id
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("supplierId"))) {
                    materialExtend.setSupplierId(tempInsertedJson.getLong("supplierId"));
                }
                //设置商品条码
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("barCode"))) {
                    materialExtend.setBarCode(tempInsertedJson.getString("barCode"));
                }
                //设置批次号
                String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
                materialExtend.setBatchNumber(batchNumber);
                //设置库存
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("inventory"))) {
                    materialExtend.setInventory(tempInsertedJson.getBigDecimal("inventory"));
                }
                //设置仓库id
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("depotId"))) {
                    materialExtend.setDepotId(tempInsertedJson.getLong("depotId"));
                }
                //设置仓位货架
                if (StringUtils.isNotEmpty(tempInsertedJson.getString("position"))) {
                    materialExtend.setPosition(tempInsertedJson.getString("position"));
                }
                //添加数据
                this.insertMaterialExtend(materialExtend);
            }
        }
        //修改拓展行
        if (null != updatedJson) {
            for (int i = 0; i < updatedJson.size(); i++) {
                JSONObject tempUpdatedJson = JSONObject.parseObject(updatedJson.getString(i));
                MaterialExtend materialExtend = new MaterialExtend();
                //设置id
                materialExtend.setId(tempUpdatedJson.getLong("id"));
                materialExtend.setBarCode(tempUpdatedJson.getString("barCode"));
                //Json里的数据赋值到对象
                this.setMaterialExtend(tempUpdatedJson,materialExtend);
                //修改商品拓展
                this.updateMaterialExtend(materialExtend);
                //如果金额为空，此处单独置空
                materialExtendMapperEx.specialUpdatePrice(materialExtend);
            }
        }
        //处理条码的排序，基本单位排第一个
        if (null != sortJson && sortJson.size()>0) {
            //此处为更新的逻辑
            for (int i = 0; i < sortJson.size(); i++) {
                JSONObject tempSortJson = JSONObject.parseObject(sortJson.getString(i));
                MaterialExtend materialExtend = new MaterialExtend();
                if(StringUtil.isExist(tempSortJson.get("id"))) {
                    materialExtend.setId(tempSortJson.getLong("id"));
                }
                if(StringUtil.isExist(tempSortJson.get("defaultFlag"))) {
                    materialExtend.setDefaultFlag(tempSortJson.getString("defaultFlag"));
                }
                this.updateMaterialExtend(materialExtend);
            }
        } else {
            //新增的时候将第一条记录设置为默认基本单位
            MaterialExtendExample example = new MaterialExtendExample();
            example.createCriteria().andMaterialIdEqualTo(materialId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
            List<MaterialExtend> meList = materialExtendMapper.selectByExample(example);
            if(meList!=null) {
                for(int i=0; i<meList.size(); i++) {
                    MaterialExtend materialExtend = new MaterialExtend();
                    materialExtend.setId(meList.get(i).getId());
                    if(i==0) {
                        materialExtend.setDefaultFlag("1"); //默认
                    } else {
                        materialExtend.setDefaultFlag("0"); //非默认
                    }
                    this.updateMaterialExtend(materialExtend);
                }
            }
        }
        return null;
    }

    /**
     * 添加商品拓展
     * @param materialExtend 商品拓展
     */
    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertMaterialExtend(MaterialExtend materialExtend)throws Exception {
        User user = userService.getCurrentUser();
        materialExtend.setDeleteFlag(BusinessConstants.DELETE_FLAG_EXISTS);
        materialExtend.setCreateTime(new Date());
        materialExtend.setUpdateTime(new Date().getTime());
        materialExtend.setCreateSerial(user.getLoginName());
        materialExtend.setUpdateSerial(user.getLoginName());
        int result = 0;
        try{
            result= materialExtendMapper.insertSelective(materialExtend);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    /**
     * 修改商品拓展
     * @param materialExtend 商品拓展
     */
    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateMaterialExtend(MaterialExtend materialExtend) throws Exception{
        User user = userService.getCurrentUser();
        materialExtend.setUpdateTime(System.currentTimeMillis());
        materialExtend.setUpdateSerial(user.getLoginName());
        int res =0;
        try{
            res= materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return res;
    }

    @Override
    public int checkIsBarCodeExist(Long id, String barCode)throws Exception {
        MaterialExtendExample example = new MaterialExtendExample();
        MaterialExtendExample.Criteria criteria = example.createCriteria();
        criteria.andBarCodeEqualTo(barCode);
        if (id > 0) {
            criteria.andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        } else {
            criteria.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        }
        List<MaterialExtend> list =null;
        try{
            list = materialExtendMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list==null?0:list.size();
    }

    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteMaterialExtend(Long id, HttpServletRequest request)throws Exception {
        int result =0;
        MaterialExtend materialExtend = new MaterialExtend();
        materialExtend.setId(id);
        materialExtend.setDeleteFlag(BusinessConstants.DELETE_FLAG_DELETED);
        Long userId = Long.parseLong(redisService.getObjectFromSessionByKey(request,"userId").toString());
        User user = userService.getUser(userId);
        materialExtend.setUpdateTime(new Date().getTime());
        materialExtend.setUpdateSerial(user.getLoginName());
        try{
            result= materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    /**
     * 删除商品拓展行
     * @param ids 拓展行id集合
     */
    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteMaterialExtendByIds(String ids, HttpServletRequest request) throws Exception{
        String [] idArray=ids.split(",");
        int result = 0;
        try{
            result = materialExtendMapperEx.batchDeleteMaterialExtendByIds(idArray);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Override
    public int insertMaterialExtend(JSONObject obj, HttpServletRequest request) throws Exception{
        MaterialExtend materialExtend = JSONObject.parseObject(obj.toJSONString(), MaterialExtend.class);
        int result=0;
        try{
            result = materialExtendMapper.insertSelective(materialExtend);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Override
    public int updateMaterialExtend(JSONObject obj, HttpServletRequest request)throws Exception {
        MaterialExtend materialExtend = JSONObject.parseObject(obj.toJSONString(), MaterialExtend.class);
        int result=0;
        try{
            result = materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
        }catch(Exception e){
            JshException.writeFail(logger, e);
        }
        return result;
    }

    @Override
    public List<MaterialExtend> getMaterialExtendByTenantAndTime(Long tenantId, Long lastTime, Long syncNum)throws Exception {
        List<MaterialExtend> list=new ArrayList<MaterialExtend>();
        try{
            //先获取最大的时间戳，再查两个时间戳之间的数据，这样同步能够防止丢失数据（应为时间戳有重复）
            Long maxTime = materialExtendMapperEx.getMaxTimeByTenantAndTime(tenantId, lastTime, syncNum);
            if(tenantId!=null && lastTime!=null && maxTime!=null) {
                MaterialExtendExample example = new MaterialExtendExample();
                example.createCriteria().andTenantIdEqualTo(tenantId)
                        .andUpdateTimeGreaterThan(lastTime)
                        .andUpdateTimeLessThanOrEqualTo(maxTime);
                list=materialExtendMapper.selectByExample(example);
            }
        }catch(Exception e){
            JshException.readFail(logger, e);
        }
        return list;
    }

    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public Long selectIdByMaterialIdAndDefaultFlag(Long materialId, String defaultFlag) {
        Long id = 0L;
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria().andMaterialIdEqualTo(materialId).andDefaultFlagEqualTo(defaultFlag)
                                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
        if(list!=null && list.size()>0) {
            id = list.get(0).getId();
        }
        return id;
    }

    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public Long selectIdByMaterialIdAndBarCode(Long materialId, String barCode) {
        Long id = 0L;
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria().andMaterialIdEqualTo(materialId).andBarCodeEqualTo(barCode)
                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
        if(list!=null && list.size()>0) {
            id = list.get(0).getId();
        }
        return id;
    }

    @Override
    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public List<MaterialExtend> getListByMaterialIdAndDefaultFlagAndBarCode(Long materialId, String defaultFlag, String barCode) {
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria().andMaterialIdEqualTo(materialId).andDefaultFlagEqualTo(defaultFlag).andBarCodeNotEqualTo(barCode)
                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        return materialExtendMapper.selectByExample(example);
    }

    @Override
    public MaterialExtend getInfoByBarCode(String barCode)throws Exception {
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
        if(list!=null && list.size()>0) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 商品的副条码和数据库里面的商品条码存在重复（除自身商品之外）
     * @param manyBarCode
     * @param barCode
     * @return
     */
    @Override
    public int getCountByManyBarCodeWithoutUs(String manyBarCode, String barCode) {
        MaterialExtendExample example = new MaterialExtendExample();
        example.createCriteria().andBarCodeEqualTo(manyBarCode).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<MaterialExtend> list = materialExtendMapper.selectByExample(example);
        if(list!=null && list.size()>0) {
            for(MaterialExtend me: list) {
                List<MaterialExtend> basicMeList = materialExtendMapperEx.getBasicInfoByMid(me.getMaterialId());
                for(MaterialExtend basicMe: basicMeList) {
                    if(basicMe!=null && !barCode.equals(basicMe.getBarCode())) {
                        return 1;
                    }
                }
            }
        }
        return 0;
    }

    @Override
    public MaterialExtend getInfoByBatchNumber(String batchNumber)throws Exception {
        MaterialExtend example = materialExtendMapper.selectByBatchNumber(batchNumber);
       return example;
    }

    /**
     * 将Json对象的数据赋值到商品拓展对象中
     * @param tempJson
     * @param materialExtend
     */
    private void setMaterialExtend(JSONObject tempJson, MaterialExtend materialExtend){
        //设置商品单位
        if (StringUtils.isNotEmpty(tempJson.getString("commodityUnit"))) {
            materialExtend.setCommodityUnit(tempJson.getString("commodityUnit"));
        }
        //设置商品属性
        if (tempJson.get("sku")!=null) {
            materialExtend.setSku(tempJson.getString("sku"));
        }
        //设置采购价格
        if (StringUtils.isNotEmpty(tempJson.getString("purchaseDecimal"))) {
            materialExtend.setPurchaseDecimal(tempJson.getBigDecimal("purchaseDecimal"));
        }
        //设置零售价格
        if (StringUtils.isNotEmpty(tempJson.getString("commodityDecimal"))) {
            materialExtend.setCommodityDecimal(tempJson.getBigDecimal("commodityDecimal"));
        }
        //设置销售价格
        if (StringUtils.isNotEmpty(tempJson.getString("wholesaleDecimal"))) {
            materialExtend.setWholesaleDecimal(tempJson.getBigDecimal("wholesaleDecimal"));
        }
        //设置最低售价
        if (StringUtils.isNotEmpty(tempJson.getString("lowDecimal"))) {
            materialExtend.setLowDecimal(tempJson.getBigDecimal("lowDecimal"));
        }
        //设置生产日期
        if (StringUtils.isNotEmpty(tempJson.getString("productionDate"))) {
            materialExtend.setProductionDate(tempJson.getDate("productionDate"));
        }
        //设置保质期天数
        if (StringUtils.isNotEmpty(tempJson.getString("expiryNum"))) {
            materialExtend.setExpiryNum(tempJson.getInteger("expiryNum"));
        }
        //设置供应商id
        if (StringUtils.isNotEmpty(tempJson.getString("supplierId"))) {
            materialExtend.setSupplierId(tempJson.getLong("supplierId"));
        }
        //设置商品条码
        if (StringUtils.isNotEmpty(tempJson.getString("barCode"))) {
            materialExtend.setBarCode(tempJson.getString("barCode"));
        }
        //设置批次号
        String batchNumber = DateUtils.dateTimeNow("yyyyMMdd") + RandomHelper.getRandomStr(6);
        materialExtend.setBatchNumber(batchNumber);
        //设置库存
        if (StringUtils.isNotEmpty(tempJson.getString("inventory"))) {
            materialExtend.setInventory(tempJson.getBigDecimal("inventory"));
        }
        //设置仓库id
        if (StringUtils.isNotEmpty(tempJson.getString("depotId"))) {
            materialExtend.setDepotId(tempJson.getLong("depotId"));
        }
        //设置仓位货架
        if (StringUtils.isNotEmpty(tempJson.getString("position"))) {
            materialExtend.setPosition(tempJson.getString("position"));
        }
    }


}
