package com.cmeeting.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cmeeting.ad.entity.SysUserSync;
import com.cmeeting.constant.CategoryConstant;
import com.cmeeting.pojo.CoreModulePermissions;
import com.cmeeting.pojo.SysUserSyncCategory;
import com.cmeeting.service.IAgentAuthService;
import com.cmeeting.service.ISysUserSyncCategoryService;
import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.R;
import com.cmeeting.vo.AgentAuthVO;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/agent/auth")
public class AgentAuthController {

    @Resource
    private IAgentAuthService iAgentAuthService;
    @Resource
    private SysUserSyncService sysUserSyncService;
    @Resource
    private ISysUserSyncCategoryService iSysUserSyncCategoryService;

    @PostMapping("/authedList")
    public R list(@RequestBody @Validated AgentAuthVO.AuthedList vo) {
        Page<CoreModulePermissions> page = iAgentAuthService.page(new Page<>(vo.getCurrent(), vo.getSize()), new LambdaQueryWrapper<CoreModulePermissions>()
                .eq(CoreModulePermissions::getTenantId, vo.getTenantId()));
        List<CoreModulePermissions> records = page.getRecords();
        if (CollUtil.isEmpty(records)) {
            return R.ok();
        }
        List<JSONObject> ret = new ArrayList<>();
        Map<String, String> deptMap = new HashMap<>();
        Map<String, SysUserSync> userMap = new HashMap<>();
        List<String> deptIdList = records.stream().filter(e -> e.getType() == 0).map(CoreModulePermissions::getRelId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(deptIdList)) {
            List<SysUserSyncCategory> deptList = iSysUserSyncCategoryService.list(new LambdaQueryWrapper<SysUserSyncCategory>()
                    .in(SysUserSyncCategory::getDeptId, deptIdList)
                    .like(StrUtil.isNotBlank(vo.getSearch()), SysUserSyncCategory::getName, vo.getSearch())
            );
            deptMap = deptList.stream().collect(Collectors.toMap(SysUserSyncCategory::getDeptId, SysUserSyncCategory::getName));
        }
        List<String> userIdList = records.stream().filter(e -> e.getType() == 1).map(CoreModulePermissions::getRelId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(userIdList)) {
            List<SysUserSync> userList = sysUserSyncService.listByUserIds(userIdList, vo.getSearch());
            userMap = userList.stream().collect(Collectors.toMap(SysUserSync::getUserId, e -> e));
        }
        for (CoreModulePermissions record : records) {
            if (record.getType() == 0) {
                JSONObject object = JSONUtil.parseObj(record);
                if (deptMap.containsKey(record.getRelId())) {
                    object.putOpt("name", deptMap.get(record.getRelId()));
                    object.putOpt("deptName", deptMap.get(record.getRelId()));
                    ret.add(object);
                }
            } else if (record.getType() == 1) {
                if (userMap.containsKey(record.getRelId())) {
                    JSONObject object = JSONUtil.parseObj(record);
                    object.putOpt("name", userMap.get(record.getRelId()).getName());
                    object.putOpt("deptName", userMap.get(record.getRelId()).getDepartment());
                    ret.add(object);
                }
            }
        }
        return R.ok(ret);
    }

    @PostMapping("/userList")
    public R list(@RequestBody @Validated AgentAuthVO.UserList vo) {
        List<CoreModulePermissions> list = iAgentAuthService.list(new LambdaQueryWrapper<CoreModulePermissions>()
                .eq(CoreModulePermissions::getTenantId, vo.getTenantId()));
        Set<String> userIdList = new HashSet<>();
        Set<String> deptIdList = new HashSet<>();
        if (CollUtil.isNotEmpty(list)) {
            deptIdList = list.stream().filter(e -> e.getType() == 0).map(CoreModulePermissions::getRelId).collect(Collectors.toSet());
            userIdList = list.stream().filter(e -> e.getType() == 1).map(CoreModulePermissions::getRelId).collect(Collectors.toSet());
        }
        List<SysUserSyncCategory> categories;
        List<SysUserSync> userSyncs = new ArrayList<>();
        if (StrUtil.isNotBlank(vo.getSearch())) {
            categories = iSysUserSyncCategoryService.list(new LambdaQueryWrapper<SysUserSyncCategory>()
                    .like(StrUtil.isNotBlank(vo.getSearch()), SysUserSyncCategory::getName, vo.getSearch())
                    .select(SysUserSyncCategory::getDeptId, SysUserSyncCategory::getName)
            );
            userSyncs = sysUserSyncService.list(new LambdaQueryWrapper<SysUserSync>()
                    .like(StrUtil.isNotBlank(vo.getSearch()), SysUserSync::getName, vo.getSearch())
                    .select(SysUserSync::getUserId, SysUserSync::getName)
            );
        } else {
            if (vo.getCategoryId().equals(CategoryConstant.ROOT)) {
                categories = iSysUserSyncCategoryService.selectParentIdNoInId(vo.getSearch());
            } else {
                categories = iSysUserSyncCategoryService.list(new LambdaQueryWrapper<SysUserSyncCategory>()
                        .eq(SysUserSyncCategory::getParentId, vo.getCategoryId())
                        .like(StrUtil.isNotBlank(vo.getSearch()), SysUserSyncCategory::getName, vo.getSearch())
                        .select(SysUserSyncCategory::getDeptId, SysUserSyncCategory::getName)
                );

                userSyncs = sysUserSyncService.list(new LambdaQueryWrapper<SysUserSync>()
                        .eq(SysUserSync::getDeptId, vo.getCategoryId())
                        .like(StrUtil.isNotBlank(vo.getSearch()), SysUserSync::getName, vo.getSearch())
                        .select(SysUserSync::getUserId, SysUserSync::getName)
                );
            }
        }
        List<JSONObject> cateObjects = new ArrayList<>();

        if (CollUtil.isNotEmpty(categories)) {
            for (SysUserSyncCategory category : categories) {
                JSONObject o = new JSONObject();
                o.putOpt("id", category.getDeptId());
                o.putOpt("name", category.getName());
                o.putOpt("checked", deptIdList.contains(category.getDeptId()));
                cateObjects.add(o);
            }
        }
        List<JSONObject> userObjects = new ArrayList<>();
        if (CollUtil.isNotEmpty(userSyncs)) {
            for (SysUserSync sysUserSync : userSyncs) {
                JSONObject o = new JSONObject();
                o.putOpt("id", sysUserSync.getUserId());
                o.putOpt("name", sysUserSync.getName());
                o.putOpt("checked", userIdList.contains(sysUserSync.getUserId()));
                userObjects.add(o);
            }
        }

        JSONObject ret = new JSONObject();
        ret.putOpt("categoryList", cateObjects);
        ret.putOpt("userList", userObjects);
        return R.ok(ret);
    }

    @PostMapping("/save")
    public R save(@RequestBody List<CoreModulePermissions> data) {
        return R.ok(iAgentAuthService.saveBatch(data));
    }

    @GetMapping("/remove")
    public R remove(String id) {
        return R.ok(iAgentAuthService.removeById(id));
    }

}
