package com.czg;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.Row;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
@SuppressWarnings("all")
@ConditionalOnClass(name = "com.czg.annotation.SaAdminCheckPermission")
public class LoadingRole implements CommandLineRunner {
    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    public void run(String... args) {
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = this.requestMappingHandlerMapping.getHandlerMethods();
        handlerMethods.forEach((key, value) -> {
            Method method = value.getMethod();

            try {
                Class<?> controllerClass = method.getDeclaringClass();
                // 获取类上的 @RequestMapping 路径
                String classPath = "";
                if (controllerClass.isAnnotationPresent(RequestMapping.class)) {
                    RequestMapping classMapping = controllerClass.getAnnotation(RequestMapping.class);
                    classPath = classMapping.value().length > 0 ? classMapping.value()[0] : "";
                }

                // 获取方法上的注解路径和请求方式
                String methodPaths = "";
                String httpMethod = "UNKNOWN";

                if (method.isAnnotationPresent(GetMapping.class)) {
                    GetMapping mapping = method.getAnnotation(GetMapping.class);
                    methodPaths = mapping.value().length > 0 ? mapping.value()[0] : "";
                    httpMethod = "GET";
                } else if (method.isAnnotationPresent(PostMapping.class)) {
                    PostMapping mapping = method.getAnnotation(PostMapping.class);
                    methodPaths = mapping.value().length > 0 ? mapping.value()[0] : "";
                    httpMethod = "POST";
                } else if (method.isAnnotationPresent(PutMapping.class)) {
                    PutMapping mapping = method.getAnnotation(PutMapping.class);
                    methodPaths = mapping.value().length > 0 ? mapping.value()[0] : "";
                    httpMethod = "PUT";
                } else if (method.isAnnotationPresent(DeleteMapping.class)) {
                    DeleteMapping mapping = method.getAnnotation(DeleteMapping.class);
                    methodPaths = mapping.value().length > 0 ? mapping.value()[0] : "";
                    httpMethod = "DELETE";
                } else if (method.isAnnotationPresent(RequestMapping.class)) {
                    RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                    methodPaths = mapping.value().length > 0 ? mapping.value()[0] : "";
                    RequestMethod[] methods = mapping.method();
                    httpMethod = methods.length > 0 ? methods[0].name() : "ALL";
                }

                // 拼接路径并输出
                String fullPath = (classPath + "/" + methodPaths).replaceAll("//+", "/");


                // 使用反射获取注解（不 import SaAdminCheckPermission）
                Class<?> annotationClass = Class.forName("com.czg.annotation.SaAdminCheckPermission");
                Object annotation = AnnotationUtils.getAnnotation(method, (Class) annotationClass);

                if (annotation == null) return;

                // 通过反射获取注解的 value() 方法
                Method valueMethod = annotationClass.getMethod("value");
                String[] permissions = (String[]) valueMethod.invoke(annotation);

                Method nameMethod = annotationClass.getMethod("name");
                String permissionName = (String) nameMethod.invoke(annotation);

                Method parentNameMethod = annotationClass.getMethod("parentName");
                String parentName = (String) parentNameMethod.invoke(annotation);


                String parentId;
                String parentMenuSql = "select * from sys_menu where title=?";    // 查询菜单是否存在
                Row parentMenu;
//                parentMenu = Db.selectOneBySql(parentMenuSql, "默认接口目录");
//                if (parentMenu == null) {
//                    Db.insertBySql("INSERT INTO `sys_menu` (`type`, `title`) VALUES (?, ?);", 0, "默认接口目录");
//                }
//                parentMenu = Db.selectOneBySql(parentMenuSql, "默认接口目录");
//                if (StrUtil.isNotBlank(parentName)) {
//                    parentMenu = Db.selectOneBySql(parentMenuSql, parentName);
//                    if (parentMenu == null) {
//                        throw new RuntimeException(StrUtil.format("上级菜单不存在, 方法名{}， 方法路径:{}", method.getName(), fullPath));
//                    }
//                }
//                parentId = parentMenu.getString("menu_id");
                parentId = "1";

                Row childMenu;
                if (StrUtil.isNotBlank(parentName)) {
                    childMenu = Db.selectOneBySql(parentMenuSql, parentName);
                    if (childMenu == null) {
                        Db.insertBySql("INSERT INTO `sys_menu` (`type`, `pid`,`title`) VALUES (?,?, ?);", 0, parentId, parentName);
                        childMenu = Db.selectOneBySql(parentMenuSql, parentName);
                    }
                    parentId = childMenu.getString("menu_id");
                }

                for (String s : permissions) {
                    String sql = "select * from sys_menu where permission=?";

                    Row menu1 = Db.selectOneBySql(sql, s);
                    if (menu1 != null) {
                        Long menuId = menu1.getLong("menu_id");
                        String title = menu1.getString("title");
                        String url = menu1.getString("url");
                        String type = menu1.getString("type");
                        String method1 = menu1.getString("method");
                        String permission = menu1.getString("permission");
                        String pid = menu1.getString("pid");
//                        String listSql = "select * from sys_roles_menus where menu_id=? and role_id=?";
//                        List<Row> count1 = Db.selectListBySql(listSql, menuId, 1L);
//
//
//                        if (count1.isEmpty()) {
//                            sql = "INSERT INTO `sys_roles_menus` (`menu_id`, `role_id`) VALUES (?, ?);";
//                            Db.insertBySql(sql, menuId, 1L);
//                            log.info("接口菜单添加成功, 菜单名称: {}, 菜单权限: {}", title, permission);
//                        }

                        if (!title.equals(permissionName) || !fullPath.equals(url) || !httpMethod.equals(method1) || !parentId.equals(pid) || !"3".equals(type)) {
                            sql = "update sys_menu set title=?,type=?, url=?, method=?, pid=? where menu_id=?";
                            Db.updateBySql(sql, permissionName, 3, fullPath, httpMethod, parentId, menuId);
                            log.info("接口菜单修改成功, 旧名称: {}, 新菜单名称: {}", title, permissionName);
                        }
                        continue;
                    }

                    sql = "INSERT INTO `czg_cashier`.`sys_menu` (  `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`, `active_menu`, `is_shop`, `url`, `method`, `pid`) VALUES " +
                            "(0, 3, ?, NULL, '', 2, '', '', b'0', b'0', b'0', ?, NULL, NULL, ?, NULL, NULL, 0, ?, ?, ?);";
                    Db.insertBySql(sql, StrUtil.isNotBlank(permissionName) ? permissionName : s, s, DateUtil.date(), fullPath, httpMethod, parentId);
                    sql = "select * from sys_menu where permission=?";
                    Row info = Db.selectOneBySql(sql, s);
                    Long menuId = info.getLong("menu_id");

//                    sql = "INSERT INTO `sys_roles_menus` (`menu_id`, `role_id`) VALUES (?, ?);";
//                    Db.insertBySql(sql, menuId, 1L);

                    log.info("接口菜单添加成功, 菜单名称: {}, 菜单权限: {}", s, s);
                }
            } catch (ClassNotFoundException e) {
                log.warn("SaAdminCheckPermission 注解未找到，跳过权限检查");
            } catch (Exception e) {
                log.error("获取 SaAdminCheckPermission 注解失败", e);
            }
        });
    }

}
