/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.youchain.businessdata.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.youchain.basicdata.domain.Item;
import com.youchain.basicdata.domain.Point;
import com.youchain.businessdata.domain.Inventory;
import com.youchain.businessdata.domain.ItemKey;
import com.youchain.businessdata.domain.Task;
import com.youchain.businessdata.repository.InventoryRepository;
import com.youchain.businessdata.service.InventoryService;
import com.youchain.exception.handler.ApiResult;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.businessdata.repository.ItemKeyRepository;
import com.youchain.businessdata.service.ItemKeyService;
import com.youchain.businessdata.service.dto.ItemKeyDto;
import com.youchain.businessdata.service.dto.ItemKeyQueryCriteria;
import com.youchain.businessdata.service.mapstruct.ItemKeyMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author houjianlan
* @date 2023-08-21
**/
@Service
@RequiredArgsConstructor
public class ItemKeyServiceImpl implements ItemKeyService {

    private final ItemKeyRepository itemKeyRepository;
    private final InventoryRepository inventoryRepository;
    private final InventoryService inventoryService;
    private final ItemKeyMapper itemKeyMapper;
    private final EntityManager entityManager;

    @Override
    public Map<String, Object> queryAll(ItemKeyQueryCriteria criteria, Pageable pageable) {
        Page<ItemKey> page = itemKeyRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(itemKeyMapper::toDto));
    }

    @Override
    public List<ItemKeyDto> queryAll(ItemKeyQueryCriteria criteria) {
        return itemKeyMapper.toDto(itemKeyRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public ItemKeyDto findById(Long id) {
        ItemKey itemKey = itemKeyRepository.findById(id).orElseGet(ItemKey::new);
        ValidationUtil.isNull(itemKey.getId(), "ItemKey", "id", id);
        return itemKeyMapper.toDto(itemKey);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ItemKeyDto create(ItemKey resources) {
        return itemKeyMapper.toDto(itemKeyRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ItemKey resources) {
        ItemKey itemKey = itemKeyRepository.findById(resources.getId()).orElseGet(ItemKey::new);
        ValidationUtil.isNull(itemKey.getId(), "ItemKey", "id", resources.getId());
        itemKey.copy(resources);
        itemKeyRepository.save(itemKey);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            itemKeyRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<ItemKeyDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (ItemKeyDto itemKey : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("物料序号", itemKey.getItem());
            map.put("批次号", itemKey.getPropC1());
            map.put("序列号", itemKey.getPropC2());
            map.put("属性3", itemKey.getPropC3());
            map.put("属性4", itemKey.getPropC4());
            map.put("属性5", itemKey.getPropC5());
            map.put("属性6", itemKey.getPropC6());
            map.put("生产日期", itemKey.getPropD1());
            map.put("到期日期", itemKey.getPropD2());
            map.put("仓库ID", itemKey.getDept());
            map.put("创建人", itemKey.getCreateBy());
            map.put("修改人", itemKey.getUpdateBy());
            map.put("创建时间", itemKey.getCreateTime());
            map.put("修改时间", itemKey.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ItemKey getItemKey(Item item, String propC1,String orderNumber) {
        //生成itemKey
        String hql = " from ItemKey ik where 1=1 ";
        if (item != null) {
            hql += " and ik.item.id=" + item.getId() + " ";
        }
        if (propC1 != null && propC1.length() > 0) {
            hql += " and ik.propC1='" + propC1 + "' ";
        }
        if (orderNumber != null && orderNumber.length() > 0) {
            hql += " and ik.orderNumber='" + orderNumber + "' ";
        }
        Query query = entityManager.createQuery(hql);
        List<ItemKey> itemKeyList = query.getResultList();
        ItemKey itemKey = null;
        if (itemKeyList.size() > 0) {
            itemKey = itemKeyList.get(0);
        } else {
            //创建ItemKey
            itemKey = new ItemKey();
            itemKey.setItem(item);
            itemKey.setDept(item.getDept());
            itemKey.setPropC1(propC1);
            itemKey.setOrderNumber(orderNumber);
            this.create(itemKey);
        }
        return itemKey;
    }

    @Override
    public ItemKey getItemKey(Item item, String propC1, String propC2, String propC3, String propC4, String propC5, String propC6,String propC7) {
        ItemKey itemKey;
        itemKey = itemKeyRepository.getByItemKey(item.getId(),propC1,propC2,propC3,propC4,propC5,propC6);
        if (itemKey==null){
            itemKey=new ItemKey();
            itemKey.setItem(item);
            itemKey.setPropC1(propC1);
            itemKey.setPropC2(propC2);
            itemKey.setPropC3(propC3);
            itemKey.setPropC4(propC4);
            itemKey.setPropC5(propC5);
            itemKey.setPropC7(propC7);
            itemKey.setPropC6(propC6.toString());
            itemKeyRepository.save(itemKey);
        }
        return itemKey;
    }

    @Override
    public ApiResult getItemKeyByInv(List<Long> ids) {
        StringBuffer data = new StringBuffer();
        List<ItemKey> itemKeyList=itemKeyRepository.getByInv(ids);
        for (int i = 0; i < itemKeyList.size(); i++) {
            ItemKey itemKey=itemKeyList.get(i);
            if (data.length()<1){
                data.append(itemKey.getPropC6());
            }else {
                data.append(","+itemKey.getPropC6());
            }
        }
        return ApiResult.fail(200,"操作成功",data);
    }

    @Override
    public ApiResult devan(JSONObject req) {
        String textPropC6=req.getString("textPropC6");
        String text1PropC6=req.getString("text1PropC6");
        String[] arrPropC6=textPropC6.split(",");
        List<String> arr1PropC6= Arrays.asList(text1PropC6.split(","));
        List<String> arr2PropC6=new ArrayList<>();
        for (int i = 0; i < arrPropC6.length; i++) {
            boolean flag=true;
            for (int j = 0; j < arr1PropC6.size(); j++) {
                if (arrPropC6[i].toString().equals(arr1PropC6.get(j).toString())){
                    flag=false;
                    break;
                }
            }
            if (flag) {
                arr2PropC6.add(arrPropC6[i]);
            }
        }

        JSONObject data=new JSONObject();
        data.put("textPropC6",arrPropC6);
        StringBuffer sb1PropC6 = getStringBuffer(arr1PropC6);
        StringBuffer sb2PropC6 = getStringBuffer(arr2PropC6);
        data.put("text1PropC6",sb1PropC6);
        data.put("text2PropC6",sb2PropC6);
        System.out.println("返回:"+data);
        return ApiResult.fail(200, "操作成功", data);
    }

    private static StringBuffer getStringBuffer(List<String> arr1PropC6) {
        StringBuffer sb1PropC6=new StringBuffer();
        for (int i = 0; i < arr1PropC6.size(); i++) {
            if (sb1PropC6.length()<1){
                sb1PropC6.append(arr1PropC6.get(i));
            }else {
                sb1PropC6.append(","+ arr1PropC6.get(i));
            }
        }
        return sb1PropC6;
    }

    @Override
    public ApiResult devanPropC6(JSONObject req) {
        String startPropC6=req.getString("startPropC6");
        String endPropC6=req.getString("endPropC6");
        int startPropInt = Integer.parseInt(startPropC6, 16);
        int endPropInt = Integer.parseInt(endPropC6, 16);
        StringBuffer text1PropC6=new StringBuffer();
        for (int i = startPropInt; i <endPropInt ; i++) {
            String hex = String.format("%04X", i); // %04X表示最小宽度为4，使用大写字母的16进制
            if (text1PropC6.length()<1){
                text1PropC6.append(hex);
            }else {
                text1PropC6.append(","+hex);
            }
        }
        JSONObject data = new JSONObject();
        data.put("text1PropC6", text1PropC6);
        System.out.println("data:"+data);
        return ApiResult.fail(200, "操作成功", data);
    }

    @Override
    public ApiResult devanning(JSONObject req) {
        JSONArray invIds=req.getJSONArray("invIds");//invIds
        String text1PropC6=req.getString("text1PropC6");
        String text2PropC6=req.getString("text2PropC6");
        for (int i = 0; i < invIds.size(); i++) {
            Long invId=invIds.getLong(i);
            Inventory startInventory=inventoryRepository.getById(invId);
            //拆托后-库位位置
            Point startPoint=startInventory.getPoint();
            Point endPoint=null;
            //拆托后-库存数量
            Integer startQuan = text1PropC6.split(",").length;
            Integer endQuan = text2PropC6.split(",").length;
            //拆托后-RFID票
            ItemKey startItemKey=startInventory.getItemKey();
            ItemKey endItemKey=getItemKey(startItemKey.getItem(), startItemKey.getPropC1(), startItemKey.getPropC2(), startItemKey.getPropC3(), startItemKey.getPropC4(), String.format("%04X", endQuan)+"", text2PropC6,"");
            //更新原来的RFID票
            startItemKey.setPropC5(String.format("%04X", startQuan)+"");
            startItemKey.setPropC6(text1PropC6);
            itemKeyRepository.save(startItemKey);
            //更新原库存
            startInventory.setQuantity(Double.valueOf(startQuan));
            inventoryRepository.save(startInventory);
            //生成拆托库存
            Inventory inventory = inventoryService.getInventory(Double.valueOf(endQuan), endItemKey.getId(), null, BizStatus.MODIFY_LOT);
        }
        return ApiResult.fail(200, "操作成功", null);
    }


}