/*
 *  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.basicdata.domain.Point;
import com.youchain.basicdata.domain.Stock;
import com.youchain.basicdata.repository.StockRepository;
import com.youchain.basicdata.service.StockService;
import com.youchain.businessdata.domain.AsnDetail;
import com.youchain.businessdata.service.TaskService;
import com.youchain.modules.quartz.utils.TimeNumberUtils;
import com.youchain.utils.*;
import lombok.RequiredArgsConstructor;
import com.youchain.businessdata.repository.AsnDetailRepository;
import com.youchain.businessdata.service.AsnDetailService;
import com.youchain.businessdata.service.dto.AsnDetailDto;
import com.youchain.businessdata.service.dto.AsnDetailQueryCriteria;
import com.youchain.businessdata.service.mapstruct.AsnDetailMapper;
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.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import cn.hutool.core.date.DateUtil;

/**
 * @author hjl
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2023-08-14
 **/
@Service
@RequiredArgsConstructor
public class AsnDetailServiceImpl implements AsnDetailService {

    private final AsnDetailRepository asnDetailRepository;
    private final StockRepository stockRepository;
    private final AsnDetailMapper asnDetailMapper;
    private final EntityManager entityMapper;
    private final TaskService taskService;

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

    @Override
    public List<AsnDetailDto> queryAll(AsnDetailQueryCriteria criteria) {
        return asnDetailMapper.toDto(asnDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public AsnDetailDto findById(Long id) {
        AsnDetail asnDetail = asnDetailRepository.findById(id).orElseGet(AsnDetail::new);
        ValidationUtil.isNull(asnDetail.getId(), "AsnDetail", "id", id);
        return asnDetailMapper.toDto(asnDetail);
    }

    @Override
    @Transactional
    public AsnDetail getEntity(Long id) {
        AsnDetail asnDetail = asnDetailRepository.findById(id).orElseGet(AsnDetail::new);
        return asnDetail;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AsnDetailDto create(AsnDetail resources) {
        return asnDetailMapper.toDto(asnDetailRepository.save(resources));
    }

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

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            AsnDetail asnDetail = asnDetailRepository.getById(id);
            if (asnDetail.getStatus().equals("OPEN")) {
                //修改容器状态
                Stock stock = asnDetailRepository.getById(id).getStock();
                stock.setStatus("FREE");
                stockRepository.save(stock);
                //删除关联表的数据 入库单明细(data_asn_detail)
                if (taskService.getAsnDetailIdToId(id) != null) {
                    taskService.deleteById(taskService.getAsnDetailIdToId(id));
                }
                asnDetailRepository.deleteById(id);
            }
        }
    }

    @Override
    public void download(List<AsnDetailDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (AsnDetailDto asnDetail : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("订单序号", asnDetail.getAsnId());
            map.put("物料", asnDetail.getItem());
            map.put("容器", asnDetail.getStock());
            map.put("点位", asnDetail.getPoint());
            map.put("行号", asnDetail.getLineNo());
            map.put("MO票", asnDetail.getPo());
            map.put("状态", asnDetail.getStatus());
            map.put("订单数量", asnDetail.getOrderQty());
            map.put("收货数量", asnDetail.getReceivedQty());
            map.put("移位数量", asnDetail.getMoveQty());
            map.put("上架数量", asnDetail.getPutQty());
            map.put("重量", asnDetail.getWeight());
            map.put("体积", asnDetail.getVolume());
            map.put("备注", asnDetail.getRemark());
            map.put("批次号", asnDetail.getPropC1());
            map.put("序列号", asnDetail.getPropC2());
            map.put("属性3", asnDetail.getPropC3());
            map.put("属性4", asnDetail.getPropC4());
            map.put("属性5", asnDetail.getPropC5());
            map.put("属性6", asnDetail.getPropC6());
            map.put("生产日期", asnDetail.getPropD1());
            map.put("到期日期", asnDetail.getPropD2());
            map.put("仓库ID", asnDetail.getDept());
            map.put("来源名称", asnDetail.getSourceName());
            map.put("来源序号", asnDetail.getSourceId());
            map.put("创建人", asnDetail.getCreateBy());
            map.put("修改人", asnDetail.getUpdateBy());
            map.put("创建时间", asnDetail.getCreateTime());
            map.put("修改时间", asnDetail.getUpdateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public AsnDetail toEntity(AsnDetailDto detailDto) {
        return asnDetailMapper.toEntity(detailDto);
    }

    @Override
    public AsnDetail findByStock(String code) {
        String hql = "select d from AsnDetail d where d.stock.code='" + code + "' and d.status='" + BizStatus.OPEN + "'";
        Query query = entityMapper.createQuery(hql);
        List<AsnDetail> ts = query.getResultList();
        if (ts.size() > 0) {
            return ts.get(0);
        }
        return null;
    }

    public List<Object[]> queryIn(String type, String date, String zoneType) {
        String hql = "";
        if (type.equals("Day")) {
            hql = "select sum(d.orderQty),sum(d.receivedQty) from AsnDetail d " +
                    " where DATE_FORMAT(d.createTime,'%Y-%m-%d')=DATE_FORMAT(now(),'%Y-%m-%d')";
        } else if (type.equals("Month")) {
            hql = "select sum(d.orderQty),sum(d.receivedQty) from AsnDetail d " +
                    " where DATE_FORMAT(d.createTime,'%Y-%m')=DATE_FORMAT(now(),'%Y-%m')";
        } else if (type.equals("InOutDay")) {
            hql = "select DATE_FORMAT(d.createTime,'%Y-%m-%d'),sum(d.receivedQty) from AsnDetail d " +
                    " where DATE_FORMAT(d.createTime,'%Y-%m-%d')>='" + date + "' " +
                    " group by DATE_FORMAT(d.createTime,'%Y-%m-%d')";
        }
        Query query = entityMapper.createQuery(hql);
        List<Object[]> ts = query.getResultList();
        return ts;
    }


    @Override
    public AsnDetail createAsnDetail(Item item, Stock stock, Point srcPoint, String propC1, String gdh, String propC3, Timestamp propD1, Double orderQty, String Po) {
        AsnDetail asnDetail = new AsnDetail();
        asnDetail.setItem(item);
        asnDetail.setLineNo(1l);
        asnDetail.setStatus(BizStatus.OPEN);
        asnDetail.setOrderQty(orderQty);
        asnDetail.setDept(item.getDept());
        asnDetail.setStock(stock);
        asnDetail.setPoint(srcPoint);
        asnDetail.setPropC1(propC1);
        asnDetail.setOrderNumber(gdh);
        asnDetail.setPropC3(propC3);
        asnDetail.setPropD1(propD1);
        asnDetail.setPo(Po);
        create(asnDetail);
        return asnDetail;
    }

    @Override
    public AsnDetail createAsnDetail(Item item, Stock stock) {
        AsnDetail asnDetail = new AsnDetail();
        asnDetail.setItem(item);
        asnDetail.setLineNo(1L);
        asnDetail.setStatus(BizStatus.RECEIVED);
        asnDetail.setOrderQty(item.getExtendD1());
        asnDetail.setReceivedQty(item.getExtendD1());
        asnDetail.setDept(item.getDept());
        String propC1 = DateUtil.format(cn.hutool.core.date.DateUtil.date(), "yyyyMMdd");
        asnDetail.setPropC1(propC1);
        asnDetail.setStock(stock);
        asnDetail.setPo(TimeNumberUtils.getRCCode());
        create(asnDetail);
        return asnDetail;
    }

    @Override
    public boolean existsByboxNumber(String boxNumber) {
        String hql = " from AsnDetail ad where ad.orderNumber=:boxNumber ";
        Query query = entityMapper.createQuery(hql);
        query.setParameter("boxNumber", boxNumber);
        List<AsnDetail> asnDetailList = query.getResultList();
        if (asnDetailList.size() > 0) {
            return true;
        }
        return false;
    }
}
