package com.ruoyi.shipping.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.shipping.domain.TCntr;
import com.ruoyi.shipping.domain.TCtnprice;
import com.ruoyi.shipping.domain.TCtnpriceItems;
import com.ruoyi.shipping.mapper.TCntrMapper;
import com.ruoyi.shipping.mapper.TCtnpriceItemsMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.shipping.mapper.TVoyageMapper;
import com.ruoyi.shipping.domain.TVoyage;
import com.ruoyi.shipping.service.ITVoyageService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

/**
 * 航次Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-04-02
 */
@Service
public class TVoyageServiceImpl implements ITVoyageService 
{
    @Autowired
    private TVoyageMapper tVoyageMapper;
    @Autowired
    private TCtnpriceItemsMapper tCtnpriceItemsMapper;
    @Autowired
    private TCntrMapper tCntrMapper;

    /**
     * 查询航次
     * 
     * @param fId 航次ID
     * @return 航次
     */
    @Override
    public TVoyage selectTVoyageById(Long fId)
    {
        TVoyage voyage = tVoyageMapper.selectTVoyageById(fId);//航次信息
        TCtnpriceItems tCtnpriceItems = new TCtnpriceItems();
        tCtnpriceItems.setfPid(fId);
        List<TCtnpriceItems> ctnpriceItems = tCtnpriceItemsMapper.selectTCtnpriceItemsList(tCtnpriceItems);
        voyage.settCtnpriceItemsList(ctnpriceItems);
        return voyage;
    }

    /**
     * 查询航次列表
     * 
     * @param tVoyage 航次
     * @return 航次
     */
    @Override
    public List<TVoyage> selectTVoyageList(TVoyage tVoyage)
    {
        return tVoyageMapper.selectTVoyageList(tVoyage);
    }

    @Override
    public List<TVoyage> freightList(TVoyage tVoyage) {
        List<TVoyage> tVoyages = new ArrayList<>();
        tVoyages = tVoyageMapper.selectTVoyageListNew(tVoyage);
        tVoyages = tVoyages.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TVoyage -> TVoyage.getfPortofloadid() + ";"+ TVoyage.getfDistinationid()+ ";"+ TVoyage.getfPortoftransshipment()))), ArrayList::new));
        if (CollectionUtils.isNotEmpty(tVoyages)){
            for (TVoyage voyage : tVoyages) {
                voyage.setTwenty(tCtnpriceItemsMapper.selectMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "20GP"));
                voyage.setFortyHc(tCtnpriceItemsMapper.selectMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "40HC"));
                voyage.setFortyRh(tCtnpriceItemsMapper.selectMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "40RH"));
                TVoyage yage = new TVoyage();
                yage.setfPortofloadid(voyage.getfPortofloadid());
                yage.setfDistinationid(voyage.getfDistinationid());
                if (voyage.getfPortoftransshipment() != null){
                    yage.setfPortoftransshipment(voyage.getfPortoftransshipment());
                }else {
                    yage.setEmpty(1L);
                }
                List<TVoyage> freightselect = this.freightselect(yage);
                if (CollectionUtils.isNotEmpty(freightselect)){
                    voyage.setFreight(freightselect);
                }
            }
        }
        return tVoyages;
    }

    @Override
    public List<TVoyage> freightselect(TVoyage tVoyage) {
        List<TVoyage> tVoyages = tVoyageMapper.selectTVoyageListNew(tVoyage);
        List<TVoyage> tVoyagesList = new ArrayList<>();
        Long fPortoftransshipment = null;
        if (CollectionUtils.isNotEmpty(tVoyages)){
            for (TVoyage voyage : tVoyages) {
                if (voyage.getfPortoftransshipment()!= null){
                    fPortoftransshipment = voyage.getfPortoftransshipment();
                }
                List<String> list = tCtnpriceItemsMapper.selectPriceMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "20GP",fPortoftransshipment);
                List<String> money = tCtnpriceItemsMapper.selectPriceMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "40HC",fPortoftransshipment);
                List<String> priceMoney = tCtnpriceItemsMapper.selectPriceMoney(voyage.getfPortofloadid(), voyage.getfDistinationid(), "40RH",fPortoftransshipment);
                if (CollectionUtils.isNotEmpty(list)){
                    for (String s : list) {
                        if (CollectionUtils.isNotEmpty(money)){
                            for (String m : money) {
                                if (CollectionUtils.isNotEmpty(priceMoney)){
                                    for (String p : priceMoney) {
                                        TVoyage yage = new TVoyage();
                                        BeanUtils.copyProperties(voyage,yage);
                                        yage.setTwenty(s);
                                        yage.setFortyHc(m);
                                        yage.setFortyRh(p);
                                        tVoyagesList.add(yage);
                                    }
                                }else {
                                    TVoyage yage = new TVoyage();
                                    BeanUtils.copyProperties(voyage,yage);
                                    yage.setTwenty(s);
                                    yage.setFortyHc(m);
                                    yage.setFortyRh("0");
                                    tVoyagesList.add(yage);
                                }

                            }
                        }else {
                            if (CollectionUtils.isNotEmpty(priceMoney)){
                                for (String p : priceMoney) {
                                    TVoyage yage = new TVoyage();
                                    BeanUtils.copyProperties(voyage,yage);
                                    yage.setTwenty(s);
                                    yage.setFortyHc("0");
                                    yage.setFortyRh(p);
                                    tVoyagesList.add(yage);
                                }
                            }else {
                                TVoyage yage = new TVoyage();
                                BeanUtils.copyProperties(voyage,yage);
                                yage.setTwenty(s);
                                yage.setFortyHc("0");
                                yage.setFortyRh("0");
                                tVoyagesList.add(yage);
                            }
                        }

                    }
                }else {
                    if (CollectionUtils.isNotEmpty(money)){
                        for (String m : money) {
                            if (CollectionUtils.isNotEmpty(priceMoney)){
                                for (String p : priceMoney) {
                                    TVoyage yage = new TVoyage();
                                    BeanUtils.copyProperties(voyage,yage);
                                    yage.setTwenty("0");
                                    yage.setFortyHc(m);
                                    yage.setFortyRh(p);
                                    tVoyagesList.add(yage);
                                }
                            }else {
                                TVoyage yage = new TVoyage();
                                BeanUtils.copyProperties(voyage,yage);
                                yage.setTwenty("0");
                                yage.setFortyHc(m);
                                yage.setFortyRh("0");
                                tVoyagesList.add(yage);
                            }
                        }
                    }else {
                        if (CollectionUtils.isNotEmpty(priceMoney)){
                            for (String p : priceMoney) {
                                TVoyage yage = new TVoyage();
                                BeanUtils.copyProperties(voyage,yage);
                                yage.setTwenty("0");
                                yage.setFortyHc("0");
                                yage.setFortyRh(p);
                                tVoyagesList.add(yage);
                            }
                        }else {
                            TVoyage yage = new TVoyage();
                            BeanUtils.copyProperties(voyage,yage);
                            yage.setTwenty("0");
                            yage.setFortyHc("0");
                            yage.setFortyRh("0");
                            tVoyagesList.add(yage);
                        }
                    }
                }

            }
        }
        return tVoyagesList;
    }

    /**
     * 新增航次
     * 
     * @param tVoyage 航次
     * @return 结果
     */
    @Override
    public int insertTVoyage(TVoyage tVoyage)
    {
        tVoyage.setCreateTime(DateUtils.getNowDate());
        tVoyage.setCreateBy(SecurityUtils.getUsername());
        if (tVoyage.getfDays()==null){
            long dateDay = DateUtils.getDateDay(tVoyage.getfEta(),tVoyage.getfEtd());
            tVoyage.setfDays(dateDay);
        }
        return tVoyageMapper.insertTVoyage(tVoyage);
    }

    /**
     * 修改航次
     * 
     * @param tVoyage 航次
     * @return 结果
     */
    @Override
    public int updateTVoyage(TVoyage tVoyage)
    {
        tVoyage.setUpdateTime(DateUtils.getNowDate());
        tVoyage.setUpdateBy(SecurityUtils.getUsername());
        if (tVoyage.getfDays()==null){
            long dateDay = DateUtils.getDateDay(tVoyage.getfEta(), tVoyage.getfEtd());
            tVoyage.setfDays(dateDay);
        }
        return tVoyageMapper.updateTVoyage(tVoyage);
    }

    /**
     * 批量删除航次
     * 
     * @param fIds 需要删除的航次ID
     * @return 结果
     */
    @Override
    public int deleteTVoyageByIds(Long[] fIds)
    {
        return tVoyageMapper.deleteTVoyageByIds(fIds);
    }

    /**
     * 删除航次信息
     * 
     * @param fId 航次ID
     * @return 结果
     */
    @Override
    public int deleteTVoyageById(Long fId)
    {
        return tVoyageMapper.deleteTVoyageById(fId);
    }

    @Override
    public String selectTVoyagefNo(TVoyage tVoyage) {
        TVoyage voyage = tVoyageMapper.selectTVoyagefNo(tVoyage);
        if (StringUtils.isNotNull(voyage) && !voyage.getfId().equals(voyage.getfId())) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public List<Map<String, Object>> selectTVoyagefNumber(TVoyage tVoyage) {
        return tVoyageMapper.selectTVoyagefNumber(tVoyage);
    }

    @Override
    public List<TVoyage> selectMessage(TVoyage tVoyage) {
        List<TVoyage> tVoyages = new ArrayList<>();
        List<TVoyage> voyages = tVoyageMapper.selectMessage(tVoyage);
        if (CollectionUtils.isNotEmpty(voyages)){
            for (TVoyage voyage : voyages) {
                TVoyage tVoyageByFid = tVoyageMapper.selectTVoyageByFid(voyage.getfId());
                tVoyages.add(tVoyageByFid);
            }
        }
        return tVoyages;
    }

    @Override
    @Transactional
    public AjaxResult insertMessage(String tVoyage, String tCtnpriceItems) {
        TVoyage voyage = JSONArray.parseObject(tVoyage, TVoyage.class);
        if (StringUtils.isEmpty(voyage.getfNo())){
            return AjaxResult.error("航次不能为空");
        }
        if (voyage.getfPortofloadid() == null){
            return AjaxResult.error("装货港不能为空");
        }
        /*if (tVoyage.getfPortofdischargeid() == null){
            return AjaxResult.error("卸货港不能为空");
        }*/
        if (voyage.getfDistinationid() == null){
            return AjaxResult.error("目的港不能为空");
        }
        if (voyage.getfEtd() == null){
            return AjaxResult.error("预计开船日期不能为空");
        }
        if (voyage.getfEta() == null){
            return AjaxResult.error("预计到达日期不能为空");
        }
        if (voyage.getfDucomentrayoffdate() == null){
            return AjaxResult.error("截单日期不能为空");
        }
        if (StringUtils.isEmpty(voyage.getfTel())){
            return AjaxResult.error("电话不能为空");
        }
        long dateDay = DateUtils.getDateDay(voyage.getfEta(),voyage.getfEtd());
        voyage.setfDays(dateDay);
        if (voyage.getfId() == null){
            //航次 起运港 目的港 中转港 预计开船日期不能重复
            List<TVoyage> tVoyages = tVoyageMapper.selectTVoyageMessage(voyage.getfNo(), voyage.getfPortofloadid(), voyage.getfDistinationid(),
                    voyage.getfPortoftransshipment(), voyage.getfEtd());
            if (CollectionUtils.isNotEmpty(tVoyages)){
                return AjaxResult.error("航次信息重复");
            }
            voyage.setCreateTime(DateUtils.getNowDate());
            voyage.setCreateBy(SecurityUtils.getUsername());
            tVoyageMapper.insertTVoyage(voyage);
        }else {
            voyage.setUpdateTime(DateUtils.getNowDate());
            voyage.setUpdateBy(SecurityUtils.getUsername());
            tVoyageMapper.updateTVoyage(voyage);
        }
        //tCtnpriceItemsMapper.deleteTCtnpriceItemsByfPid(voyage.getfId());
        JSONArray warehouseJSON = JSONArray.parseArray(tCtnpriceItems);
        List<TCtnpriceItems> ctnpriceItems = JSONObject.parseArray(warehouseJSON.toJSONString(), TCtnpriceItems.class);
        if (CollectionUtils.isNotEmpty(ctnpriceItems)){
            for (TCtnpriceItems ctnpriceItem : ctnpriceItems) {
                if (ctnpriceItem.getfCntrid() == null){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error("集装箱类型不能为空");
                }
                if (ctnpriceItem.getfPrice() == null){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.error("单价不能为空");
                }
                if (ctnpriceItem.getfId() == null){
                    List<TCtnpriceItems> ctnpriceItemsList = tCtnpriceItemsMapper.selectItemMeaasge(voyage.getfId(), ctnpriceItem.getfCntrid());
                    if (CollectionUtils.isNotEmpty(ctnpriceItemsList)){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        TCntr cntr = tCntrMapper.selectTCntrById(ctnpriceItem.getfCntrid());
                        return AjaxResult.error("运价中集装箱编号"+cntr.getfNo()+"重复，请确认");
                    }
                    ctnpriceItem.setfPid(voyage.getfId());
                    ctnpriceItem.setCreateTime(DateUtils.getNowDate());
                    ctnpriceItem.setCreateBy(SecurityUtils.getUsername());
                    int items = tCtnpriceItemsMapper.insertTCtnpriceItems(ctnpriceItem);
                }else {
                    ctnpriceItem.setfPid(voyage.getfId());
                    ctnpriceItem.setUpdateTime(DateUtils.getNowDate());
                    ctnpriceItem.setUpdateBy(SecurityUtils.getUsername());
                    int items = tCtnpriceItemsMapper.updateTCtnpriceItems(ctnpriceItem);
                }
            }
        }
        return AjaxResult.success();
    }

    @Override
    public List<TVoyage> createOrder(TVoyage tVoyage) {
        //查询所有的航次 然后按 起运港 中转港 目的港 去重
        List<TVoyage> tVoyages = new ArrayList<>();
        tVoyages = tVoyageMapper.selectTVoyageListNew(tVoyage);
        tVoyages = tVoyages.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TVoyage -> TVoyage.getfPortofloadid() + ";"+ TVoyage.getfDistinationid()+ ";"+ TVoyage.getfPortoftransshipment()))), ArrayList::new));
        if (CollectionUtils.isNotEmpty(tVoyages)){
            for (TVoyage voyage : tVoyages) {
                //然后根据 起运港 中转港  目的港 获取所有的航次ID
                List<Long> longs = tVoyageMapper.selectTVoyageIds(voyage);
                //然后根据航次ID去运价详情表中获取对应箱型的最低价
               if (CollectionUtils.isNotEmpty(longs)){
                   voyage.setTwenty(tCtnpriceItemsMapper.selectMinMoney("20GP",longs));
                   voyage.setFortyHc(tCtnpriceItemsMapper.selectMinMoney("40HC",longs));
                   voyage.setFortyRh(tCtnpriceItemsMapper.selectMinMoney("40RH",longs));
                   List<TVoyage> freightselect = new ArrayList<>();
                   //然后根据 所有的航次ID 获取对应的航次信息以及对应箱型的价格
                   for (Long aLong : longs) {
                       TVoyage tVoyageByFid = tVoyageMapper.selectTVoyageByFid(aLong);
                       if (tVoyageByFid != null){
                           freightselect.add(tVoyageByFid);
                       }
                   }
                   voyage.setFreight(freightselect);
               }
            }
        }
        return tVoyages;
    }

    @Override
    public List<Map<String, Object>> shipDynamic() {
        return tVoyageMapper.shipDynamic();
    }
}
