package com.ruoyi.quotation.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.basicData.domain.TCorps;
import com.ruoyi.basicData.mapper.TCorpsMapper;
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.quotation.domain.TSeaprice;
import com.ruoyi.quotation.domain.TSeapriceitem;
import com.ruoyi.quotation.mapper.TSeapriceMapper;
import com.ruoyi.quotation.mapper.TSeapriceitemMapper;
import com.ruoyi.quotation.service.ITSeapriceService;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

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

/**
 * 海运价主Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-06-01
 */
@Service
public class TSeapriceServiceImpl implements ITSeapriceService
{
    @Autowired
    private TCorpsMapper tCorpsMapper;

    @Autowired
    private TSeapriceMapper tSeapriceMapper;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    @Autowired
    private TSeapriceitemMapper tSeapriceitemMapper;

    /**
     *  查询海运报价列表信息
     * @param tSeaprice 条件
     * @return  结果
     */
    @Override
    public List<Map<String, Object>> selectTSeapriceMapList(TSeaprice tSeaprice) {
        List<Map<String, Object>> list =tSeapriceMapper.selectTSeapriceMapList(tSeaprice);
        List<Map<String, Object>> result = new ArrayList<>();
        //新增主表内带item逻辑
        for (int i = 0; i < list.size(); i++) {
            Map<String,Object> m = list.get(i);
            //获取主表id
            Long fId = Long.parseLong(String.valueOf(m.get("fId")));
            //获取明细表数据,填充到主表map
            TSeapriceitem tSeapriceitem = new TSeapriceitem();
            tSeapriceitem.setfPid(fId);
            tSeapriceitem.setfType("0");
            m.put("seapriceItem", tSeapriceitemMapper.selectTSeapriceitemList(tSeapriceitem));
            tSeapriceitem.setfType("1");
            m.put("seapriceFees", tSeapriceitemMapper.selectTSeapriceitemList(tSeapriceitem));
            result.add(m);
        }
        return result;
    }

    /**
     * 查询海运报价列表信息
     *
     * @param tSeaprice 条件
     * @return 结果
     */
    @Override
    public List<Map<String, Object>> selectTSeapriceMapListApp(TSeaprice tSeaprice) {
        List<Map<String, Object>> list =tSeapriceMapper.selectTSeapriceMapList(tSeaprice);
        List<Map<String, Object>> result = new ArrayList<>();
        //新增主表内带item逻辑
        for (int i = 0; i < list.size(); i++) {
            Map<String,Object> m = list.get(i);
            //获取主表id
            Long fId = Long.parseLong(String.valueOf(m.get("fId")));
            //获取明细表数据,填充到主表map
            TSeapriceitem tSeapriceitem = new TSeapriceitem();
            tSeapriceitem.setfPid(fId);
            tSeapriceitem.setfType("0");
            m.put("seapriceItem", tSeapriceitemMapper.selectTSeapriceitemListApp(tSeapriceitem));
            result.add(m);
        }
        return result;
    }

    /**
     * 查询海运价主
     * 
     * @param fId 海运价主ID
     * @return 海运价主
     */
    @Override
    public AjaxResult selectTSeapriceById(Long fId)
    {
        TSeaprice tSeaprice = tSeapriceMapper.selectTSeapriceById(fId);
        if (StringUtils.isNull(tSeaprice)) {
            return AjaxResult.error("请确认该单据是否存在");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("seaprice", tSeaprice);
        TSeapriceitem tSeapriceitem = new TSeapriceitem();
        tSeapriceitem.setfPid(fId);
        tSeapriceitem.setfType("0");
        map.put("seapriceItem", tSeapriceitemMapper.selectTSeapriceitemList(tSeapriceitem));
        tSeapriceitem.setfType("1");
        map.put("seapriceFees", tSeapriceitemMapper.selectTSeapriceitemList(tSeapriceitem));
        return AjaxResult.success(map);
    }

    /**
     * 查询海运价主列表
     * 
     * @param tSeaprice 海运价主
     * @return 海运价主
     */
    @Override
    public List<TSeaprice> selectTSeapriceList(TSeaprice tSeaprice)
    {
        return tSeapriceMapper.selectTSeapriceList(tSeaprice);
    }

    /**
     * 保存海运价主
     *
     * @param tSeaprice 海运价主
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult saveTSeaprice(String tSeaprice, String tSeapriceItem, String tSeapriceFlees) {
        Map<String, Object> map = new HashMap<>();
        TSeaprice seaprice = JSONArray.parseObject(tSeaprice, TSeaprice.class);
        // 校验必填项
        AjaxResult ajaxResult = checkSeaprice(seaprice);
        String code = ajaxResult.get("code").toString();
        if ("500".equals(code)) {
            return ajaxResult;
        }
        // 校验是否存在相同规则
        if (tSeapriceMapper.checkSeapriceByValiddate(seaprice) != 0) {
            return AjaxResult.error("该海运价规则已存在");
        }
        Long fId = 0L;
        Long timestamp = DateUtils.getTimestamp(new Date());
        seaprice.setfDateChanged(timestamp.toString() + (int) (Math.random() * 900) + 100);
        if (StringUtils.isNotNull(seaprice.getfId())) {
            if (StringUtils.isNotNull(seaprice.getDeleteItem0())) {
                tSeapriceitemMapper.deleteTSeapriceitemByIds(seaprice.getDeleteItem0());
            }
            if (StringUtils.isNotNull(seaprice.getDeleteItem1())) {
                tSeapriceitemMapper.deleteTSeapriceitemByIds(seaprice.getDeleteItem1());
            }
            seaprice.setUpdateTime(new Date());
            seaprice.setUpdateBy(SecurityUtils.getUsername());
            tSeapriceMapper.updateTSeaprice(seaprice);
            fId = seaprice.getfId();
        } else {
            seaprice.setCreateTime(new Date());
            seaprice.setCreateBy(SecurityUtils.getUsername());
            tSeapriceMapper.insertTSeaprice(seaprice);
            fId = seaprice.getfId();
        }
        map.put("seaprice", seaprice);
        if (StringUtils.isNotEmpty(tSeapriceItem) && !"[]".equalsIgnoreCase(tSeapriceItem)) {
            JSONArray parseArray = JSONArray.parseArray(tSeapriceItem);
            List<TSeapriceitem> tSeapriceitems = JSONObject.parseArray(parseArray.toJSONString(), TSeapriceitem.class);
            // 校验必填项
            AjaxResult result = checkSeapriceItem(tSeapriceitems, "0");
            if ("500".equals(result.get("code").toString())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            // 校验是否存在重复费用id
            List<Long> collect = tSeapriceitems.stream().map(TSeapriceitem::getfFeeid).collect(Collectors.toList());
            long count = collect.stream().distinct().count();
            if (collect.size() != count) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("海运费中存在重复费用,请确认");
            }
            AjaxResult insertOrUpdateItem = insertOrUpdateItem(tSeapriceitems, fId, "0");
            String itemCode = insertOrUpdateItem.get("code").toString();
            if ("500".equals(itemCode)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            map.put("itemList", tSeapriceitems);
        }
        if (StringUtils.isNotEmpty(tSeapriceFlees) && !"[]".equalsIgnoreCase(tSeapriceFlees)) {
            JSONArray parseArray = JSONArray.parseArray(tSeapriceFlees);
            List<TSeapriceitem> tSeapriceitems = JSONObject.parseArray(parseArray.toJSONString(), TSeapriceitem.class);
            // 校验必填项
            AjaxResult result = checkSeapriceItem(tSeapriceitems, "1");
            if ("500".equals(result.get("code").toString())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            // 校验是否存在重复费用id
            List<Long> collect = tSeapriceitems.stream().map(TSeapriceitem::getfFeeid).collect(Collectors.toList());
            long count = collect.stream().distinct().count();
            if (collect.size() != count) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("杂费表中存在重复费用,请确认");
            }
            AjaxResult insertOrUpdateItem = insertOrUpdateItem(tSeapriceitems, fId, "1");
            String itemCode = insertOrUpdateItem.get("code").toString();
            if ("500".equals(itemCode)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            map.put("itemList2", tSeapriceitems);
        }
        return AjaxResult.success(map);
    }

    /**
     * 新增海运价主
     *
     * @param tSeaprice 海运价主
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult insertTSeaprice(String tSeaprice, String tSeapriceItem, String tSeapriceFlees) {
        TSeaprice seaprice = JSONArray.parseObject(tSeaprice, TSeaprice.class);
        // 校验必填项
        AjaxResult ajaxResult = checkSeaprice(seaprice);
        String code = ajaxResult.get("code").toString();
        if ("500".equals(code)) {
            return ajaxResult;
        }
        // 校验是否存在相同规则
        if (tSeapriceMapper.checkSeapriceByValiddate(seaprice) != 0) {
            return AjaxResult.error("该海运价规则已存在");
        }
        Long fId = 0L;
        Long timestamp = DateUtils.getTimestamp(new Date());
        seaprice.setfDateChanged(timestamp.toString() + (int) (Math.random() * 900) + 100);
        if (StringUtils.isNotNull(seaprice.getfId())) {
            if (StringUtils.isNotNull(seaprice.getDeleteItem0())) {
                tSeapriceitemMapper.deleteTSeapriceitemByIds(seaprice.getDeleteItem0());
            }
            if (StringUtils.isNotNull(seaprice.getDeleteItem1())) {
                tSeapriceitemMapper.deleteTSeapriceitemByIds(seaprice.getDeleteItem1());
            }
            seaprice.setUpdateTime(new Date());
            seaprice.setUpdateBy(SecurityUtils.getUsername());
            tSeapriceMapper.updateTSeaprice(seaprice);
            fId = seaprice.getfId();
        } else {
            seaprice.setCreateTime(new Date());
            seaprice.setCreateBy(SecurityUtils.getUsername());
            tSeapriceMapper.insertTSeaprice(seaprice);
            fId = seaprice.getfId();
        }
        if (StringUtils.isEmpty(tSeapriceItem) || "[]".equalsIgnoreCase(tSeapriceItem)) {
            return AjaxResult.error("未找到海运费信息");
        } else {
            JSONArray parseArray = JSONArray.parseArray(tSeapriceItem);
            List<TSeapriceitem> tSeapriceitems = JSONObject.parseArray(parseArray.toJSONString(), TSeapriceitem.class);
            // 校验必填项
            AjaxResult result = checkSeapriceItem(tSeapriceitems, "0");
            if ("500".equals(result.get("code").toString())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            // 校验是否存在重复费用id
            List<Long> collect = tSeapriceitems.stream().map(TSeapriceitem::getfFeeid).collect(Collectors.toList());
            long count = collect.stream().distinct().count();
            if (collect.size() != count) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("海运费中存在重复费用,请确认");
            }
            insertOrUpdateItem(tSeapriceitems, fId, "0");
            String itemCode = ajaxResult.get("code").toString();
            if ("500".equals(itemCode)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
        }
        if (StringUtils.isEmpty(tSeapriceFlees) || "[]".equalsIgnoreCase(tSeapriceFlees)) {
            return AjaxResult.error("未找到杂费信息");
        } else {
            JSONArray parseArray = JSONArray.parseArray(tSeapriceFlees);
            List<TSeapriceitem> tSeapriceitems = JSONObject.parseArray(parseArray.toJSONString(), TSeapriceitem.class);
            // 校验必填项
            AjaxResult result = checkSeapriceItem(tSeapriceitems, "1");
            if ("500".equals(result.get("code").toString())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
            // 校验是否存在重复费用id
            List<Long> collect = tSeapriceitems.stream().map(TSeapriceitem::getfFeeid).collect(Collectors.toList());
            long count = collect.stream().distinct().count();
            if (collect.size() != count) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("杂费表中存在重复费用,请确认");
            }
            insertOrUpdateItem(tSeapriceitems, fId, "1");
            String itemCode = ajaxResult.get("code").toString();
            if ("500".equals(itemCode)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ajaxResult;
            }
        }
        return AjaxResult.success();
    }

    /**
     * 计算海运费
     */
    @Override
    public AjaxResult calculateOceanFreight(TSeaprice tSeaprice) {
        Map<String, Object> map = new HashMap<>();
        if (StringUtils.isNull(tSeaprice.getfQty()) || tSeaprice.getfQty() == 0L) {
            return AjaxResult.error("请维护箱量");
        }
        // 求出海运费金额
        tSeaprice.setfType("0");
        tSeaprice.setfValiddate(new Date());
        BigDecimal oceanAmt = tSeapriceMapper.selectSeapriceItemAmt(tSeaprice);
        // 求出其他运费金额
        tSeaprice.setfType("1");
        BigDecimal otherAmt = tSeapriceMapper.selectSeapriceItemAmt(tSeaprice);
        // 海运费金额合计 * 数量
        oceanAmt = oceanAmt.multiply(new BigDecimal(tSeaprice.getfQty()));
        // 海运费 * 数量 + 其他运费合计
        otherAmt = otherAmt.add(tSeaprice.getRmb().multiply(new BigDecimal(tSeaprice.getfQty())));
        // (海运费合计 + 其他运费合计) / 2
        map.put("amt", oceanAmt.add(otherAmt).divide(new BigDecimal(tSeaprice.getfQty()),2,BigDecimal.ROUND_HALF_UP));
        /*BigDecimal amt = oceanAmt.multiply(new BigDecimal(tSeaprice.getfQty())).add(tSeaprice.getExrate().multiply(new BigDecimal(tSeaprice.getfQty()))).add(otherAmt);
        map.put("amt", amt.divide(new BigDecimal(tSeaprice.getfQty()),2,BigDecimal.ROUND_HALF_UP));*/
        map.put("fleet", tSeapriceMapper.selectSeapriceItem(tSeaprice));
        return AjaxResult.success(map);
    }

    /**
     * 动态查询海运费、汇率
     * @param tSeaprice 条件
     * @return  结果
     */
    @Override
    public AjaxResult changeSelectShippingFee(TSeaprice tSeaprice) {
        tSeaprice.setfValiddate(new Date());
        return AjaxResult.success(tSeapriceMapper.selectShippingFee(tSeaprice));
    }

    /**
     *  查询所需基础资料
     * @return
     */
    @Override
    public AjaxResult getAppBasicInformation() {
        Map<String, Object> map = new HashMap<>();
        map.put("billType", sysDictDataMapper.selectDictDataByType("data_billType"));
        TCorps tCorps = new TCorps();
        tCorps.setfTypeid("\"8\"");
        map.put("corpList", tCorpsMapper.selectTCorpsList(tCorps));
        return AjaxResult.success(map);
    }

    /**
     *  校验主表必填项是否填写
     * @param seaprice
     * @return
     */
    public AjaxResult checkSeaprice (TSeaprice seaprice) {
        if (StringUtils.isNull(seaprice.getfBilltype())) {
            return AjaxResult.error("请维护业务类型");
        }
        if (StringUtils.isNull(seaprice.getfCorpid())) {
            return AjaxResult.error("请维护船公司");
        }
        if (StringUtils.isNull(seaprice.getPolId())) {
            return AjaxResult.error("请维护起运港");
        }
        if (StringUtils.isNull(seaprice.getPodId())) {
            return AjaxResult.error("请维护目的港");
        }
        if (StringUtils.isNull(seaprice.getfValiddate())) {
            return AjaxResult.error("请维护有效期");
        }
        if (DateUtils.belongCalendarBefore(seaprice.getfValiddate())) {
            return AjaxResult.error("有效期时间不得早于当天");
        }
        return AjaxResult.success();
    }

    /**
     *  校验明细表必填项是否填写
     * @param tSeapriceitems
     * @return
     */
    public AjaxResult checkSeapriceItem (List<TSeapriceitem> tSeapriceitems, String fType) {
        int line = 1;
        for (TSeapriceitem item : tSeapriceitems) {
            if (StringUtils.isNull(item.getfFeeid())) {
                if ("0".equalsIgnoreCase(fType)) {
                    return AjaxResult.error("请维护海运费表第"+line+ "行未选择费用");
                }
                return AjaxResult.error("请维护杂费表第"+line+ "行未选择费用");
            }
        }
        line++;
        return AjaxResult.success();
    }

    /**
     *  新增或更新明细信息
     * @param tSeapriceitems    明细信息
     * @param fId               主表id
     * @param fType             类型
     * @return  结果
     */
    @Transactional
    public AjaxResult insertOrUpdateItem (List<TSeapriceitem> tSeapriceitems, Long fId, String fType) {
        for (TSeapriceitem item : tSeapriceitems) {
            item.setfPid(fId);
            item.setfType(fType);
            if (StringUtils.isNull(item.getfId())) {
                item.setCreateTime(new Date());
                item.setCreateBy(SecurityUtils.getUsername());
                tSeapriceitemMapper.insertTSeapriceitem(item);
            } else {
                item.setUpdateTime(new Date());
                item.setUpdateBy(SecurityUtils.getUsername());
                tSeapriceitemMapper.updateTSeapriceitem(item);
            }
        }
        return AjaxResult.success(tSeapriceitems);
    }

    /**
     * 修改海运价主
     * 
     * @param tSeaprice 海运价主
     * @return 结果
     */
    @Override
    public int updateTSeaprice(TSeaprice tSeaprice)
    {
        tSeaprice.setUpdateTime(DateUtils.getNowDate());
        return tSeapriceMapper.updateTSeaprice(tSeaprice);
    }

    /**
     * 批量删除海运价主
     * 
     * @param fIds 需要删除的海运价主ID
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult deleteTSeapriceByIds(Long[] fIds)
    {
        for (Long l : fIds) {
            tSeapriceitemMapper.deleteTSeapriceitemByfPid(l);
            tSeapriceMapper.deleteTSeapriceById(l);
        }
        return AjaxResult.success();
    }

    /**
     * 删除海运价主信息
     * 
     * @param fId 海运价主ID
     * @return 结果
     */
    @Override
    public int deleteTSeapriceById(Long fId)
    {
        return tSeapriceMapper.deleteTSeapriceById(fId);
    }
}
