package com.tuoheng.admin.service.leg;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.admin.entity.Channel;
import com.tuoheng.admin.entity.Leg;
import com.tuoheng.admin.entity.LegDept;
import com.tuoheng.admin.entity.User;
import com.tuoheng.admin.enums.MarkEnum;
import com.tuoheng.admin.enums.DataPermissionEnum;
import com.tuoheng.admin.enums.LegEnum;
import com.tuoheng.admin.mapper.DeptMapper;
import com.tuoheng.admin.mapper.ChannelMapper;
import com.tuoheng.admin.mapper.LegDeptMapper;
import com.tuoheng.admin.mapper.LegMapper;
import com.tuoheng.admin.query.LegQuery;
import com.tuoheng.admin.service.leg.query.QueryLegListByDeptIdService;
import com.tuoheng.admin.service.leg.query.QueryLegListByChannelIdAndDeptIdService;
import com.tuoheng.admin.service.leg.query.QueryLegListByChannelIdService;
import com.tuoheng.admin.utils.CurrentUserUtil;
import com.tuoheng.admin.vo.SectionInfoVo;
import com.tuoheng.common.core.common.BaseServiceImpl;
import com.tuoheng.common.core.enums.ServiceExceptionEnum;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.DateUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * @Author ChengWang
 * @Date 2022/11/17
 */
@Service
public class LegServiceImpl extends BaseServiceImpl<LegMapper, Leg> implements ILegService {

    @Autowired
    private LegMapper legMapper;

    @Autowired
    private ChannelMapper channelMapper;

    @Autowired
    private LegDeptMapper legDeptMapper;

    @Autowired
    private QueryLegListByDeptIdService queryLegListByDeptIdService;

    @Autowired
    private QueryLegListByChannelIdService queryLegListByChannelIdService;

    @Autowired
    private QueryLegListByChannelIdAndDeptIdService queryLegListByChannelIdAndDeptIdService;

    @Autowired
    private DeptMapper deptMapper;


    /**
     * 获取航段列表(分页)
     *
     * @param query
     * @return
     */
    @Override
    public JsonResult queryPage(LegQuery query) {
        if (null == query.getLimit() && null == query.getPage()) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //获取当前登录用户信息
        User user = CurrentUserUtil.getUserInfo();
        if (ObjectUtil.isNull(user)) {
            return JsonResult.error(LegEnum.USER_IS_NOT_EXIST.getCode(), LegEnum.USER_IS_NOT_EXIST.getMsg());
        }
        String tenantId = user.getTenantId();
        IPage<Leg> pageData = new Page<>(query.getPage(), query.getLimit());
        //数据权限 超级管理员可以查看全部航段
        if (DataPermissionEnum.ALL.getCode() == user.getDataPermission()) {
            //获取分页数据
            IPage<Leg> page = new Page<>(query.getPage(), query.getLimit());
            pageData = legMapper.selectPage(page, Wrappers.<Leg>lambdaQuery()
                    .eq(Leg::getMark, 1)
                    .eq(Leg::getTenantId, tenantId)
                    .orderByDesc(Leg::getCreateTime));
            List<Leg> records = pageData.getRecords();
            List<Leg> list = new ArrayList<>();
            for (Leg record : records) {
                //获取每条航段对应的航道id
                Channel channel = channelMapper.selectOne(Wrappers.<Channel>lambdaQuery()
                        .eq(Channel::getId, record.getChannelId())
                        .eq(Channel::getMark, 1));
                if (StringUtils.isNotNull(channel)) {
                    if (StringUtils.isNotEmpty(channel.getCode())) {
                        record.setCode(channel.getCode());
                    }
                    if(StringUtils.isNotEmpty(channel.getName())){
                        record.setName(channel.getName());
                    }
                }
                //判断航段是否关联部门
                SectionRelation(record);
                list.add(record);
            }
            pageData.setRecords(list);
        }
        //部门管理员和普通用户 查看本部门及下属部门
        if (DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == user.getDataPermission() || DataPermissionEnum.DEPT.getCode() == user.getDataPermission()) {
            //获取分页数据
            IPage<Leg> page = new Page<>(query.getPage(), query.getLimit());
            //获取当前部门及其子部门列表
            String deptId = user.getDeptId();
            if (StringUtils.isEmpty(deptId)) {
                return JsonResult.error(LegEnum.DEPT_IS_NOT_EXIST.getCode(), LegEnum.DEPT_IS_NOT_EXIST.getMsg());
            }
            List<String> deptList = deptMapper.selectAllChildListById(deptId);
            if(StringUtils.isEmpty(deptList) && deptList.size()<=0){
                return JsonResult.error(LegEnum.DEPT_ID_IS_NULL.getCode(), LegEnum.DEPT_ID_IS_NULL.getMsg());
            }
            //根据部门列表查对应的部门航段数据列表
            List<LegDept> legDeptList = legDeptMapper.selectList(Wrappers.<LegDept>lambdaQuery()
                    .eq(LegDept::getTenantId, tenantId)
                    .in(LegDept::getDeptId, deptList));
            if(StringUtils.isEmpty(legDeptList) && legDeptList.size()<=0){
                return JsonResult.error(LegEnum.DEPT_SECTION_IS_NOT_EXIST.getCode(), LegEnum.DEPT_SECTION_IS_NOT_EXIST.getMsg());
            }
            //查询对应的航段列表
            List<String> legIdList = legDeptList.stream().map(t -> t.getLegId()).collect(Collectors.toList());
            if (StringUtils.isEmpty(legIdList)) {
                return JsonResult.error(LegEnum.SECTION_ID_IS_NULL.getCode(), LegEnum.SECTION_ID_IS_NULL.getMsg());
            }
            //根据航段id列表获取对应的航段信息
            List<Leg> legList = legMapper.selectList(new LambdaQueryWrapper<Leg>()
                    .eq(Leg::getMark, 1)
                    .eq(Leg::getTenantId, tenantId)
                    .in(Leg::getId, legIdList));
            if (StringUtils.isEmpty(legList)) {
                return JsonResult.error(LegEnum.SECTION_LIST_IS_NULL.getCode(), LegEnum.SECTION_LIST_IS_NULL.getMsg());
            }
            List<Leg> list = new ArrayList<>();
            for (Leg leg : legList) {
                //获取每条航段对应的航道id
                Channel channel = channelMapper.selectOne(Wrappers.<Channel>lambdaQuery()
                        .eq(Channel::getId, leg.getChannelId())
                        .eq(Channel::getMark, 1));
                if (ObjectUtil.isNotNull(channel)) {
                    if (StringUtils.isNotEmpty(channel.getCode())) {
                        leg.setCode(channel.getCode());
                    }
                }
                //判断航段是否关联部门
                SectionRelation(leg);
                list.add(leg);
            }
            pageData.setRecords(list);
        }
        return JsonResult.success(pageData);
    }

    //对航段范围进行处理
    private String getSectionRanges(Leg record) {
        //航段范围属性
        String legRange = record.getLegRange();
        String[] legRanges = legRange.split(",");
        legRange ="K"+legRanges[0]+"+"+legRanges[1]+"~"+"K"+legRanges[2]+"+"+legRanges[3];
        return legRange;
    }

    @Override
    public JsonResult getListInfo(LegQuery query) {
        //获取当前登录人信息
        String tenantId = CurrentUserUtil.getTenantId();
        if (StringUtils.isEmpty(tenantId)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        List<Leg> legList = legMapper.selectList(new LambdaQueryWrapper<Leg>()
                .eq(Leg::getMark, 1)
                .eq(Leg::getTenantId, tenantId)
                .orderByDesc(Leg::getCreateTime));
        List<Leg> list = new ArrayList<>();
        for (Leg leg : legList) {
            //判断航段是否关联部门
            SectionRelation(leg);
            list.add(leg);
        }

        return JsonResult.success(list);
    }

    /**
     * 根据部门id获取该部门下航段信息列表
     *
     * @param deptId
     * @return
     */
    @Override
    public JsonResult getListByDeptId(String deptId) {
        return queryLegListByDeptIdService.getList(deptId);
    }

    /**
     * 根据航道id获取该航道下航段信息列表
     *
     * @param channelId
     * @return
     */
    @Override
    public JsonResult getListByChannelId(String channelId) {
        return queryLegListByChannelIdService.getList(channelId);
    }

    @Override
    public JsonResult getListByChannelIdAndDeptId(String channelId, String deptId) {
        return queryLegListByChannelIdAndDeptIdService.getList(channelId, deptId);
    }

    @Override
    public JsonResult editInfo(Leg entity) {
        //超级管理员可以进行新增和编辑，普通用户不能进行此操作,部门管理员可以进行修改经纬度
        String userId = CurrentUserUtil.getUserId();
        String tenantId = CurrentUserUtil.getTenantId();
        if(StringUtils.isEmpty(tenantId)){
            return JsonResult.error("租户id为空");
        }
        if (StringUtils.isEmpty(entity.getId())) {
            //新增
            entity.setCreateTime(DateUtils.now());
            entity.setCreateUser(userId);
            entity.setTenantId(tenantId);
        } else {
            //更新
            entity.setUpdateTime(DateUtils.now());
            entity.setUpdateUser(userId);
            entity.setTenantId(tenantId);
        }
        super.edit(entity);

        return JsonResult.success();
    }

    @Override
    public JsonResult getLegInfo(String legId) {
        if (StringUtils.isEmpty(legId)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //根据id查询航段
        Leg leg = legMapper.selectOne(Wrappers.<Leg>lambdaQuery()
                .eq(Leg::getMark, 1).eq(Leg::getId, legId));
        String channelId = leg.getChannelId();
        if (StringUtils.isEmpty(channelId)) {
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //根据channelId查询对应的航道
        Channel channel = channelMapper.selectOne(new LambdaQueryWrapper<Channel>()
                .eq(Channel::getId, channelId)
                .eq(Channel::getMark, 1));
        //获取航道代号
        if (StringUtils.isNull(channel)) {
            return JsonResult.error("对应的航道为空");
        }
        String code = channel.getCode();
        if (StringUtils.isEmpty(code)) {
            return JsonResult.error("航道代号为空");
        }
        SectionInfoVo legInfoVo = new SectionInfoVo();
        BeanUtils.copyProperties(leg, legInfoVo);
        legInfoVo.setCode(code);

        return JsonResult.success(legInfoVo);
    }

    @Override
    public JsonResult getLegList() {
        //获取当前登录人信息 登录用户名
        User user = CurrentUserUtil.getUserInfo();
        if(ObjectUtils.isEmpty(user)) {
            return JsonResult.error(LegEnum.USER_IS_NOT_EXIST.getCode());
        }
        String tenantId = CurrentUserUtil.getTenantId();
        //超级管理员获取当前租户下全部航道，部门管理员和普通用户显示用户所属部门监管范围航段之和
        if(null == user.getDataPermission()){
            throw new ServiceException(ServiceExceptionEnum.PARAMETER_IS_NULL);
        }
        //登录用户若为部门管理员或普通用户需要查询所在部门
        String deptId = user.getDeptId();
        List<Leg> list = new ArrayList<>();
        List<Channel> channelList = new ArrayList<>();

        //超级管理员
        if(DataPermissionEnum.ALL.getCode() == user.getDataPermission()){
            channelList = this.getAllChannelList(tenantId);
            return JsonResult.success(channelList);
        }

        //部门管理员和普通用户
        if(DataPermissionEnum.DEPT_AND_SUB_DEPT.getCode() == user.getDataPermission() || DataPermissionEnum.DEPT.getCode() == user.getDataPermission()){
            //对应部门下的航段列表
            List<LegDept> legDeptList = legDeptMapper.selectList(new LambdaQueryWrapper<LegDept>()
                    .eq(LegDept::getDeptId, deptId).eq(LegDept::getTenantId, tenantId));
            //获取对应的航段列表
            List<String> legList = legDeptList.stream().map(t -> t.getLegId()).collect(Collectors.toList());
            //获取当前租户当前部门下的航段列表
            list = legMapper.selectList(Wrappers.<Leg>lambdaQuery()
                    .eq(Leg::getTenantId, tenantId)
                    .eq(Leg::getMark, MarkEnum.VALID.getCode())
                    .in(Leg::getId, legList));
            List<Leg> legs = new ArrayList<>();
            for (Leg leg : list) {
                String channelId = leg.getChannelId();
                //每条航段对应的航道代号
                Channel channel = channelMapper.selectOne(Wrappers.<Channel>lambdaQuery()
                        .eq(Channel::getTenantId, tenantId)
                        .eq(Channel::getId, channelId)
                        .eq(Channel::getMark, MarkEnum.VALID.getCode()));
                if(channel !=null){
                    leg.setCode(channel.getCode());
                }
                legs.add(leg);
            }
            return JsonResult.success(legs);
        }

        return JsonResult.error(LegEnum.QUERY_IS_FAILED.getCode());
    }


    /**
     * 如果是顶级部门，则查询所有航道列表
     *
     * @param tenantId
     * @return
     */
    private List<Channel> getAllChannelList(String tenantId) {
        List<Channel> channelList = channelMapper.selectList(new LambdaQueryWrapper<Channel>()
                .eq(Channel::getTenantId, tenantId)
                .eq(Channel::getMark, MarkEnum.VALID.getCode()));
        if (CollectionUtil.isEmpty(channelList)) {
            return null;
        }
        return channelList;
    }


    private void SectionRelation(Leg leg) {
        List<LegDept> legDeptList = legDeptMapper.selectList(Wrappers.<LegDept>lambdaQuery()
                .eq(LegDept::getTenantId, CurrentUserUtil.getTenantId())
                .eq(LegDept::getLegId, leg.getId()));
        if (StringUtils.isNotEmpty(legDeptList)) {
            //航段关联与部门关联，设置关联字段为true
            leg.setRelation(true);
        } else {
            leg.setRelation(false);
        }
    }


}
