package com.djhk.uav.label.service.impl;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.djhk.common.core.domain.R;
import com.djhk.common.utils.DateUtils;
import com.djhk.uav.label.domain.AppFolderParam;
import com.djhk.uav.label.domain.AppOrderParam;
import com.djhk.uav.label.domain.FolderInfo;
import com.djhk.uav.label.domain.Plotting;
import com.djhk.uav.label.domain.vo.FolderVo;
import com.djhk.uav.label.mapper.FolderInfoMapper;
import com.djhk.uav.label.mapper.PlottingMappers;
import com.djhk.uav.label.query.FolderTreeQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

@Service("appFolderInfoService")
public class AppFolderInfoServiceImpl {
    @Autowired
    private FolderInfoMapper folderInfoMapper;

    @Autowired
    private PlottingMappers plottingMapper;

    /**
     * 查询目录信息
     *
     * @param id 目录信息主键
     * @return 目录信息
     */

    public FolderInfo selectFolderInfoById(Long id)
    {
        return folderInfoMapper.selectFolderInfoById(id);
    }

    /**
     * 查询目录信息列表
     *
     * @param folderInfo 目录信息
     * @return 目录信息
     */

    public List<FolderInfo> selectFolderInfoList(FolderInfo folderInfo)
    {
        return folderInfoMapper.selectFolderInfoList(folderInfo);
    }

    /**
     * 新增目录信息
     *
     * @param folderInfo 目录信息
     * @return 结果
     */

    public int insertFolderInfo(FolderInfo folderInfo)
    {
        folderInfo.setCreateTime(DateUtils.getNowDate());
        return folderInfoMapper.insertFolderInfo(folderInfo);
    }

    /**
     * 修改目录信息
     *
     * @param folderInfo 目录信息
     * @return 结果
     */

    public R<String> updateFolderInfo(FolderInfo folderInfo)
    {
        FolderInfo folder = folderInfoMapper.selectFolderInfoById(folderInfo.getId());
        if (folder == null) {
            return R.fail("目录不存在");
        }

        if (
                !folder.getAppId().equals(folderInfo.getAppId())
                || !folder.getOrgId().equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

        if (folder.getLockStatus() == 1) {
            return R.fail("目录已锁定，不可修改");
        }
        folderInfo.setUpdateTime(DateUtils.getNowDate());
        int i = folderInfoMapper.updateFolderInfo(folderInfo);
        if (i > 0) {
            return R.ok("修改成功");
        }
        return R.fail("修改失败");
    }

    /**
     * 批量删除目录信息
     *
     * @param ids 需要删除的目录信息主键
     * @return 结果
     */

    public R<String> deleteFolderInfoByIds(Long[] ids,String appId, Long orgId)
    {
        //1.查询所有属于这个
        Integer count = folderInfoMapper.selectCount(
                new QueryWrapper<FolderInfo>()
                        .in("id", ids)
                        .eq("app_id", appId)
                        .eq("org_id", orgId)
        );
        if (count != ids.length) {
            return R.fail("批量修改参数错误");
        }
        //查询所有子集目录id
        List<Long> allIds = queryAllIds(new ArrayList<>(Arrays.asList(ids)));
        //校验是否有锁定状态的目录，如果有，提示不可删除
        List<String> lockFolders = folderInfoMapper.selectLockFolderNames(allIds);
        if (!CollectionUtils.isEmpty(lockFolders)) {
            return R.fail(JSON.toJSONString(lockFolders)+"已锁定，不允许删除");
        }

        //查询是否有锁定状态的标绘，如果有，不允许删除
        List<String> haveLockPlottingFolders = folderInfoMapper.selectHaveLockPlottingFolders(allIds);
        if (!CollectionUtils.isEmpty(haveLockPlottingFolders)) {
            return R.fail(JSON.toJSONString(haveLockPlottingFolders)+"下有锁定标绘，不允许删除");
        }
        int i = folderInfoMapper.deleteFolderInfoByIds(allIds.toArray(new Long[allIds.size()]));
        if (i > 0) {
            return R.ok("删除成功");
        }
        return R.fail("删除失败");
    }

    @Transactional
    public R<String> deleteFolderInfoByIdsV1(Long id,String appId, Long orgId)
    {
        Optional<FolderInfo> folderOpt = folderInfoMapper.selectList(
                new QueryWrapper<FolderInfo>()
                        .eq("id", id)
                        .eq("app_id", appId)
                        .eq("org_id", orgId)
                        .eq("del_flag", "0")
        ).stream().findFirst();
        if (folderOpt.isEmpty()) {
            return R.fail("目录为空");
        }
        //校验是否有锁定状态的目录，如果有，提示不可删除
        List<String> lockFolders = folderInfoMapper.selectLockFolderNames(List.of(id));
        if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(lockFolders)) {
            return R.fail("目录已被锁定,删除失败");
        }

        FolderInfo folderInfo = folderOpt.get();
        //非默认目录
        if(folderInfo.getInit() == 0){
            folderInfoMapper.deleteFolderInfoByIds(new Long[]{folderInfo.getId()});
        }
        Plotting plotting = new Plotting();
        plotting.setDelFlag("2");
        plottingMapper.update(plotting,new LambdaQueryWrapper<Plotting>().eq(Plotting::getFolderId,folderInfo.getId()));
        return R.ok();
    }

    /**
     * 查询自身+所有下级id
     * @param ids
     * @return
     */
    private List<Long> queryAllIds(List<Long> ids) {
        List<Long> childIds = List.copyOf(ids);
        do {
            childIds = folderInfoMapper.selectIdsByParentIds(childIds);
            if (!CollectionUtils.isEmpty(childIds)) {
                childIds = childIds.stream().filter(id -> !ids.contains(id)).collect(Collectors.toList());
                ids.addAll(childIds);
            }
        }while (!CollectionUtils.isEmpty(childIds));
        return ids;
    }

    /**
     * 删除目录信息信息
     *
     * @param id 目录信息主键
     * @return 结果
     */

    public int deleteFolderInfoById(Long id)
    {
        return folderInfoMapper.deleteFolderInfoById(id);
    }


    public R<List<FolderVo>> queryFolderTree(FolderTreeQuery query) {
        checkAndCreateDefaultFolders(query.getAppId(),query.getOrgId());
        List<FolderVo> folderVos = folderInfoMapper.queryFolderVos(query);
        if (CollectionUtils.isEmpty(folderVos)) {
            return R.ok();
        }
        List<FolderVo> folderVoList = folderVos.stream().map(this::checkFoldersWithPlotting).collect(Collectors.toList());
        // TODO: 2023/9/22  文件目录只有一层
//        List<Long> parentIds = folderVos.stream().map(f -> f.getParentId()).collect(Collectors.toList());
//        List<FolderVo> allParentsFolder = findAllParentsFolder(parentIds);
//        folderVos.addAll(allParentsFolder);
        List<FolderVo> folderTree = getFolderTree(folderVoList);
        return R.ok(folderTree);
    }

    private FolderVo checkFoldersWithPlotting(FolderVo folderVo) {
        if(folderVo == null){
            return new FolderVo();
        }
        Boolean share = false;
        if(folderVo.getInit() == 1 && folderVo.getSource() == 2){
            share = true;
        }
        folderVo.setPlottingStatus(false);
        Plotting plotting = new Plotting();
        plotting.setFolderId(folderVo.getId());
        List<Plotting> plottings = plottingMapper.selectPlottingList(plotting);
        if(com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(plottings)){
            folderVo.setPlottingStatus(true);
        }
        for(Plotting plotting1 : plottings){
            plotting1.setFolderName(folderVo.getName());
            plotting1.setShare(share);
        }
        folderVo.setPlottings(plottings);
        return folderVo;
    }

    private void checkAndCreateDefaultFolders(String appId,Long orgId) {
        Integer count = folderInfoMapper.selectCount(
                new QueryWrapper<FolderInfo>()
                        .eq("app_id",appId)
                        .eq("org_id",orgId)
                        .eq("del_flag","0")
                        .eq("type",1)
                        .eq("init",1)
        );

        if (count == 0) {
            List<FolderInfo> templateFolders = folderInfoMapper.selectList(
                    new QueryWrapper<FolderInfo>()
                            .eq("app_id", "-1")
                            .eq("del_flag", "0")
                            .eq("type", 1)
                            .eq("init", 1)
            );

            if (!CollectionUtils.isEmpty(templateFolders)) {
                for (FolderInfo templateFolder : templateFolders) {
                    templateFolder.setAppId(appId);
                    templateFolder.setOrgId(orgId);
                    templateFolder.setCreateTime(new Date());
                    templateFolder.setUpdateTime(new Date());
                    folderInfoMapper.insertFolderInfo(templateFolder);
                }
            }
        }
    }

    private List<FolderVo> getFolderTree(List<FolderVo> folderVos) {
        folderVos = folderVos.stream().distinct().collect(Collectors.toList());
        //筛选出所有parentId是0的根目录
        List<FolderVo> root = folderVos.stream().filter(f -> f.getParentId() == 0).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(root)) {
            return folderVos;
        }

        Map<Long, FolderVo> rootMap = root.stream().collect(Collectors.toMap(FolderVo::getId, FolderVo -> FolderVo));
        List<FolderVo> children = folderVos.stream().filter(f -> f.getParentId() != 0).collect(Collectors.toList());

        Integer childNums = children.size();
        while (!CollectionUtils.isEmpty(children)) {
            Map<Long, FolderVo> rootMapNew = new HashMap<>();
            Map<Long, FolderVo> finalRootMap = rootMap;
            children.removeIf(c -> {
                FolderVo parent = finalRootMap.get(c.getParentId());
                if (parent == null) {
                    return false;
                } else {
                    List<FolderVo> childrenList = parent.getChildren();
                    if (childrenList == null) {
                        childrenList = new ArrayList<>();
                        parent.setChildren(childrenList);
                    }
                    childrenList.add(c);
                    rootMapNew.put(c.getId(),c);
                    return true;
                }
            });

            if (childNums == children.size()) {
                break;
            }
            rootMap = rootMapNew;
        }
        return root;
    }

    private List<FolderVo> findAllParentsFolder(List<Long> parentIds) {
        List<FolderVo> allParents = new ArrayList<>();
        while (!CollectionUtils.isEmpty(parentIds)) {
            List<FolderVo> firstParentFolders = findFirstParentFolders(parentIds);
            allParents.addAll(firstParentFolders);
            parentIds = firstParentFolders.stream().map(f -> f.getParentId()).collect(Collectors.toList());
        }
        return allParents;
    }

    private List<FolderVo> findFirstParentFolders(List<Long> ids) {
        return folderInfoMapper.findFirstParentFolders(ids);
    }


    public R<String> changeParent(Long parentId, Long id,String appId, Long orgId) {

        FolderInfo folderInfo = folderInfoMapper.selectFolderInfoById(id);
        if (
                folderInfo == null
                || "2".equals(folderInfo.getDelFlag())
                || !appId.equals(folderInfo.getAppId())
                || !orgId.equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

        FolderInfo parent = folderInfoMapper.selectFolderInfoById(parentId);
        if (
                parent == null
                || "2".equals(parent.getDelFlag())
                || !appId.equals(parent.getAppId())
                || !orgId.equals(parent.getOrgId())
        ) {
            return R.fail("父级不存在");
        }

        //修改父级id
        folderInfo.setParentId(parentId);
        updateFolderInfo(folderInfo);

        //修改当前文件夹及下级文件夹显隐、锁定、分享状态

        return R.ok();
    }

    @Transactional

    public R<String> changeLockStatus(Long id,Integer lockStatus,String appId, Long orgId) {
        FolderInfo folderInfo = folderInfoMapper.selectFolderInfoById(id);
        if (
                folderInfo == null
                || "2".equals(folderInfo.getDelFlag())
                || !appId.equals(folderInfo.getAppId())
                || !orgId.equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

        List<FolderInfo> folderInfos = folderInfoMapper.selectSelfAndChildren(id);
        List<Long> ids = folderInfos.stream().map(FolderInfo::getId).collect(Collectors.toList());
        int i = folderInfoMapper.changeLockStatus(ids,lockStatus);
        if (i > 0) {
            plottingMapper.updateLockStatusByFolderId(id,lockStatus);
        }
        if (i > 0) {
            plottingMapper.updateLockStatusByFolderId(id,lockStatus);
        }
        return R.ok();
    }


    @Transactional
    public R<String> changeShowStatusWeb(Long id, Integer showStatus,String appId, Long orgId) {
        FolderInfo folderInfo = folderInfoMapper.selectFolderInfoById(id);
        if (
                folderInfo == null
                || "2".equals(folderInfo.getDelFlag())
                || !appId.equals(folderInfo.getAppId())
                || !orgId.equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

        List<FolderInfo> folderInfos = folderInfoMapper.selectSelfAndChildren(id);
        if (CollectionUtils.isEmpty(folderInfos)) {
            return R.fail("目录不存在");
        }

        List<String> lockFolderNames = folderInfos.stream().filter(f -> f.getLockStatus() == 1).map(f -> f.getName()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(lockFolderNames)) {
            return R.fail(JSON.toJSONString(lockFolderNames)+"目录已锁定，修改失败");
        }
        List<Long> ids = folderInfos.stream().map(f -> f.getId()).collect(Collectors.toList());
        Integer maxLockStatus = plottingMapper.selectMaxLockStatusByFolderIdIds(ids);
        if (maxLockStatus == 1) {
            return R.fail("目录下有锁定状态标绘，操作失败");
        }

        //修改所有目录
        int i = folderInfoMapper.batchUpdateShowStatusWeb(ids,showStatus);
        if (i > 0) {
            plottingMapper.batchUpdateShowStatusWebByFolderId(ids,showStatus);
        }
        return R.ok();
    }


    public R<String> changeShareStatus(Long id, Integer shareStatus,String appId, Long orgId) {
        FolderInfo folderInfo = folderInfoMapper.selectFolderInfoById(id);
        if (
                folderInfo == null
                        || "2".equals(folderInfo.getDelFlag())
                        || !appId.equals(folderInfo.getAppId())
                        || !orgId.equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

        List<FolderInfo> folderInfos = folderInfoMapper.selectSelfAndChildren(id);
        if (CollectionUtils.isEmpty(folderInfos)) {
            return R.fail("目录不存在");
        }

        List<String> lockFolderNames = folderInfos.stream().filter(f -> f.getLockStatus() == 1).map(f -> f.getName()).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(lockFolderNames)) {
            return R.fail(JSON.toJSONString(lockFolderNames)+"目录已锁定，修改失败");
        }
        List<Long> ids = folderInfos.stream().map(f -> f.getId()).collect(Collectors.toList());
        Integer maxLockStatus = plottingMapper.selectMaxLockStatusByFolderIdIds(ids);
        if (maxLockStatus == 1) {
            return R.fail("目录下有锁定状态标绘，操作失败");
        }

        //修改所有目录
        int i = folderInfoMapper.batchUpdateShareStatus(ids,shareStatus);
        if (i > 0) {
            plottingMapper.batchUpdateShareStatusByFolderId(ids,shareStatus);
        }
        return R.ok();
    }

    public R<String> changeShareStatusV1(Long id, Integer shareStatus,String appId, Long orgId) {
        FolderInfo folderInfo = folderInfoMapper.selectFolderInfoById(id);
        if (
                folderInfo == null
                        || "2".equals(folderInfo.getDelFlag())
                        || !appId.equals(folderInfo.getAppId())
                        || !orgId.equals(folderInfo.getOrgId())
        ) {
            return R.fail("目录不存在");
        }

//        List<FolderInfo> folderInfos = folderInfoMapper.selectSelfAndChildren(id);
//        if (CollectionUtils.isEmpty(folderInfos)) {
//            return R.fail("目录不存在");
//        }

        if(folderInfo.getInit() == 1 && folderInfo.getSource() == 2){
            return R.fail("暂不支持修改");
        }
        if(folderInfo.getLockStatus() == 1){
            return R.fail("目录已锁定，修改失败");
        }

//        List<String> lockFolderNames = folderInfos.stream().filter(f -> f.getLockStatus() == 1).map(f -> f.getName()).collect(Collectors.toList());
//        if (!CollectionUtils.isEmpty(lockFolderNames)) {
//            return R.fail(JSON.toJSONString(lockFolderNames)+"目录已锁定，修改失败");
//        }
//        List<Long> ids = folderInfos.stream().map(f -> f.getId()).collect(Collectors.toList());
//        Integer maxLockStatus = plottingMapper.selectMaxLockStatusByFolderIdIds(ids);
//        if (maxLockStatus == 1) {
//            return R.fail("目录下有锁定状态标绘，操作失败");
//        }

        //修改所有目录
        int i = folderInfoMapper.batchUpdateShareStatus(List.of(id),shareStatus);
        if (i > 0) {
            plottingMapper.batchUpdateShareStatusByFolderId(List.of(id),shareStatus);
        }
        return R.ok();
    }

    public R<Map<String, Object>> orderFolder(AppFolderParam folderParam) {
        Long id = folderParam.getId();
        List<AppOrderParam> folderOrders = folderParam.getOrders();
        for(AppOrderParam orderParam : folderOrders){
            FolderInfo folderInfo = new FolderInfo();
            folderInfo.setId(orderParam.getId());
            folderInfo.setOrder(orderParam.getOrder());
            folderInfo.setUpdateTime(DateUtils.getNowDate());

            folderInfoMapper.updateById(folderInfo);
        }
        return R.ok(Map.of("id",id));
    }
}
