/*
 *  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.youchain.basicdata.domain.Item;
import com.youchain.businessdata.domain.ItemKey;
import com.youchain.utils.FileUtil;
import com.youchain.utils.PageUtil;
import com.youchain.utils.QueryHelp;
import com.youchain.utils.ValidationUtil;
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;

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

    private final ItemKeyRepository itemKeyRepository;
    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) {
        StringBuilder hql = new StringBuilder(" from ItemKey ik where 1=1 ");
        Map<String, Object> params = new HashMap<>();
        if (item != null) {
            hql.append(" and ik.item.id = :itemId");
            params.put("itemId", item.getId());
        }
        if (propC1 != null && !propC1.isEmpty()) {
            hql.append(" and ik.propC1 = :propC1");
            params.put("propC1", propC1);
        }
        if (orderNumber != null && !orderNumber.isEmpty()) {
            hql.append(" and ik.orderNumber = :orderNumber");
            params.put("orderNumber", orderNumber);
        }
        Query query = entityManager.createQuery(hql.toString());
        params.forEach(query::setParameter);

        Optional<ItemKey> itemKey = query.getResultStream().findFirst();
        if (itemKey.isPresent()) {
            return itemKey.get();
        } else {
            ItemKey newItemKey = new ItemKey();
            newItemKey.setItem(item);
            newItemKey.setDept(item.getDept());
            newItemKey.setPropC1(propC1);
            newItemKey.setOrderNumber(orderNumber);
            create(newItemKey);
            return newItemKey;
        }
    }


}
