package com.keyware.shandan.bianmu.controller;

import cn.hutool.core.bean.BeanUtil;
import com.keyware.shandan.bianmu.dto.DirOperateDTO;
import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.enums.DirectoryType;
import com.keyware.shandan.bianmu.enums.ReviewStatus;
import com.keyware.shandan.bianmu.service.DirPermissionService;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.bianmu.utils.DirectoryBuilder;
import com.keyware.shandan.common.controller.BaseController;
import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.frame.config.security.SecurityUtil;
import com.keyware.shandan.system.entity.SysFile;
import com.keyware.shandan.system.entity.SysUser;
import com.keyware.shandan.system.service.SysFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 目录表 前端控制器
 * </p>
 *
 * @author GuoXin
 * @since 2021-06-01
 */
@Slf4j
@RestController
@RequestMapping("/business/directory")
public class DirectoryController extends BaseController<DirectoryService, DirectoryVo, String> {

    @Autowired
    private DirectoryService directoryService;

    @Autowired
    private SysFileService sysFileService;

    @Autowired
    private DirPermissionService dirPermissionService;

    @Autowired
    private DirectoryBuilder directoryBuilder;

    @GetMapping("/")
    public ModelAndView index(ModelAndView modelAndView) {
        modelAndView.setViewName("business/directory/directory");
        SysUser user = SecurityUtil.getLoginSysUser();
        dirPermissionService.refreshCache();
        modelAndView.addObject("readDirIds", dirPermissionService.getByReadPermis(user));
        modelAndView.addObject("writeDirIds", dirPermissionService.getByWritePermis(user));
        return modelAndView;
    }

    /**
     * 保存目录与数据资源关系
     *
     * @param directoryId
     * @param metadataIds
     * @return
     */
    @PostMapping("/save/metadata")
    public Result<Object> saveMetadata(String directoryId, String metadataIds) {
        if (StringUtils.isBlank(directoryId) || StringUtils.isBlank(metadataIds)) {
            return Result.of(null, false, "参数错误");
        }

        DirectoryVo dir = directoryService.getById(directoryId);
        Assert.notNull(dir, "目录不存在");
        if (DirectoryType.LINK_DIR == dir.getDirectoryType()) {
            dir = directoryService.getById(dir.getResourceId());
            Assert.notNull(dir, "软连接源目录不存在");
        }
        String parentId = dir.getId();
        // 将关联的数据资源插入到目录表中去
        List<DirectoryVo> metaDirList = Arrays.stream(metadataIds.split(","))
                .map(id -> directoryBuilder.buildMetadataDir(parentId, id))
                .collect(Collectors.toList());
        directoryService.saveBatch(metaDirList);

        // 更新目录审核状态
        if (dir.getReviewStatus() != ReviewStatus.UN_SUBMIT) {
            dir.setReviewStatus(ReviewStatus.UN_SUBMIT);
            directoryService.updateById(dir);
        }

        return Result.of(dir);
    }

    /**
     * 移除目录和数据资源关系
     *
     * @param directoryId
     * @param metadataId
     * @return
     */
    @PostMapping("/remove/metadata")
    public Result<Object> removeMetadata(String directoryId, String metadataId) {
        if (StringUtils.isBlank(directoryId) || StringUtils.isBlank(metadataId)) {
            return Result.of(null, false, "参数错误");
        }

        DirectoryVo dir = directoryService.getById(directoryId);
        Assert.notNull(dir, "目录不存在");

        directoryService.deleteByDirectoryIdAndResourceId(directoryId, metadataId);

        // 更新目录审核状态
        if (dir.getReviewStatus() != ReviewStatus.UN_SUBMIT) {
            dir.setReviewStatus(ReviewStatus.UN_SUBMIT);
            directoryService.updateById(dir);
        }

        return Result.of(dir);
    }

    @PostMapping("/remove/file")
    public Result<Object> removeFile(String fileId) {
        if (StringUtils.isBlankAny(fileId)) {
            return Result.of(null, false, "参数错误");
        }

        SysFile file = sysFileService.getById(fileId);
        Assert.notNull(file, "文件不存在");

        DirectoryVo dir = directoryService.getById(file.getEntityId());
        Assert.notNull(dir, "目录不存在");

        directoryService.deleteByDirectoryIdAndResourceId(file.getEntityId(), fileId);

        // 更新目录审核状态
        if (sysFileService.deleteById(fileId).getData()) {
            if (dir.getReviewStatus() != ReviewStatus.UN_SUBMIT) {
                dir.setReviewStatus(ReviewStatus.UN_SUBMIT);
                directoryService.updateById(dir);
            }
        }

        return Result.of(dir);
    }

    /**
     * 关联其他目录以及数据
     *
     * @param targetId
     * @param sourceId
     * @return
     */
    @PostMapping("/link")
    public Result<Object> dirCopy(@RequestBody String targetId, @RequestBody String sourceId) {
        saveLinkDirTree(sourceId, targetId);
        dirPermissionService.refreshCache();
        return Result.of(true);
    }

    /**
     * @param targetId
     * @param sourceIds
     * @return
     */
    @PostMapping("/move")
    public Result<Object> dirMove(@RequestBody String targetId, @RequestBody String sourceIds) {
        DirectoryVo targetDir = directoryService.getById(targetId);
        List<String> idList = Arrays.asList(sourceIds.split(","));
        List<DirectoryVo> sourceDirs = directoryService.listByIds(idList);
        for (DirectoryVo dir : sourceDirs) {
            DirectoryVo newDir = new DirectoryVo();
            BeanUtil.copyProperties(dir, newDir);
            newDir.setParentId(targetDir.getId());
            replaceNewAttribute(newDir, dir, targetDir);
            directoryService.updateById(newDir);
            List<DirectoryVo> children = directoryService.allChildrenLists(dir);
            children.forEach(child -> {
                replaceNewAttribute(child, dir, targetDir);
            });
            directoryService.updateBatchById(children);
        }
        dirPermissionService.refreshCache();
        return Result.of("成功");
    }

    /**
     * 保存软连接目录树
     *
     * @param sourceId
     * @param targetId
     */
    private void saveLinkDirTree(String sourceId, String targetId) {
        DirectoryVo sourceDir = directoryService.getById(sourceId);
        DirectoryVo dir;
        if (DirectoryType.METADATA == sourceDir.getDirectoryType() || DirectoryType.LINK_METADATA == sourceDir.getDirectoryType()) {
            dir = directoryBuilder.buildMetadataLinkDir(targetId, sourceDir.getId());
        } else if (DirectoryType.FILE == sourceDir.getDirectoryType() || DirectoryType.LINK_FILE == sourceDir.getDirectoryType()) {
            dir = directoryBuilder.buildFileLinkDir(targetId, sourceDir.getId());
        } else {
            dir = directoryBuilder.buildLinkDir(targetId, sourceDir.getId());
        }
        directoryService.save(dir);
    }


    private void replaceNewAttribute(DirectoryVo current, DirectoryVo source, DirectoryVo target) {
        String replacePath = source.getDirectoryPath().substring(0, source.getDirectoryPath().lastIndexOf("/"));
        current.setDirectoryPath(current.getDirectoryPath().replaceFirst(replacePath + "/", target.getDirectoryPath() + "/"));
        current.setReviewStatus(ReviewStatus.UN_SUBMIT);
        current.setOwner(target.getOwner());
        current.setOwnerId(target.getOwnerId());
        current.setOwnerType(target.getOwnerType());
        /*current.setPermisEveryone(target.getPermisEveryone());
        current.setPermisAllParent(target.getPermisAllParent());
        current.setPermisAllChild(target.getPermisAllChild());
        current.setPermisParent(target.getPermisParent());
        current.setPermisChild(target.getPermisChild());*/
    }

    /**
     * 目录整编体检批量删除功能
     * @param ids
     * add 2024/04/11 xiongcl
     */
    @DeleteMapping("batch/delete/{ids}")
    public Result<Object> batchDelete(@PathVariable("ids") String ids) {
        Arrays.stream(ids.split(",")).forEach(dir -> {
            commonService.deleteById(dir);
            System.out.println(dir);
        });
        return Result.of("删除成功");
    }
}
