#include "app_main_menu.h"
#include "../ui/ui_manager.h"
#include "app_config.h"
#include "app_input_pwd.h"
#include "data_config.h"
#include "app_real_time_data.h"
#include "app_dev_set_show.h"
#include "app_fix_set.h"
#include "app_fix_show.h"
#include "app_debugset.h"
#include "app_history_report.h"
#include "app_version_info.h"
#include <stdio.h>

/* ============================================================================
 * 菜单映射表优化设计说明
 * ----------------------------------------------------------------------------
 * 优化目标：使用映射表（结构体数组）替代原有的 switch-case 结构，提升代码
 *          可维护性和扩展性，同时保持密码验证等安全逻辑的正确性。
 *
 * 设计要点：
 * 1. 集中配置：所有菜单项的配置集中在 s_menu_mapping 数组中
 * 2. 直接映射：通过菜单索引直接访问配置，时间复杂度 O(1)
 * 3. 密码验证：需要密码的菜单项通过 pwd_callback 回调处理验证后逻辑
 * 4. 类型安全：使用函数指针类型定义，编译期检查参数匹配
 * 5. 常量存储：映射表使用 const 修饰，存储在 ROM 中节省 RAM
 * ============================================================================ */

/* 菜单页面创建函数类型定义 - 统一所有页面创建函数的签名 */
typedef void (*MenuPageCreateFunc)(PageCtx *ctx, uint8_t arg1, uint8_t arg2);

/* 密码验证回调函数类型定义 - 处理密码输入后的页面跳转和权限设置 */
typedef void (*PwdVerifiedCallback)(PageCtx *ctx, int pwd_val);

/* 菜单映射表项结构体 - 定义单个菜单项的完整配置 */
typedef struct {
    PageType            page_type;        /* 页面类型枚举，用于页面上下文 */
    CursorPosition      cursor_pos;       /* 默认光标位置 */
    uint8_t             left_menu_idx;    /* 左侧菜单默认选中索引 */
    uint8_t             right_data_idx;   /* 右侧数据默认选中索引 */
    MenuPageCreateFunc  create_func;      /* 页面创建函数指针，NULL 表示无需跳转 */
    bool                need_password;    /* 是否需要密码验证 */
    PwdVerifiedCallback pwd_callback;     /* 密码验证通过后的回调函数 */
} MenuMappingItem;

/* 静态函数前向声明 */
static void process_component_event(keyValue kval);
static void switch_to_subpage(uint8_t idx);
static void handle_direction_key(keyValue kval);
static void update_selection(uint8_t new_idx);
static void convert_service_to_ui_config(UIMainMenuConfig *ui_config, const MainMenuPageConfig *service_config);

/* 密码验证回调函数声明 - 用于需要密码的菜单项 */
static void on_dev_set_pwd_verified(PageCtx *ctx, int pwd_val);
static void on_dev_fix_pwd_verified(PageCtx *ctx, int pwd_val);

/* 全局状态变量 */
static uint8_t s_sel_idx = 0;
static UIMainMenuConfig s_ui_config = {0};

/* ============================================================================
 * 菜单映射表定义
 * ----------------------------------------------------------------------------
 * 说明：
 * 1. 使用指定初始化器语法 [索引] = { ... }，提高可读性和可维护性
 * 2. MAIN_MENU_DEV_SET 和 MAIN_MENU_DEV_FIX 需要密码验证
 * 3. 其他菜单项直接跳转，无需密码
 * 4. 若某菜单项暂时无实际页面，可将 create_func 设为 NULL
 * ============================================================================ */
static const MenuMappingItem s_menu_mapping[MAIN_MENU_NUM] = {
    /* [装置参数] - 需要密码验证 */
    [MAIN_MENU_DEV_SET] = {
        .page_type      = PAGE_DEV_SET,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = NULL,  /* 密码验证后通过回调创建页面 */
        .need_password  = true,
        .pwd_callback   = on_dev_set_pwd_verified
    },

    /* [定值设置] - 需要密码验证 */
    [MAIN_MENU_DEV_FIX] = {
        .page_type      = PAGE_DEV_FIX,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = NULL,  /* 密码验证后通过回调创建页面 */
        .need_password  = true,
        .pwd_callback   = on_dev_fix_pwd_verified
    },

    /* [装置参数查看] - 无需密码 */
    [MAIN_MENU_DEV_SET_SHOW] = {
        .page_type      = PAGE_DEV_SET_SHOW,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_dev_set_show_create_list_data,
        .need_password  = false,
        .pwd_callback   = NULL
    },

    /* [定值查看] - 无需密码 */
    [MAIN_MENU_DEV_FIX_SHOW] = {
        .page_type      = PAGE_DEV_FIX_SHOW,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_fix_show_create_list_data,
        .need_password  = false,
        .pwd_callback   = NULL
    },

    /* [实时数据] - 无需密码 */
    [MAIN_MENU_REAL_TIME_DATA] = {
        .page_type      = PAGE_REAL_TIME_DATA,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_rtd_create_list_data,
        .need_password  = false,
        .pwd_callback   = NULL
    },

    /* [历史数据] - 无需密码 */
    [MAIN_MENU_HISTORY_DATA] = {
        .page_type      = PAGE_HISTORY_DATA,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_history_report_create_list_data,
        .need_password  = false,
        .pwd_callback   = NULL
    },

    /* [调试测试] - 无需密码 */
    [MAIN_MENU_DEBUG_TEST] = {
        .page_type      = PAGE_DEBUG_TEST,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_debugset_create_list_data,
        .need_password  = false,
        .pwd_callback   = NULL
    },

    /* [版本信息] - 无需密码 */
    [MAIN_MENU_DEV_INFO] = {
        .page_type      = PAGE_DEV_INFO,
        .cursor_pos     = CURSOR_LEFT_MENU,
        .left_menu_idx  = 0,
        .right_data_idx = 0,
        .create_func    = (MenuPageCreateFunc)app_version_info_create_page,
        .need_password  = false,
        .pwd_callback   = NULL
    }
};

void app_main_menu_create_page(PageCtx *ctx, uint8_t selected_idx)
{
    if (ctx == NULL) {
        return;
    }

    main_menu_service_init();

    s_sel_idx = selected_idx;

    MainMenuPageConfig service_config = {0};
    main_menu_service_get_page_config(&service_config, s_sel_idx);
    convert_service_to_ui_config(&s_ui_config, &service_config);

    ui_main_menu_record_type((UIMainMenuType)s_sel_idx);

    UICursorState cursor_state = {0};
    cursor_state.cursor_pos = CURSOR_LEFT_MENU;
    cursor_state.left_menu_idx = s_sel_idx;
    ui_manager_cursor_set_value(cursor_state);

    ui_manager_main_menu_create(ctx, &s_ui_config);
}

void app_main_menu_handle_event(keyValue kval)
{
    UICursorState cursor_state = ui_manager_get_cursor();
    if (cursor_state.cursor_pos > CURSOR_RIGHT_DATA) {
        process_component_event(kval);
        return;
    }

    switch (kval) {
        case KEY_DATA_UP:
        case KEY_DATA_DOWN:
        case KEY_DATA_LEFT:
        case KEY_DATA_RIGHT:
            handle_direction_key(kval);     // 处理方向键
            break;

        case KEY_DATA_ENTER:
            switch_to_subpage(s_sel_idx);   // 进入子页面
            break;

        case KEY_DATA_BACK:
            ui_manager_switch_page(NULL);   // 返回首页
            break;

        default:
            break;
    }
}

static void convert_service_to_ui_config(UIMainMenuConfig *ui_config, const MainMenuPageConfig *service_config)
{
    if (ui_config == NULL || service_config == NULL) {
        return;
    }

    uint8_t i;
    for (i = 0; i < MAIN_MENU_NUM && i < UI_MAIN_MENU_NUM; i++) {
        ui_config->items[i].name = service_config->items[i].name;
        ui_config->items[i].need_password = service_config->items[i].need_password;
        ui_config->items[i].type = (UIMainMenuType)service_config->items[i].type;
    }
    ui_config->selected_idx = service_config->selected_idx;
}

static void handle_direction_key(keyValue kval)
{
    uint8_t new_idx = s_sel_idx;

    switch (kval) {
        case KEY_DATA_UP:
            if (s_sel_idx < 4) {
                new_idx = s_sel_idx + 4;
            } else {
                new_idx = s_sel_idx - 4;
            }
            break;

        case KEY_DATA_DOWN:
            if (s_sel_idx < 4) {
                new_idx = s_sel_idx + 4;
            } else {
                new_idx = s_sel_idx - 4;
            }
            break;

        case KEY_DATA_LEFT:
            if (s_sel_idx == 0) {
                new_idx = 7;
            } else if (s_sel_idx == 4) {
                new_idx = 3;
            } else {
                new_idx = s_sel_idx - 1;
            }
            break;

        case KEY_DATA_RIGHT:
            if (s_sel_idx == 3) {
                new_idx = 4;
            } else if (s_sel_idx == 7) {
                new_idx = 0;
            } else {
                new_idx = s_sel_idx + 1;
            }
            break;

        default:
            return;
    }

    update_selection(new_idx);
}

static void update_selection(uint8_t new_idx)
{
    if (new_idx >= MAIN_MENU_NUM) {
        return;
    }

    s_sel_idx = new_idx;
    s_ui_config.selected_idx = new_idx;

    UICursorState cursor_state = ui_manager_get_cursor();
    cursor_state.left_menu_idx = s_sel_idx;
    ui_manager_cursor_set_value(cursor_state);

    ui_manager_select_index(s_sel_idx);
}

/* ============================================================================
 * 密码验证回调函数实现
 * ----------------------------------------------------------------------------
 * 说明：以下回调函数在密码验证通过后被调用，负责：
 * 1. 根据密码值设置权限类型（超级密码/普通密码）
 * 2. 创建对应的设置页面
 * 3. 保持与原代码完全一致的权限判断逻辑
 * ============================================================================ */

/**
 * @brief 装置参数菜单密码验证回调
 * @param ctx   页面上下文指针，已预填充基础信息
 * @param pwd_val 用户输入的密码值
 *
 * 说明：对应原代码中 menu_idx == MAIN_MENU_DEV_SET 的处理逻辑
 *       超级密码(SUPER_PWD)赋予超级用户权限，其他正确密码赋予普通权限
 */
static void on_dev_set_pwd_verified(PageCtx *ctx, int pwd_val)
{
    if (ctx == NULL) {
        return;
    }

    /* 根据密码值设置权限类型 - 与原代码逻辑保持一致 */
    if (pwd_val == SUPER_PWD) {
        ctx->pwd_type = UI_PWD_TYPE_SUPER;
    } else if (pwd_val == Password_opt[2].value) {
        ctx->pwd_type = UI_PWD_TYPE_NORMAL;
    } else {
        /* 密码错误时默认无权限，实际场景应在调用前验证密码正确性 */
        ctx->pwd_type = UI_PWD_TYPE_NONE;
    }

    /* 创建设置页面 */
    app_dev_set_show_create_list_data(ctx, 0, 0);
}

/**
 * @brief 定值设置菜单密码验证回调
 * @param ctx   页面上下文指针，已预填充基础信息
 * @param pwd_val 用户输入的密码值
 *
 * 说明：对应原代码中 menu_idx == MAIN_MENU_DEV_FIX 的处理逻辑
 */
static void on_dev_fix_pwd_verified(PageCtx *ctx, int pwd_val)
{
    if (ctx == NULL) {
        return;
    }

    /* 根据密码值设置权限类型 - 与原代码逻辑保持一致 */
    if (pwd_val == SUPER_PWD) {
        ctx->pwd_type = UI_PWD_TYPE_SUPER;
    } else if (pwd_val == Password_opt[2].value) {
        ctx->pwd_type = UI_PWD_TYPE_NORMAL;
    } else {
        ctx->pwd_type = UI_PWD_TYPE_NONE;
    }

    /* 创建定值设置页面 */
    app_fix_set_create_list_data(ctx, 0, 0);
}

/* ============================================================================
 * 菜单跳转核心函数
 * ----------------------------------------------------------------------------
 * 说明：使用映射表替代原有的 switch-case 结构，实现 O(1) 的菜单跳转
 * 处理流程：
 * 1. 边界检查 - 确保索引有效性
 * 2. 密码检查 - 需要密码时切换到密码输入界面
 * 3. 页面创建 - 从映射表获取配置并创建页面
 * ============================================================================ */

/**
 * @brief 切换到指定菜单子页面
 * @param idx 菜单索引，对应 MenuType 枚举值
 *
 * 说明：
 * - 若菜单项需要密码验证，则保存当前状态并切换到密码输入界面
 * - 若无需密码，直接从映射表获取配置并创建目标页面
 * - 所有页面上下文参数均从映射表获取，避免硬编码
 */
static void switch_to_subpage(uint8_t idx)
{
    /* 边界检查：确保索引在有效范围内 */
    if (idx >= MAIN_MENU_NUM) {
        return;
    }

    /* 获取映射表项 - 常量指针确保不会意外修改配置 */
    const MenuMappingItem *item = &s_menu_mapping[idx];

    /* 密码验证检查：需要密码时切换到密码输入界面 */
    if (item->need_password) {
        UICursorState state = ui_manager_get_cursor();
        state.cursor_pos = CURSOR_INPUT_PWD;
        state.left_menu_idx = idx;
        ui_manager_cursor_set_value(state);
        ui_manager_comp_create_input_pwd();
        return;
    }

    /* 无需密码验证，直接创建目标页面 */
    PageCtx ctx = {0};

    /* 从映射表填充页面上下文 - 避免硬编码，提高可维护性 */
    ctx.cur_page = item->page_type;
    ctx.cursor_state.cursor_pos = item->cursor_pos;
    ctx.cursor_state.left_menu_idx = item->left_menu_idx;
    ctx.cursor_state.right_data_idx = item->right_data_idx;

    /* 调用页面创建函数 */
    if (item->create_func != NULL) {
        item->create_func(&ctx, 0, 0);
    }
    /* 注意：若 create_func 为 NULL 且无需密码，表示该菜单项暂无可跳转页面 */
}

/* ============================================================================
 * 组件事件处理函数
 * ----------------------------------------------------------------------------
 * 说明：处理密码输入等组件级事件
 * 优化点：使用映射表替代硬编码的菜单索引判断，提高可扩展性
 * ============================================================================ */

/**
 * @brief 处理组件级事件（如密码输入）
 * @param kval 按键值
 *
 * 处理流程：
 * 1. 检查当前光标状态是否为密码输入模式
 * 2. 获取密码输入值和目标菜单索引
 * 3. 根据按键类型执行相应操作：
 *    - ENTER：验证密码并通过回调创建页面
 *    - BACK/CANCEL：返回主菜单
 *
 * 安全说明：密码验证回调函数内部负责权限设置，本函数仅负责流程控制
 */
static void process_component_event(keyValue kval)
{
    UICursorState state = ui_manager_get_cursor();

    /* 仅处理密码输入状态下的事件 */
    if (state.cursor_pos != CURSOR_INPUT_PWD) {
        return;
    }

    uint8_t menu_idx = state.left_menu_idx;

    /* 边界检查：确保菜单索引有效 */
    if (menu_idx >= MAIN_MENU_NUM) {
        return;
    }

    /* 获取映射表项 */
    const MenuMappingItem *item = &s_menu_mapping[menu_idx];

    /* 确认该菜单项确实需要密码验证（防御性编程） */
    if (!item->need_password) {
        return;
    }
    int pwd_val = app_input_pwd_handle_event(kval);
    
    if (kval == KEY_DATA_ENTER) {
        

        /* 构建页面上下文 - 从映射表获取配置避免硬编码 */
        PageCtx ctx = {0};
        ctx.cur_page = item->page_type;
        ctx.cursor_state.cursor_pos = item->cursor_pos;
        ctx.cursor_state.left_menu_idx = item->left_menu_idx;
        ctx.cursor_state.right_data_idx = item->right_data_idx;

        /* 调用密码验证回调函数 - 由回调负责权限设置和页面创建 */
        if (item->pwd_callback != NULL) {
            item->pwd_callback(&ctx, pwd_val);
        }
    } else if (kval == KEY_DATA_BACK || kval == KEY_DATA_CANCEL) {
        /* 取消密码输入，返回主菜单 */
        ui_manager_switch_to_main_menu(menu_idx);
    }
}
