package com.zjrs.zwnw.auth.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zjrs.zwnw.auth.entity.FwOperator;
import com.zjrs.zwnw.auth.entity.FwOperatorMapper;
import com.zjrs.zwnw.auth.service.AuthRedisService;
import com.zjrs.zwnw.portal.entity.SSgMenuMapper;
import com.zjrs.zwnw.portal.entity.VRsSyYydhInfoMapper;
import com.zjrs.zwnw.portal.po.SSgMenuPO;
import com.zjrs.zwnw.portal.po.VRsSyYydhInfoPO;
import com.zjrs.zwnw.sxgl.entity.FwRight2ResourceMapper;
import com.zjrs.zwnw.sxgl.entity.FwrightMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 用户信息控制器
 * <p>
 * 对应原 leaf6-uni-cloud-uc-service 中的用户信息接口。
 * 前端在登录获取 Token 后调用此接口获取用户基本信息（loginUserDTO）。
 * 路径前缀为 /leaf6-uni-cloud-uc-service（与前端 vue.config.js 中的代理路径一致）。
 */
@RestController
public class UserInfoController {

    private static final Logger log = LoggerFactory.getLogger(UserInfoController.class);

    @Autowired
    private AuthRedisService authRedisService;

    @Autowired
    private VRsSyYydhInfoMapper vRsSyYydhInfoMapper;

    @Autowired
    private SSgMenuMapper sSgMenuMapper;

    @Autowired
    private FwrightMapper fwrightMapper;

    @Autowired
    private FwRight2ResourceMapper fwRight2ResourceMapper;

    @Autowired
    private FwOperatorMapper fwOperatorMapper;

    @GetMapping("/leaf6-uni-cloud-uc-service/api/users/{id}")
    public Map<String, Object> getUserById(@PathVariable("id") String id) {
        if (StringUtils.isEmpty(id)) {
            throw new org.springframework.web.server.ResponseStatusException(
                    org.springframework.http.HttpStatus.BAD_REQUEST, "ID不能为空");
        }

        FwOperator operator = fwOperatorMapper.selectByOperId(id);
        if (operator == null) {
            // 如果不是操作员ID，尝试作为sguserid查询？或者直接返回404
            // 鉴于用户请求示例是UUID，可能是operid
            throw new org.springframework.web.server.ResponseStatusException(
                    org.springframework.http.HttpStatus.NOT_FOUND, "用户不存在");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("id", operator.getOperid());
        result.put("loginId", operator.getLoginid());
        result.put("userName", operator.getOpername());
        result.put("operunitid", operator.getOperunitid());
        result.put("bae001", operator.getBae001());
        result.put("opertype", operator.getOpertype());
        
        return result;
    }

    /**
     * 获取当前登录用户信息
     * <p>
     * 请求方式：GET /leaf6-uni-cloud-uc-service/api/security/users/current/loginResponse
     * Header：Access-Token: eyJ...
     * <p>
     * 成功响应：{ "loginUserDTO": { "id": "...", "loginId": "...", "userName": "..." } }
     * 失败响应（Token 无效或已过期）：HTTP 401
     */
    @GetMapping("/leaf6-uni-cloud-uc-service/api/security/users/current/loginResponse")
    public Map<String, Object> getCurrentUser(HttpServletRequest request) {
        String token = request.getHeader("Access-Token");

        if (token == null || token.trim().isEmpty()) {
            log.warn("[UserInfo] 请求未携带 Access-Token");
            throw new org.springframework.web.server.ResponseStatusException(
                    org.springframework.http.HttpStatus.UNAUTHORIZED, "未提供 Token");
        }

        // 从 Redis 获取用户信息
        Map<String, Object> userInfo = authRedisService.getUserInfo(token.trim());
        if (userInfo == null) {
            log.warn("[UserInfo] Token 对应的用户信息不存在或已过期");
            throw new org.springframework.web.server.ResponseStatusException(
                    org.springframework.http.HttpStatus.UNAUTHORIZED, "Token 已过期，请重新登录");
        }

        // 构造前端期望的 loginUserDTO 格式
        Map<String, Object> loginUserDTO = new HashMap<>();
        loginUserDTO.put("id", userInfo.get("id"));
        loginUserDTO.put("loginId", userInfo.get("loginId"));
        loginUserDTO.put("userName", userInfo.get("userName"));
        loginUserDTO.put("operunitid", userInfo.get("operunitid"));
        loginUserDTO.put("bae001", userInfo.get("bae001"));
        loginUserDTO.put("opertype", userInfo.get("opertype"));
        loginUserDTO.put("belongsOrgName", userInfo.get("belongsOrgName"));

        Map<String, Object> result = new HashMap<>();
        result.put("loginUserDTO", loginUserDTO);

        log.debug("[UserInfo] 返回用户信息，loginId={}", userInfo.get("loginId"));
        return result;
    }

    @GetMapping("/leaf6-uni-cloud-uc-service/api/version")
    public Map<String, Object> getVersion() {
        Map<String, Object> result = new HashMap<>();
        result.put("version", "0.15.0");
        result.put("isShowVersion", true);
        return result;
    }

    @GetMapping("/leaf6-uni-cloud-uc-service/api/users/{id}/navMenus")
    public List<Map<String, Object>> getNavMenus(@PathVariable("id") String id, HttpServletRequest request) {
        String token = request.getHeader("Access-Token");
        Map<String, Object> userInfo = token == null ? null : authRedisService.getUserInfo(token.trim());
        String userId = null;
        if (userInfo != null && userInfo.get("id") != null) {
            userId = String.valueOf(userInfo.get("id"));
        } else {
            userId = id;
        }
        if (userId == null || userId.trim().isEmpty()) {
            return new ArrayList<>();
        }
        
        // 1. 查询用户常用/授权的扁平菜单列表 (基于视图 v_rs_sy_yydh_info)
        // 这个列表代表“用户拥有的应用权限”
        List<VRsSyYydhInfoPO> userApps = vRsSyYydhInfoMapper.selectList(
                new QueryWrapper<VRsSyYydhInfoPO>()
                        .eq("userid", userId)
        );
        
        // 提取用户拥有的应用 ID 集合
        Set<String> userAppIds = new HashSet<>();
        for (VRsSyYydhInfoPO app : userApps) {
            if (StringUtils.hasText(app.getCdid())) {
                userAppIds.add(app.getCdid().trim());
            }
        }
        
        // 如果用户没有任何应用权限，返回空列表
        if (userAppIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 从 S_SG_MENU 表加载完整菜单树结构 (替换之前的硬编码)
        List<SSgMenuPO> allMenus = sSgMenuMapper.selectList(
                new QueryWrapper<SSgMenuPO>().orderByAsc("ORDER_NUMBER")
        );
        
        if (allMenus == null || allMenus.isEmpty()) {
            log.warn("S_SG_MENU table is empty, returning empty menu tree");
            return new ArrayList<>();
        }

        // 构建 ID -> Node 映射
        Map<String, MenuNode> menuMap = new HashMap<>();
        for (SSgMenuPO po : allMenus) {
            MenuNode node = new MenuNode(
                po.getId(), 
                po.getMenuName(), 
                po.getIcon(), 
                po.getUrl(), 
                po.getParentId(), 
                po.getOrderNumber() != null ? po.getOrderNumber() : 999
            );
            menuMap.put(node.id, node);
        }

        // 3. 根据用户拥有的应用权限，筛选并补全树结构
        // 逻辑修正：如果用户拥有某个节点权限，则：
        //   (1) 该节点的所有祖先可见（向上递归）
        //   (2) 该节点的所有子孙可见（向下递归，级联显示子菜单）
        Set<String> visibleMenuIds = new HashSet<>();
        
        // 第一轮：标记直接拥有的权限节点
        for (String appId : userAppIds) {
            if (menuMap.containsKey(appId)) {
                visibleMenuIds.add(appId);
                // 级联添加所有子孙节点
                addDescendants(appId, menuMap, visibleMenuIds);
            }
        }
        
        // 第二轮：向上递归补全父节点
        boolean added;
        do {
            added = false;
            // 创建副本进行遍历，避免并发修改异常
            Set<String> currentIds = new HashSet<>(visibleMenuIds);
            for (String menuId : currentIds) {
                MenuNode node = menuMap.get(menuId);
                if (node != null && StringUtils.hasText(node.parentId)) {
                    if (!visibleMenuIds.contains(node.parentId)) {
                        visibleMenuIds.add(node.parentId);
                        added = true;
                    }
                }
            }
        } while (added);

        // 4. 组装树形结构
        List<MenuNode> rootNodes = new ArrayList<>();
        for (MenuNode node : menuMap.values()) {
            // 只处理可见节点
            if (!visibleMenuIds.contains(node.id)) {
                continue;
            }
            
            // 如果父节点为空，或者父节点不可见，则视为当前上下文的根节点
            // 注意：如果父节点存在但不可见（理论上第二轮已补全，除非数据异常），也暂且视为根节点显示，防止断链
            if (!StringUtils.hasText(node.parentId) || !menuMap.containsKey(node.parentId) || !visibleMenuIds.contains(node.parentId)) {
                rootNodes.add(node);
            } else {
                MenuNode parent = menuMap.get(node.parentId);
                parent.addChild(node);
            }
        }
        
        // 根节点排序
        rootNodes.sort(Comparator.comparingInt(o -> o.sortNo));

        // 转换为 Map 结构返回
        return convertToMapList(rootNodes);
    }
    
    // 递归添加所有子孙节点
    private void addDescendants(String parentId, Map<String, MenuNode> menuMap, Set<String> visibleMenuIds) {
        for (MenuNode node : menuMap.values()) {
            if (parentId.equals(node.parentId)) {
                if (!visibleMenuIds.contains(node.id)) {
                    visibleMenuIds.add(node.id);
                    // 继续递归添加该子节点的子孙
                    addDescendants(node.id, menuMap, visibleMenuIds);
                }
            }
        }
    }

    private List<Map<String, Object>> convertToMapList(List<MenuNode> nodes) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (MenuNode node : nodes) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", node.id);
            map.put("name", node.name);
            map.put("icon", node.icon);
            map.put("path", node.path);
            
            // OpenType 推断
            String openType = "1";
            if (node.path != null && (node.path.startsWith("http://") || node.path.startsWith("https://"))) {
                openType = "2";
            }
            map.put("openType", openType);
            
            if (!node.children.isEmpty()) {
                map.put("children", convertToMapList(node.children));
            }
            result.add(map);
        }
        return result;
    }

    // 内部类用于构建树
    static class MenuNode {
        String id;
        String name;
        String icon;
        String path;
        String parentId;
        int sortNo;
        List<MenuNode> children = new ArrayList<>();

        public MenuNode(String id, String name, String icon, String path, String parentId, int sortNo) {
            this.id = id;
            this.name = name;
            this.icon = icon;
            this.path = path;
            this.parentId = parentId;
            this.sortNo = sortNo;
        }
        
        public void addChild(MenuNode child) {
            children.add(child);
            children.sort(Comparator.comparingInt(o -> o.sortNo));
        }
    }

    // --- 保留原有辅助方法 (UserConfig, Avatar 等) ---

    @GetMapping("/leaf6-uni-cloud-uc-service/api/userConfig/find/{type}")
    public Map<String, Object> getUserConfig(@PathVariable("type") String type) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", type);
        if ("global-setting".equals(type)) {
            Map<String, Object> attribute = new HashMap<>();
            attribute.put("layout", "sider-layout");
            attribute.put("enableMultiTags", false);
            attribute.put("showBreadcrumb", false);
            result.put("attribute", attribute);
        }
        return result;
    }

    @PostMapping("/leaf6-uni-cloud-uc-service/api/userConfig/save")
    public Map<String, Object> saveUserConfig(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", request.get("type"));
        result.put("attribute", request.get("attribute"));
        return result;
    }

    @GetMapping("/leaf6-uni-cloud-uc-service/api/users/{id}/avatar")
    public ResponseEntity<byte[]> getAvatar(@PathVariable("id") String id) {
        String base64 = authRedisService.getUserAvatar(id);
        if (!StringUtils.hasText(base64)) {
            return ResponseEntity.noContent().build();
        }
        byte[] avatar;
        try {
            avatar = Base64.getDecoder().decode(base64);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.noContent().build();
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_PNG);
        return ResponseEntity.ok().headers(headers).body(avatar);
    }

    @PostMapping("/leaf6-uni-cloud-uc-service/api/users/{id}/avatar")
    public ResponseEntity<String> uploadAvatar(@PathVariable("id") String id, @RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("文件不能为空");
        }
        try {
            if (file.getSize() > 2 * 1024 * 1024) {
                return ResponseEntity.badRequest().body("文件大小不能超过2MB");
            }
            byte[] bytes = file.getBytes();
            String base64 = Base64.getEncoder().encodeToString(bytes);
            authRedisService.saveUserAvatar(id, base64);
            return ResponseEntity.ok("头像上传成功");
        } catch (Exception e) {
            log.error("头像上传失败", e);
            return ResponseEntity.status(500).body("头像上传失败: " + e.getMessage());
        }
    }
}
