package com.pangu.web.controller.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.pangu.common.core.domain.AjaxResult;

/**
 * 菜单管理Controller
 * 
 * @author 湖北新华业务中台研发团队
 */
@RestController
@RequestMapping("/api/system/menu")
public class SysMenuController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 查询菜单列表
     */
    @GetMapping("/list")
    public AjaxResult list(
            @RequestParam(required = false) String menuName,
            @RequestParam(required = false) String status) {

        StringBuilder sql = new StringBuilder();
        sql.append("SELECT menu_id, menu_name, parent_id, order_num, path, component, ");
        sql.append("query, is_frame, is_cache, menu_type, visible, status, perms, icon, create_time ");
        sql.append("FROM sys_menu WHERE 1=1 ");

        List<Object> params = new ArrayList<>();
        if (menuName != null && !menuName.isEmpty()) {
            sql.append("AND menu_name LIKE ? ");
            params.add("%" + menuName + "%");
        }
        if (status != null && !status.isEmpty()) {
            sql.append("AND status = ? ");
            params.add(status);
        }
        sql.append("ORDER BY parent_id, order_num");

        List<Map<String, Object>> menus = jdbcTemplate.queryForList(sql.toString(), params.toArray());
        return AjaxResult.success(menus);
    }

    /**
     * 获取菜单详情
     */
    @GetMapping("/{menuId}")
    public AjaxResult getInfo(@PathVariable Long menuId) {
        String sql = "SELECT * FROM sys_menu WHERE menu_id = ?";
        Map<String, Object> menu = jdbcTemplate.queryForMap(sql, menuId);
        return AjaxResult.success(menu);
    }

    /**
     * 获取菜单树
     */
    @GetMapping("/treeselect")
    public AjaxResult treeselect() {
        List<Map<String, Object>> menus = jdbcTemplate.queryForList(
                "SELECT menu_id, parent_id, menu_name FROM sys_menu ORDER BY parent_id, order_num");

        List<Map<String, Object>> tree = buildTree(menus, 0L);

        // 添加根节点
        List<Map<String, Object>> result = new ArrayList<>();
        Map<String, Object> root = new HashMap<>();
        root.put("id", 0L);
        root.put("label", "主目录");
        root.put("children", tree);
        result.add(root);

        return AjaxResult.success(result);
    }

    /**
     * 新增菜单
     */
    @PostMapping
    public AjaxResult add(@RequestBody Map<String, Object> menu) {
        String sql = "INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, " +
                "query, is_frame, is_cache, menu_type, visible, status, perms, icon, " +
                "create_by, create_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'admin', NOW())";

        jdbcTemplate.update(sql,
                menu.get("menuName"),
                menu.getOrDefault("parentId", 0),
                menu.getOrDefault("orderNum", 0),
                menu.get("path"),
                menu.get("component"),
                menu.get("query"),
                menu.getOrDefault("isFrame", 1),
                menu.getOrDefault("isCache", 0),
                menu.getOrDefault("menuType", "M"),
                menu.getOrDefault("visible", "0"),
                menu.getOrDefault("status", "0"),
                menu.get("perms"),
                menu.getOrDefault("icon", "#"));

        return AjaxResult.success();
    }

    /**
     * 修改菜单
     */
    @PutMapping
    public AjaxResult edit(@RequestBody Map<String, Object> menu) {
        Long menuId = Long.valueOf(menu.get("menuId").toString());
        Long parentId = menu.get("parentId") != null ? Long.valueOf(menu.get("parentId").toString()) : 0L;

        if (menuId.equals(parentId)) {
            return AjaxResult.error("修改菜单失败，上级菜单不能选择自己");
        }

        String sql = "UPDATE sys_menu SET menu_name = ?, parent_id = ?, order_num = ?, path = ?, " +
                "component = ?, query = ?, is_frame = ?, is_cache = ?, menu_type = ?, " +
                "visible = ?, status = ?, perms = ?, icon = ?, update_by = 'admin', update_time = NOW() " +
                "WHERE menu_id = ?";

        jdbcTemplate.update(sql,
                menu.get("menuName"),
                parentId,
                menu.getOrDefault("orderNum", 0),
                menu.get("path"),
                menu.get("component"),
                menu.get("query"),
                menu.getOrDefault("isFrame", 1),
                menu.getOrDefault("isCache", 0),
                menu.getOrDefault("menuType", "M"),
                menu.getOrDefault("visible", "0"),
                menu.getOrDefault("status", "0"),
                menu.get("perms"),
                menu.getOrDefault("icon", "#"),
                menuId);

        return AjaxResult.success();
    }

    /**
     * 删除菜单
     */
    @DeleteMapping("/{menuId}")
    public AjaxResult remove(@PathVariable Long menuId) {
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(*) FROM sys_menu WHERE parent_id = ?", Integer.class, menuId);
        if (count != null && count > 0) {
            return AjaxResult.error("存在子菜单，不允许删除");
        }

        count = jdbcTemplate.queryForObject(
                "SELECT COUNT(*) FROM sys_role_menu WHERE menu_id = ?", Integer.class, menuId);
        if (count != null && count > 0) {
            return AjaxResult.error("菜单已分配给角色，不允许删除");
        }

        jdbcTemplate.update("DELETE FROM sys_menu WHERE menu_id = ?", menuId);
        return AjaxResult.success();
    }

    private List<Map<String, Object>> buildTree(List<Map<String, Object>> list, Long parentId) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> item : list) {
            Long pid = ((Number) item.get("parent_id")).longValue();
            if (pid.equals(parentId)) {
                Map<String, Object> node = new HashMap<>();
                Long id = ((Number) item.get("menu_id")).longValue();
                node.put("id", id);
                node.put("label", item.get("menu_name"));
                List<Map<String, Object>> children = buildTree(list, id);
                if (!children.isEmpty()) {
                    node.put("children", children);
                }
                result.add(node);
            }
        }
        return result;
    }
}
