#include "bsp_key.h"
#include "bsp_motor.h"
#include "bsp_uart.h"
#include "bsp_led.h"
#include "bsp_ml307r.h"
#include "log.h"
#include "SLEEP.h"

// https://www.cnblogs.com/iot-fan/p/14304943.html

#undef LOG_ENABLE
#define LOG_ENABLE 1

#undef LOG_TAG
#define LOG_TAG "key"

uint8_t motor_flag;
tmosTaskID key_task_id = INVALID_TASK_ID;

volatile uint8_t key_wakeup_flag = 0;
volatile uint8_t key_timeout_flag = 0;

static app_task_evt_handler_t p_handler = NULL;

static volatile uint8_t key_timeout_cnt = 0;

void app_task_handler(TeAppEvtType app_evt_type)
{
    switch(app_evt_type)
    {
    case kKeyShort:{
        logDebug("button short press");
        break;
    }
    case kKeyLong:
        logDebug("button long press");

        break;
    case kKeyRelease:
        BSP_KEY_EnterLowpower();
        // DelayMs(10);
        BSP_RequestSleep();
        logDebug("gpio relase;BSP_RequestSleep ");
        break;
    default:
        break;
    }
}

static void KEY_Task_ProcessTmosMsg(tmos_event_hdr_t *pMsg)
{
    switch (pMsg->event)
    {
        default:
            logDebug("pMsg->event %04x", pMsg->event);
            break;
    }
}

#if 1
static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & SYS_EVENT_MSG)
    {
        uint8_t *pMsg;
        if ((pMsg = tmos_msg_receive(key_task_id)) != NULL)
        {
            KEY_Task_ProcessTmosMsg((tmos_event_hdr_t *)pMsg);
            // Release the TMOS message
            tmos_msg_deallocate(pMsg);
        }
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if (events & KEY_SCAN_EVT)
    {
        static volatile uint8_t key_vaild_times       = 0;
        static volatile uint8_t key_run               = 0;
        static volatile bool key_vaild_for_long_press = false;
        if (IS_KEY_Vaild())
        {
            if (key_vaild_times > (KEY_LONG_PRESS_MS / KEY_SACN_MS))
            { //> 20ms*100=2000ms
                if (false == key_vaild_for_long_press)
                {
                    if (NULL != p_handler)
                    {
                        p_handler(kKeyLong);
                        key_run = 1;
                    }
                    // PRINT("WE should power switch here\r\n");
                    key_vaild_for_long_press = true;
                }
            }
            else
            {
                key_vaild_times++;
            }
            key_timeout_cnt = 10;
        }
        else
        { // button release

            if (key_vaild_times)
            {
                if ((key_vaild_times) < (KEY_LONG_PRESS_MS / KEY_SACN_MS))
                {
                    p_handler(kKeyShort);
                    key_run = 1;
                }
                key_vaild_times = 0;
                // PRINT("KEY VAILED\r\n");
            }

            key_vaild_for_long_press = false;
        }
        if (key_timeout_cnt)
        {
            key_timeout_cnt--;
            logDebug("key_timeout_cnt %d", key_timeout_cnt);
            tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS)); // 40ms
        }
        else
        {
            // if(key_run == 1)
            // {
            //     p_handler(kKeyRelease);
            //     key_run = 0;
            // }
            if(key_run == 1)
            {
                // 确保按键已真正释放后再触发释放事件
                if (!IS_KEY_Vaild()) {
                    p_handler(kKeyRelease);
                    key_run = 0;
                } else {
                    // 按键仍未释放，继续检测
                    tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS));
                }
            }
        }
        return (events ^ KEY_SCAN_EVT);
    }

    // Discard unknown events
    return 0;
}

#endif

// 由按键中断唤醒后开启按键扫描
void BSP_KEY_EnterLowpower(void)
{
    // key_wakeup_flag = 0;
    // tmos_stop_task(key_task_id, KEY_SCAN_EVT);

    // R16_PB_INT_MODE |= KEY_B_PIN; // edge mode
    // GPIOB_ResetBits(KEY_B_PIN);   // edge fall
    // R16_PB_INT_IF = KEY_B_PIN;
    // R16_PB_INT_EN |= KEY_B_PIN;

    // 由外部上拉电阻了
    // 设置为浮空输入模式
    // GPIOB_SetBits(KEY_B_PIN);
    // GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);

    // TODO:按键电平触发设置
    // 下降沿触发
    GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);

    // 开启GPIO的睡眠唤醒,如果需要的话
    // PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
    PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);

    // 开启GPIOB中断
    PFIC_EnableIRQ(GPIO_B_IRQn);
}

void BSP_KEY_ExitLowpower(void)
{
    BSP_BlockSleep();

    // 关闭GPIOB中断
    PFIC_DisableIRQ(GPIO_B_IRQn);
    PWR_PeriphWakeUpCfg(DISABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
}

#if 0
uint8_t read_button_GPIO(uint8_t button_id)
{
    // you can share the GPIO read function with multiple Buttons
    switch(button_id)
    {
        case btn1_id:
            return (uint8_t)GPIOB_ReadPortPin(KEY_B_PIN);
        default:
            // logAssert(0, while (1));
            return 0;
    }
}

void BTN1_PRESS_DOWN_Handler(void* btn)
{
    logDebug("BTN1_PRESS_DOWN_Handler");
    // BSP_KEY_EnterLowpower();
}

void BTN1_PRESS_UP_Handler(void* btn)
{
    logDebug("BTN1_PRESS_UP_Handler");
    tmos_stop_task(key_task_id, KEY_IDLE_TIMEOUT_EVT);
    tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(1000 * 5));
    logDebug("tmos_start_task KEY_IDLE_TIMEOUT_EVT");
    // BSP_KEY_EnterLowpower();
}

void BTN1_SINGLE_Click_Handler(void* btn)
{
    logDebug("BTN1_SINGLE_Click_Handler");
    // BSP_KEY_EnterLowpower();
}

void BTN1_DOUBLE_Click_Handler(void* btn)
{
    logDebug("BTN1_DOUBLE_Click_Handler");
    // BSP_KEY_EnterLowpower();
}

void BTN1_LONG_PRESS_START_Handler(void* btn)
{
    logDebug("BTN1_LONG_PRESS_START_Handler");
    // BSP_KEY_EnterLowpower();
}

static uint16_t KEY_Task_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & SYS_EVENT_MSG)
    {
        uint8_t *pMsg;
        if ((pMsg = tmos_msg_receive(key_task_id)) != NULL)
        {
            KEY_Task_ProcessTmosMsg((tmos_event_hdr_t *)pMsg);
            // Release the TMOS message
            tmos_msg_deallocate(pMsg);
        }
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }
    // if (events & KEY_WAKEUP_EVT)
    // {
    //     logDebug("KEY_WAKEUP_EVT");

    //     BSP_KEY_ExitLowpower();
    //     return (events ^ KEY_WAKEUP_EVT);
    // }
    if (events & KEY_SCAN_EVT)
    {
        // 按键没抬起来就继续扫描
        if (0 == key_timeout_flag)
        {
            tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(5));
        }
        else
        {
            logDebug("KEY_SCAN_EVT timeout");
            BSP_KEY_EnterLowpower();
        }
        // logDebug("KEY_SCAN_EVT");
        button_ticks();

        return (events ^ KEY_SCAN_EVT);
    }
    if (events & KEY_IDLE_TIMEOUT_EVT)
    {
        tmos_stop_task(key_task_id, KEY_SCAN_EVT);
        BSP_KEY_EnterLowpower();
        logDebug("KEY_IDLE_TIMEOUT_EVT");
        key_timeout_flag = 1;
        return (events ^ KEY_IDLE_TIMEOUT_EVT);
    }


    // Discard unknown events
    return 0;
}
#endif

void BSP_KEY_Init(app_task_evt_handler_t handler)
{
    p_handler = handler;
    key_task_id = TMOS_ProcessEventRegister(KEY_Task_ProcessEvent);

    // 由外部上拉电阻了
    // 设置为浮空输入模式
    // GPIOB_SetBits(KEY_B_PIN);
    GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);

    // 下降沿触发
    GPIOB_ITModeCfg(KEY_B_PIN, GPIO_ITMode_FallEdge);

    // 开启GPIO的睡眠唤醒,如果需要的话
    // PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay);
    PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);

    // 开启GPIOB中断
    PFIC_EnableIRQ(GPIO_B_IRQn);

    tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(KEY_SACN_MS));

    // tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(5));

    //开始一个定时事件,不断的执行,除非运行tmos_stop_task关掉,
    //tmosTimer具体是 1600 = 1s
    // BSP_KEY_EnterLowpower();
}

__HIGH_CODE
__attribute__((noinline))
void KEY_ProcessLoop(void)
{
    static uint8_t key_flag = 0;
    // {
    //     if (R16_PB_INT_IF & KEY_B_PIN)
    //     {
    //         R16_PB_INT_IF = KEY_B_PIN;
    //         tmos_set_event(key_task_id, KEY_SCAN_EVT);
    //         logDebug("KEY_ProcessLoop");
    //     }
    // }

    if (key_wakeup_flag)
    {
        key_wakeup_flag = 0;
        key_flag = !key_flag;
        if(key_flag)
        {
            motor_flag = 1;
            logDebug("motor open");
        }
        else {
            motor_flag = 2;
            logDebug("motor close");
            logDebug("motor_flag_start = %d",motor_flag);
        }
        tmos_set_event(key_task_id, KEY_SCAN_EVT);
        logDebug("KEY_ProcessLoop");
    }

    // if (key_wakeup_flag)
    // {
    //     key_wakeup_flag = 0;
    //     tmos_set_event(key_task_id, KEY_SCAN_EVT);
    //     // tmos_start_task(key_task_id, KEY_SCAN_EVT, MS1_TO_SYSTEM_TIME(20));
    //     // tmos_start_task(key_task_id, KEY_IDLE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(1000 * 10));
    //     logDebug("key_wakeup_flag");
    // }
}


__INTERRUPT     // 告诉编译器使用硬件压栈
__HIGH_CODE // 放到RAM里
void GPIOB_IRQHandler(void)
{
    // 清除中断标志位
    GPIOB_ClearITFlagBit(KEY_B_PIN);

    // 检查是否为真实按键事件（通过确认电平是否真的接近0V）
    if (GPIOB_ReadPortPin(KEY_B_PIN) == 0) {
        // 再次确认是否真的为低电平（接近0V）
        DelayUs(50); // 短暂延时
        if (GPIOB_ReadPortPin(KEY_B_PIN) == 0) {
            // 确认是真实按键事件
            // 阻止睡眠
            BSP_BlockSleep();
            // 关按键中断
            BSP_KEY_ExitLowpower();

            printf("KEY IRQ");
            key_wakeup_flag = 1;
        }
    } else {
        // 可能是电源波动导致的中断，忽略此次中断
        printf("Power Fluctuation - Ignored");
    }
    // // 阻止睡眠
    // BSP_BlockSleep();
    // // 关按键中断
    // BSP_KEY_ExitLowpower();

    // printf("KEY IRQ");

    // GPIOB_ClearITFlagBit(KEY_B_PIN);

    // key_wakeup_flag = 1;

}
