package com.pangu.system.controller;

import com.pangu.common.core.controller.BaseController;
import com.pangu.common.core.domain.AjaxResult;
import com.pangu.common.core.page.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 角色管理Controller
 * @author 湖北新华业务中台研发团队
 */
@RestController
@RequestMapping("/api/system/role")
public class SysRoleController extends BaseController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询角色列表
     */
    @GetMapping("/list")
    public TableDataInfo list(
            @RequestParam(required = false) String roleName,
            @RequestParam(required = false) String roleKey,
            @RequestParam(required = false) String status,
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT role_id, role_name, role_key, role_sort, data_scope, status, create_time, remark ");
        sql.append("FROM sys_role WHERE del_flag = '0' ");
        
        List<Object> params = new ArrayList<>();
        if (roleName != null && !roleName.isEmpty()) {
            sql.append("AND role_name LIKE ? ");
            params.add("%" + roleName + "%");
        }
        if (roleKey != null && !roleKey.isEmpty()) {
            sql.append("AND role_key LIKE ? ");
            params.add("%" + roleKey + "%");
        }
        if (status != null && !status.isEmpty()) {
            sql.append("AND status = ? ");
            params.add(status);
        }
        
        String countSql = "SELECT COUNT(*) FROM (" + sql.toString() + ") t";
        Integer total = jdbcTemplate.queryForObject(countSql, params.toArray(), Integer.class);
        
        sql.append("ORDER BY role_sort LIMIT ? OFFSET ?");
        params.add(pageSize);
        params.add((pageNum - 1) * pageSize);
        
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql.toString(), params.toArray());
        
        TableDataInfo dataInfo = new TableDataInfo();
        dataInfo.setCode(200);
        dataInfo.setMsg("查询成功");
        dataInfo.setRows(rows);
        dataInfo.setTotal(total != null ? total : 0);
        return dataInfo;
    }

    /**
     * 获取角色详情
     */
    @GetMapping("/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId) {
        String sql = "SELECT * FROM sys_role WHERE role_id = ? AND del_flag = '0'";
        List<Map<String, Object>> roles = jdbcTemplate.queryForList(sql, roleId);
        if (roles.isEmpty()) {
            return AjaxResult.error("角色不存在");
        }
        
        Map<String, Object> role = roles.get(0);
        
        // 查询角色菜单
        String menuSql = "SELECT menu_id FROM sys_role_menu WHERE role_id = ?";
        List<Long> menuIds = jdbcTemplate.queryForList(menuSql, Long.class, roleId);
        role.put("menuIds", menuIds);
        
        return AjaxResult.success(role);
    }

    /**
     * 新增角色
     */
    @PostMapping
    public AjaxResult add(@RequestBody Map<String, Object> role) {
        String roleName = (String) role.get("roleName");
        String roleKey = (String) role.get("roleKey");
        
        // 检查角色名是否存在
        Integer count = jdbcTemplate.queryForObject(
            "SELECT COUNT(*) FROM sys_role WHERE role_name = ? AND del_flag = '0'",
            Integer.class, roleName);
        if (count != null && count > 0) {
            return AjaxResult.error("角色名称已存在");
        }
        
        // 检查角色标识是否存在
        count = jdbcTemplate.queryForObject(
            "SELECT COUNT(*) FROM sys_role WHERE role_key = ? AND del_flag = '0'",
            Integer.class, roleKey);
        if (count != null && count > 0) {
            return AjaxResult.error("角色标识已存在");
        }
        
        String sql = "INSERT INTO sys_role (role_name, role_key, role_sort, data_scope, status, " +
                    "create_by, create_time, remark) VALUES (?, ?, ?, ?, ?, 'admin', NOW(), ?)";
        
        jdbcTemplate.update(sql,
            roleName,
            roleKey,
            role.getOrDefault("roleSort", 0),
            role.getOrDefault("dataScope", "1"),
            role.getOrDefault("status", "0"),
            role.get("remark")
        );
        
        Long roleId = jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class);
        
        // 分配菜单权限
        if (role.get("menuIds") != null) {
            @SuppressWarnings("unchecked")
            List<Integer> menuIds = (List<Integer>) role.get("menuIds");
            for (Integer menuId : menuIds) {
                jdbcTemplate.update("INSERT INTO sys_role_menu (role_id, menu_id) VALUES (?, ?)", roleId, menuId);
            }
        }
        
        return AjaxResult.success("新增成功");
    }

    /**
     * 修改角色
     */
    @PutMapping
    public AjaxResult edit(@RequestBody Map<String, Object> role) {
        Long roleId = Long.valueOf(role.get("roleId").toString());
        
        if (roleId == 1) {
            return AjaxResult.error("不允许修改超级管理员角色");
        }
        
        String sql = "UPDATE sys_role SET role_name = ?, role_key = ?, role_sort = ?, " +
                    "data_scope = ?, status = ?, remark = ?, update_by = 'admin', update_time = NOW() " +
                    "WHERE role_id = ?";
        
        jdbcTemplate.update(sql,
            role.get("roleName"),
            role.get("roleKey"),
            role.getOrDefault("roleSort", 0),
            role.getOrDefault("dataScope", "1"),
            role.getOrDefault("status", "0"),
            role.get("remark"),
            roleId
        );
        
        // 更新菜单权限
        jdbcTemplate.update("DELETE FROM sys_role_menu WHERE role_id = ?", roleId);
        if (role.get("menuIds") != null) {
            @SuppressWarnings("unchecked")
            List<Integer> menuIds = (List<Integer>) role.get("menuIds");
            for (Integer menuId : menuIds) {
                jdbcTemplate.update("INSERT INTO sys_role_menu (role_id, menu_id) VALUES (?, ?)", roleId, menuId);
            }
        }
        
        return AjaxResult.success("修改成功");
    }

    /**
     * 删除角色
     */
    @DeleteMapping("/{roleIds}")
    public AjaxResult remove(@PathVariable String roleIds) {
        String[] ids = roleIds.split(",");
        for (String id : ids) {
            if ("1".equals(id)) {
                return AjaxResult.error("不允许删除超级管理员角色");
            }
            // 检查是否有用户使用该角色
            Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(*) FROM sys_user_role WHERE role_id = ?",
                Integer.class, Long.valueOf(id));
            if (count != null && count > 0) {
                return AjaxResult.error("角色已分配给用户，无法删除");
            }
            jdbcTemplate.update("UPDATE sys_role SET del_flag = '2' WHERE role_id = ?", Long.valueOf(id));
        }
        return AjaxResult.success("删除成功");
    }

    /**
     * 修改状态
     */
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody Map<String, Object> role) {
        Long roleId = Long.valueOf(role.get("roleId").toString());
        if (roleId == 1) {
            return AjaxResult.error("不允许修改超级管理员角色状态");
        }
        String status = (String) role.get("status");
        jdbcTemplate.update("UPDATE sys_role SET status = ?, update_time = NOW() WHERE role_id = ?",
            status, roleId);
        return AjaxResult.success("状态修改成功");
    }

    /**
     * 获取菜单树（用于权限分配）
     */
    @GetMapping("/menuTree")
    public AjaxResult menuTree() {
        String sql = "SELECT menu_id as id, parent_id as parentId, menu_name as label, menu_type " +
                    "FROM sys_menu WHERE status = '0' ORDER BY parent_id, order_num";
        List<Map<String, Object>> menus = jdbcTemplate.queryForList(sql);
        return AjaxResult.success(buildTree(menus));
    }

    /**
     * 获取角色已选菜单ID
     */
    @GetMapping("/roleMenuIds/{roleId}")
    public AjaxResult roleMenuIds(@PathVariable Long roleId) {
        String sql = "SELECT menu_id FROM sys_role_menu WHERE role_id = ?";
        List<Long> menuIds = jdbcTemplate.queryForList(sql, Long.class, roleId);
        return AjaxResult.success(menuIds);
    }

    private List<Map<String, Object>> buildTree(List<Map<String, Object>> list) {
        List<Map<String, Object>> result = new ArrayList<>();
        Map<Long, Map<String, Object>> nodeMap = new HashMap<>();
        
        for (Map<String, Object> node : list) {
            Long id = ((Number) node.get("id")).longValue();
            nodeMap.put(id, node);
            node.put("children", new ArrayList<Map<String, Object>>());
        }
        
        for (Map<String, Object> node : list) {
            Long parentId = ((Number) node.get("parentId")).longValue();
            if (parentId == 0) {
                result.add(node);
            } else {
                Map<String, Object> parent = nodeMap.get(parentId);
                if (parent != null) {
                    @SuppressWarnings("unchecked")
                    List<Map<String, Object>> children = (List<Map<String, Object>>) parent.get("children");
                    children.add(node);
                }
            }
        }
        return result;
    }
}
