package com.xxfc.platform.vehicle.biz;


import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.xxfc.platform.vehicle.common.RestResponse;
import com.xxfc.platform.vehicle.constant.RedisKey;
import com.xxfc.platform.vehicle.entity.VehicleCata;
import com.xxfc.platform.vehicle.entity.VehiclePlatCata;
import com.xxfc.platform.vehicle.mapper.VehiclePlatCataMapper;
import com.xxfc.platform.vehicle.pojo.Cascade;
import com.xxfc.platform.vehicle.pojo.CataVo;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Arrays;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class VehiclePlatCataBiz extends BaseBiz<VehiclePlatCataMapper, VehiclePlatCata> {

    @Autowired
    VehicleCataBiz vehicleCataBiz;

    //更新
    @Transactional
    @CacheClear(pre = RedisKey.BRANCH_CATA_CACHE)
    public RestResponse update(CataVo cataVo) {
        VehiclePlatCata vehiclePlatCata = new VehiclePlatCata();
        BeanUtils.copyProperties(cataVo, vehiclePlatCata);
        if (vehiclePlatCata.getId() == null || vehiclePlatCata.getId() == 0) {
            vehiclePlatCata.setUpdTime(System.currentTimeMillis());
            insertSelective(vehiclePlatCata);
        } else {
            updateSelectiveById(vehiclePlatCata);
        }
        return RestResponse.suc();
    }

    /**
     * 获取无限级的类别资源
     */
    @Transactional
    @Cache(key = RedisKey.BRANCH_COMPANY_CATA_ALL)
    public JSONObject findTypeTree() throws Exception {
        //默认查询出所有的一级类别
        JSONObject obj = new JSONObject();
        List<VehiclePlatCata> typeList = getAll(0);
        List<Object> list = new ArrayList<>();
        for (VehiclePlatCata cata : typeList) {
            JSONObject treeObject = new JSONObject();
            treeObject.put("id", cata.getId());
            treeObject.put("parentId", cata.getParentId());
            treeObject.put("name", cata.getName());
            treeObject.put("level", cata.getLevel());
            treeObject.put("icon", cata.getIcon());
            treeObject.put("children", getChildren(cata.getId()));
            list.add(treeObject);
        }
        obj.put("cata", list);
        return obj;
    }


    public List<Object> getChildren(Integer parentId) {
        List<Object> list = new ArrayList<>();
        List<VehiclePlatCata> children = getAll(parentId);
        if (children.size() > 0) {
            for (VehiclePlatCata cata : children) {
                JSONObject obj = new JSONObject();
                obj.put("id", cata.getId());
                obj.put("parentId", cata.getParentId());
                obj.put("name", cata.getName());
                obj.put("level", cata.getLevel());
                obj.put("icon", cata.getIcon());
                obj.put("children", getChildren(cata.getId()));
                list.add(obj);
            }
        }
        return list;
    }

    public List<VehiclePlatCata> getAll(Integer parentId) {
        Example example = new Example(VehiclePlatCata.class);
        example.createCriteria().andEqualTo("parentId", parentId).andEqualTo("state", 0);
        example.setOrderByClause("`rank` desc");
        return mapper.selectByExample(example);
    }




    /**
     * 根据车型获取
     *
     * @param modelId
     * @return
     */
    public List<VehiclePlatCata> getByModelId(Integer modelId) {
        List<VehicleCata> vehicleCatas = vehicleCataBiz.selectByExample(new Example.Builder(VehicleCata.class)
                .where(WeekendSqls.<VehicleCata>custom().andEqualTo(VehicleCata::getVehicleModelId, modelId)).build());

        if (vehicleCatas.isEmpty()) {
            return new ArrayList<VehiclePlatCata>();
        } else {
            List<VehiclePlatCata> VehiclePlatCatas = this.selectByExample(new Example.Builder(VehiclePlatCata.class)
                    .where(WeekendSqls.<VehiclePlatCata>custom().andIn(VehiclePlatCata::getId
                            , vehicleCatas.parallelStream().map(VehicleCata::getCataId).distinct()
                                    .collect(Collectors.toList()))).build());
            return VehiclePlatCatas;
        }
    }








    /**
     * 级联添加
     * @param cascade
     * @return
     */
    @Transactional
    public ObjectRestResponse addCascade(Cascade<VehiclePlatCata> cascade)  {

            //取出一级标签
            VehiclePlatCata parent = cascade.getParent();
            parent.setCrtTime(System.currentTimeMillis());
            parent.setState(0);
            //插入一级标签获得id
            mapper.insertSelective(parent);
            Integer parentId = parent.getId();
           int  i = 1/0;
            //取出二级标签
            List<VehiclePlatCata> childrens = cascade.getChildren();
            //逐条插入二级标签
            for (VehiclePlatCata children : childrens) {
                children.setParentId(parentId);
                children.setState(0);
                children.setCrtTime(System.currentTimeMillis());
            }
            mapper.addPlatCataList(childrens);
            return ObjectRestResponse.succ();
    }



    /**
     * 根据父类id获取子标签
     *
     * @param parentId
     * @return
     */
    public ObjectRestResponse fingCatasByParentId(Integer parentId) {

        Example example = Example.builder(VehiclePlatCata.class)
                .where(WeekendSqls.<VehiclePlatCata>custom()
                        .andEqualTo(VehiclePlatCata::getParentId, parentId)
                        .andEqualTo(VehiclePlatCata::getState, 0))
                .orderByAsc("rank")
                .build();
        List<VehiclePlatCata> vpcs = mapper.selectByExample(example);
        return ObjectRestResponse.succ(vpcs);
    }


    /**
     * 分页或不分页,获取一级标签及其子标签
     *
     *
     * @param sort
     * @param page
     * @param limit
     * @return
     */
    public ObjectRestResponse getCascades( Integer page, Integer limit ,Integer sort) {
        try {
            //标签列表页面
            if (sort==null||sort==0) {
                return getPage(page, limit);
            }

            //增加车型页面
            if (sort==1){
                return getList();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ObjectRestResponse.createDefaultFail();
    }


    @Cache(key = RedisKey.BRANCH_COMPANY_CATA_LIST)
    private ObjectRestResponse getList()  {
        //获取一级标签
        Example example = Example.builder(VehiclePlatCata.class)
                .where(WeekendSqls.<VehiclePlatCata>custom()
                        .andEqualTo(VehiclePlatCata::getParentId, 0)
                        .andEqualTo(VehiclePlatCata::getState, 0))
                .orderByAsc("isMore","rank")
                .build();
        //分页查询父类
        List<VehiclePlatCata> parentvpcs = mapper.selectByExample(example);
        //传入一级标签集集合,或去一二级标签集合
        ArrayList<Cascade<VehiclePlatCata>> cascades = getCascades(parentvpcs);

        return ObjectRestResponse.succ(cascades);
    }
    @Cache(key = RedisKey.BRANCH_COMPANY_CATA_PAGE)
    private ObjectRestResponse getPage(Integer page, Integer limit) {
        //获取一级标签
        Example example = Example.builder(VehiclePlatCata.class)
                .where(WeekendSqls.<VehiclePlatCata>custom()
                        .andEqualTo(VehiclePlatCata::getParentId, 0)
                        .andEqualTo(VehiclePlatCata::getState, 0))
                .orderByAsc("rank")
                .build();

        //分页查询一级标签并分类
        PageDataVO opdvo = PageDataVO.pageInfo(page, limit, () -> mapper.selectByExample(example));
        List<VehiclePlatCata> parentvpcs = opdvo.getData();

        //传入一级标签集集合,或去一二级标签集合
        ArrayList<Cascade<VehiclePlatCata>> cascades = getCascades(parentvpcs);

        //用一二级标签集合,替换原来的一级标签集合
        opdvo.setData(cascades);
        return ObjectRestResponse.succ(opdvo);
    }

    private ArrayList<Cascade<VehiclePlatCata>> getCascades(List<VehiclePlatCata> parentvpcs) {
        ArrayList<Cascade<VehiclePlatCata>> cascades = new ArrayList();
        //获取二级标签
        for (VehiclePlatCata parentvpc : parentvpcs) {
            Example exa = Example.builder(VehiclePlatCata.class)
                    .where(WeekendSqls.<VehiclePlatCata>custom()
                            .andEqualTo(VehiclePlatCata::getParentId, parentvpc.getId())
                            .andEqualTo(VehiclePlatCata::getState, 0))
                    .orderByAsc("rank")
                    .build();
            List<VehiclePlatCata> childrenvpcs = mapper.selectByExample(exa);
            //一级标签和其二级标签存入Cascade中集合中
            cascades.add(new Cascade<VehiclePlatCata>(parentvpc, childrenvpcs));

        }
        return cascades;
    }


    /**
     * 查询一个一级标签及其子标签
     *
     * @param id
     * @return
     */
    public ObjectRestResponse findCascade(Integer id) {
        VehiclePlatCata vehiclePlatCata = new VehiclePlatCata();
        vehiclePlatCata.setId(id);
        vehiclePlatCata.setState(0);
        VehiclePlatCata result = mapper.selectOne(vehiclePlatCata);

        Example example = Example.builder(VehiclePlatCata.class)
                .where(WeekendSqls.<VehiclePlatCata>custom()
                        .andEqualTo(VehiclePlatCata::getParentId, id)
                        .andEqualTo(VehiclePlatCata::getState, 0))
                .orderByAsc("rank")
                .build();
        List<VehiclePlatCata> vpcs = mapper.selectByExample(example);
        return ObjectRestResponse.succ(new Cascade<VehiclePlatCata>(result, vpcs));
    }


    /**
     * 更新和添加
     * @param cas
     * @return
     */

    public ObjectRestResponse updateAndAdd( Cascade<VehiclePlatCata> cas) {
        try {
            if (cas==null||cas.getParent()==null) {
                return ObjectRestResponse.createDefaultFail();
            }

            //通过判断一级标签是否有id来判断是更新还是添加
            if (cas.getParent().getId()==null||cas.getParent().getId()==0) {
                return addCascade(cas);
            }else{

                return updateCascade(cas);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ObjectRestResponse.createDefaultFail();
        }

    }


    /**
     * 修改
     * @param cas
     * @return
     */
    @Transactional
    public ObjectRestResponse updateCascade(Cascade<VehiclePlatCata> cas) {

        try {
            VehiclePlatCata parentVPC = cas.getParent();
            //设置更新时间
            parentVPC.setUpdTime(System.currentTimeMillis());
            //更新一级标签
            updateSelectiveById(parentVPC);
            //获取子标签签
            List<VehiclePlatCata> children = cas.getChildren();
            //判断是否有子标签
            if (children==null||children.size()==0) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE,"无子标签");
            }

            //遍历
            for (VehiclePlatCata child : children) {
                //判断子标签是更新还是新增
                if (child.getId()==null){
                    child.setState(0);
                    child.setUpdTime(System.currentTimeMillis());
                    //添加
                  insertSelective(child);
                }else {
                     //判断是否是删除
                    if (child.getState()==1) {
                        Integer id = child.getId();
                        VehicleCata vehicleCata = new VehicleCata();
                        vehicleCata.setCataId(id);
                        //修改车型和标签的中间表
                        vehicleCataBiz.delete(vehicleCata);
                    }

                    //更新
                    child.setUpdTime(System.currentTimeMillis());
                    updateSelectiveById(child);
                }

            }
            return ObjectRestResponse.succ();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(ResultCode.FAILED_CODE);
        }

    }

    /**
     * 修改rank
     * @param id
     * @param rank
     * @return
     */
    public ObjectRestResponse updateParentRank(Integer id, Integer rank){

        try {
            VehiclePlatCata vehiclePlatCata = new VehiclePlatCata();
            vehiclePlatCata.setId(id);
            vehiclePlatCata.setRank(rank);
            updateSelectiveById(vehiclePlatCata);
           return ObjectRestResponse.succ();
        } catch (Exception e) {
            e.printStackTrace();
          return   ObjectRestResponse.createDefaultFail();
        }
    }

    /**
     * 查询当前车型拥有的标签
     * @param ids
     * @return
     */
    public ObjectRestResponse getCatasByIds( String ids){
        Example exa = Example.builder(VehiclePlatCata.class).where(
                WeekendSqls.<VehiclePlatCata>custom()
                        .andIn(VehiclePlatCata::getId, Arrays.asList(ids.split(",")))
                        .andEqualTo(VehiclePlatCata::getState,0)
        ).build();
        List<VehiclePlatCata> vehiclePlatCatas = selectByExample(exa);
        return ObjectRestResponse.succ(vehiclePlatCatas);
    }

}
