package com.ruoyi.basicData.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.TWarehouse;
import com.ruoyi.basicData.domain.TWarehouseArea;
import com.ruoyi.basicData.mapper.TWarehouseAreaMapper;
import com.ruoyi.basicData.mapper.TWarehouseMapper;
import com.ruoyi.basicData.service.ITWarehouseService;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.warehouseBusiness.domain.TWarehouseBills;
import com.ruoyi.warehouseBusiness.mapper.TWarehouseBillsMapper;
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 2020-12-11
 */
@Service
public class TWarehouseServiceImpl implements ITWarehouseService {
    @Autowired
    private TWarehouseMapper tWarehouseMapper;

    @Autowired
    private TWarehouseAreaMapper tWarehouseAreaMapper;

    @Autowired
    private TWarehouseBillsMapper tWarehouseBillsMapper;


    /**
     * 查询仓库
     *
     * @param fId 仓库ID
     * @return 仓库
     */
    @Override
    public TWarehouse selectTWarehouseById(Long fId) {
        return tWarehouseMapper.selectTWarehouseById(fId);
    }

    @Override
    public Map<String, Object> selectTWarehouseById1(Long fId) {
        Map<String, Object> map = new HashMap<>();
        TWarehouse tWarehouse = tWarehouseMapper.selectTWarehouseById(fId);
        if (StringUtils.isNotNull(tWarehouse)) {
            map.put("tWarehouse", tWarehouse);
        }
        TWarehouseArea tWarehouseArea=  new TWarehouseArea();
        tWarehouseArea.setfWarehouseid(fId);
        List<TWarehouseArea> tWarehouseAreaList =tWarehouseAreaMapper.selectTWarehouseAreaList(tWarehouseArea);
        if (StringUtils.isNotEmpty(tWarehouseAreaList)) {
            map.put("tWarehouseArea", tWarehouseAreaList);
        }
        return map;
    }

    /**
     * 查询仓库列表
     *
     * @param tWarehouse 仓库
     * @return 仓库
     */
    @Override
    public List<TWarehouse> selectTWarehouseList(TWarehouse tWarehouse) {
        return tWarehouseMapper.selectTWarehouseList(tWarehouse);
    }

    @Override
    public List<TWarehouse> selectTWarehouseLists(TWarehouse tWarehouse) {
        return tWarehouseMapper.selectTWarehouseLists(tWarehouse);
    }

    /**
     * 新增仓库
     *
     * @param tWarehouse 仓库
     * @return 结果
     */
    @Override
    @Transactional
    public int insertTWarehouse(TWarehouse tWarehouse) {
        tWarehouse.setCreateTime(DateUtils.getNowDate());
        TWarehouse info = tWarehouseMapper.selectTWarehouseById(tWarehouse.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getfStatus())) {
            throw new CustomException("部门停用，不允许新增");
        }
        tWarehouse.setAncestors(info.getAncestors() + "," + tWarehouse.getParentId());
        // 所有节点转换成中文拼接
        String  fWarehouseInformation = warehouseName(info.getAncestors() + "," + tWarehouse.getParentId(),tWarehouse.getfName());
        tWarehouse.setfWarehouseInformation(fWarehouseInformation);
        tWarehouseMapper.insertTWarehouse(tWarehouse);
        // 更新库容
        if (tWarehouse.getfLocation()==1){
            int i = updateWarehousefTotalgross(tWarehouse.getAncestors());
            if (i <= 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return 0;
            }
        }
        return 1;

    }

    @Override
    @Transactional
    public AjaxResult insertTWarehouse1(String tWarehouse, String tWarehouseArea, LoginUser loginUser) {
        if (StringUtils.isEmpty(tWarehouse)) {
            return AjaxResult.error("提交失败：仓库信息为空");
        }
        if ( StringUtils.isEmpty(tWarehouseArea) && !"[{}]".equals(tWarehouseArea) ) {
            return AjaxResult.error("提交失败：库区为空");
        }
        Long fPid = null;
        TWarehouse tWarehouses = JSONArray.parseObject(tWarehouse, TWarehouse.class);
        JSONArray jsonArray = JSONArray.parseArray(tWarehouseArea);
        List<TWarehouseArea> tWarehouseAreaList = JSONObject.parseArray(jsonArray.toJSONString(), TWarehouseArea.class);
        if (StringUtils.isNull(tWarehouses.getfId())) {
            tWarehouses.setCreateBy(loginUser.getUser().getUserName());
            tWarehouses.setCreateTime(new Date());
            tWarehouses.setfStatus("0");
            tWarehouseMapper.insertTWarehouse(tWarehouses);
            fPid=tWarehouses.getfId();
        } else {
            fPid=tWarehouses.getfId();
            tWarehouses.setUpdateBy(loginUser.getUser().getUserName());
            tWarehouses.setUpdateTime(new Date());
            if(tWarehouses.getfStatus()!=null && tWarehouses.getfStatus().equals("1") ){
                TWarehouseBills   tWarehouseBill =new TWarehouseBills();
                tWarehouseBill.setfWarehouseid(tWarehouses.getfId());
                List<TWarehouseBills>   tWarehouseBillList=tWarehouseBillsMapper.selectTWarehousebillsList(tWarehouseBill);
                if(tWarehouseBillList!=null && !tWarehouseBillList.isEmpty()){
                    return AjaxResult.error("仓库在库存总账有记录不可变更状态");
                }
            }
            tWarehouseMapper.updateTWarehouse(tWarehouses);
            // tWarehouseAreaMapper.deleteTWarehouseAreaByTWarehoused(fPid);
        }
        for (TWarehouseArea cc : tWarehouseAreaList) {
            if( StringUtils.isNull(cc.getfNo())  ||
                StringUtils.isNull(cc.getfName()) ||
                StringUtils.isNull(cc.getfAddr()) ){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("请完善库区明细信息");
            }
            if(cc.getfId()!=null){
                cc.setUpdateBy(loginUser.getUser().getUserName());
                cc.setUpdateTime(new Date());
                tWarehouseAreaMapper.updateTWarehouseArea(cc);
            } else {
                cc.setfWarehouseid(fPid);
                cc.setfStatus("0");
                cc.setCreateBy(loginUser.getUser().getUserName());
                cc.setCreateTime(new Date());
                tWarehouseAreaMapper.insertTWarehouseArea(cc);
            }

        }
        return AjaxResult.success();
    }

    /**
     * 修改仓库
     *
     * @param tWarehouse 仓库
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult updateTWarehouse(TWarehouse tWarehouse) {
        if(tWarehouse.getfStatus()!=null && tWarehouse.getfStatus().equals("1") ){
            TWarehouseBills   tWarehouseBill =new TWarehouseBills();
            tWarehouseBill.setfWarehouseid(tWarehouse.getfId());
            List<TWarehouseBills>   tWarehouseBillList=tWarehouseBillsMapper.selectTWarehousebillsList(tWarehouseBill);
            if(tWarehouseBillList!=null && !tWarehouseBillList.isEmpty()){
                return AjaxResult.error("仓库在库存总账有记录不可变更状态");
            }
        }
        tWarehouse.setUpdateTime(DateUtils.getNowDate());
        tWarehouseMapper.updateTWarehouse(tWarehouse);
        return AjaxResult.success();
    }

    @Override
    public int updateTWarehouses(TWarehouse tWarehouse) {
        TWarehouse newParentTWarehouse = tWarehouseMapper.selectTWarehouseById(tWarehouse.getParentId());
        TWarehouse oldTWarehouse = tWarehouseMapper.selectTWarehouseById(tWarehouse.getfId());
        if (StringUtils.isNotNull(newParentTWarehouse) && StringUtils.isNotNull(oldTWarehouse)) {
            String newAncestors = newParentTWarehouse.getAncestors() + "," + newParentTWarehouse.getfId();
            String oldAncestors = oldTWarehouse.getAncestors();
            tWarehouse.setAncestors(newAncestors);
            updateDeptChildren(tWarehouse.getfId(), newAncestors, oldAncestors);
            // 修改仓库信息
            String  fWarehouseInformation = warehouseName(newAncestors,tWarehouse.getfName());
            tWarehouse.setfWarehouseInformation(fWarehouseInformation);
        }
        int result = tWarehouseMapper.updateTWarehouse(tWarehouse);
        if (UserConstants.DEPT_NORMAL.equals(tWarehouse.getfStatus())) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatus(tWarehouse);
        }
        // 更新库容
        if (tWarehouse.getfLocation()==1){
            int i = updateWarehousefTotalgross(tWarehouse.getAncestors());
            if (i <= 0) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return 0;
            }
        }
        return result;
    }

    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors) {
        List<TWarehouse> children = tWarehouseMapper.selectChildrenDeptById(deptId);
        for (TWarehouse child : children) {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            tWarehouseMapper.updateDeptChildren(children);
        }
    }

    /**
     * 修改该部门的父级部门状态
     *
     * @param tWarehouse 当前部门
     */
    private void updateParentDeptStatus(TWarehouse tWarehouse) {
        String updateBy = tWarehouse.getUpdateBy();
        tWarehouse = tWarehouseMapper.selectTWarehouseById(tWarehouse.getfId());
        tWarehouse.setUpdateBy(updateBy);
        tWarehouseMapper.updateDeptStatus(tWarehouse);
    }

    /**
     * 批量删除仓库
     *
     * @param fIds 需要删除的仓库ID
     * @return 结果
     */
    @Override
    @Transactional
    public AjaxResult deleteTWarehouseByIds(Long[] fIds) {
        // 查询仓库主表 是否有仓库在使用
        int i = 1;
        for(Long id:fIds){
            TWarehouseBills   tWarehouseBill =new TWarehouseBills();
            tWarehouseBill.setfWarehouseid(id);
            List<TWarehouseBills>   tWarehouseBillList=tWarehouseBillsMapper.selectTWarehousebillsList(tWarehouseBill);
            if(tWarehouseBillList!=null && !tWarehouseBillList.isEmpty()){
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error("仓库第" + i + "行仓库有货物不可删除");
            }
            tWarehouseMapper.deleteTWarehouseById(id);
            i++;
        }
        // tWarehouseMapper.deleteTWarehouseByIds(fIds);
        return AjaxResult.success();
    }

    /**
     * 删除仓库信息
     *
     * @param fId 仓库ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteTWarehouseById(Long fId) {
        return tWarehouseMapper.deleteTWarehouseById(fId);
    }

    @Override
    public String checkNameUnique(TWarehouse tWarehouse) {
        Long fId = StringUtils.isNull(tWarehouse.getfId()) ? -1L : tWarehouse.getfId();
        TWarehouse info = tWarehouseMapper.checkDeptNameUnique(tWarehouse.getfName(), tWarehouse.getParentId());
        if (StringUtils.isNotNull(info) && info.getfId().longValue() != fId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public boolean hasChildByfId(Long fId) {
        int result = tWarehouseMapper.hasChildByfId(fId);
        return result > 0 ? true : false;
    }

    @Override
    public boolean checkDeptExistWarehouse(Long deptId) {
        int result = tWarehouseMapper.checkDeptExistarehouse(deptId);
        return result > 0 ? true : false;
    }

    @Override
    public boolean checkDeptExistWarehouseItems(Long deptId) {
        int result = tWarehouseMapper.checkDeptExistWarehouseItems(deptId);
        return result > 0 ? true : false;
    }

    @Override
    public String checkUFNoUnique(TWarehouse tWarehouse) {
        TWarehouse tWarehouse1 = tWarehouseMapper.checkFNoUnique(tWarehouse.getfNo());
        if (StringUtils.isNotNull(tWarehouse1) && tWarehouse1.getfId()!=tWarehouse.getfId()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkUFNnameUnique(TWarehouse tWarehouse) {
        TWarehouse tWarehouse1 = tWarehouseMapper.checkUFNnameUnique(tWarehouse.getfName());
        if (StringUtils.isNotNull(tWarehouse1) && tWarehouse1.getfId()!=tWarehouse.getfId()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkUFAaddrUnique(TWarehouse tWarehouse) {
        TWarehouse tWarehouse1 = tWarehouseMapper.checkUFAaddrUnique(tWarehouse.getfAddr());
        if (StringUtils.isNotNull(tWarehouse1) && tWarehouse1.getfId()!=tWarehouse.getfId()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkUFTWarehouseAreaNoUnique(TWarehouseArea tWarehouseAreas) {
        TWarehouseArea tWarehouseAreas1 = tWarehouseAreaMapper.checkFNoUnique(tWarehouseAreas.getfNo(),tWarehouseAreas.getfWarehouseid());
        if (StringUtils.isNotNull(tWarehouseAreas1) && tWarehouseAreas1.getfId()!=tWarehouseAreas.getfId()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkUTWarehouseAreaFNnameUnique(TWarehouseArea tWarehouseAreas) {
        TWarehouseArea tWarehouseAreas1 = tWarehouseAreaMapper.checkUFNnameUnique(tWarehouseAreas.getfName(),tWarehouseAreas.getfWarehouseid());
        if (StringUtils.isNotNull(tWarehouseAreas1) && tWarehouseAreas1.getfId()!=tWarehouseAreas.getfId()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public int selectNormalChildrenDeptById(Long fId) {
        return tWarehouseMapper.selectNormalChildrenDeptById(fId);
    }

    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<TWarehouse> tWarehouses) {
        List<TWarehouse> deptTrees = buildDeptTree(tWarehouses);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param depts 部门列表
     * @return 树结构列表
     */
    @Override
    public List<TWarehouse> buildDeptTree(List<TWarehouse> depts) {
        List<TWarehouse> returnList = new ArrayList<TWarehouse>();
        List<Long> tempList = new ArrayList<Long>();
        for (TWarehouse dept : depts) {
            tempList.add(dept.getfId());
        }
        for (Iterator<TWarehouse> iterator = depts.iterator(); iterator.hasNext(); ) {
            TWarehouse dept = (TWarehouse) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }

    @Override
    public String checkUFAreUnique(TWarehouse tWarehouse) {
        TWarehouseArea tWarehouseArea = tWarehouseAreaMapper.selectTWarehouseAreaByWarehouseId(tWarehouse.getParentId());
        if (StringUtils.isNotNull(tWarehouseArea) ) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<TWarehouse> list, TWarehouse t) {
        // 得到子节点列表
        List<TWarehouse> childList = getChildList(list, t);
        t.setChildren(childList);
        for (TWarehouse tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<TWarehouse> getChildList(List<TWarehouse> list, TWarehouse t) {
        List<TWarehouse> tlist = new ArrayList<TWarehouse>();
        Iterator<TWarehouse> it = list.iterator();
        while (it.hasNext()) {
            TWarehouse n = (TWarehouse) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getfId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<TWarehouse> list, TWarehouse t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    public  String warehouseName(String ancestors,String oldName){
        String str[] = ancestors.split(",");
        String fWarehouseInformation = "";
        for (String id: str){
            if(!(id.equals("0")) && !(id.equals("100"))){
                // 查询仓库名称
                TWarehouse tWarehouse=tWarehouseMapper.selectTWarehouseById(Long.valueOf(id));
                fWarehouseInformation += tWarehouse.getfName() + "/";
            }
        }
        if(StringUtils.isNull(fWarehouseInformation) && !fWarehouseInformation.equals("") ){
            fWarehouseInformation = oldName;
        } else {
            fWarehouseInformation +=  oldName;
        }
        return fWarehouseInformation;
    }

    /**
     *  修改仓库库容
     * @param ancestors
     * @return
     */
    public  int updateWarehousefTotalgross(String  ancestors){
        String str[] = ancestors.split(",");
        Long warehouseId =0L;
        for (String id: str){
            if(!(id.equals("0")) && !(id.equals("100"))){
                warehouseId = Long.valueOf(id);
                break;
            }
        }
        if(warehouseId!=0){
            // 所有库容
            BigDecimal fTotalgross = tWarehouseMapper.selectTWarehouseFTotalgross(warehouseId);
            TWarehouse tWarehouseNew = new TWarehouse();
            tWarehouseNew.setfId(warehouseId);
            tWarehouseNew.setfTotalgross(fTotalgross);
            return  tWarehouseMapper.updatefTotalgross(tWarehouseNew);
        }else {
            return 0;
        }
    }

}
