#include <Arduino.h>
#include <WiFi.h>
#include <esp_task_wdt.h>
#include <ArduinoJson.h>
#include <Preferences.h>
#include "wifi_manager.h"
#include "radar_manager.h"

// ESP32 GPIO控制演示
#define BOOT_BUTTON_PIN 0   // Boot按钮引脚
#define NETWORK_LED_PIN 5    // 网络状态LED指示灯开发板48引脚，雷达板5引脚
#define CONFIG_CLEAR_PIN 4   // 配置清除指示灯
#define GPIO8 8              // 自定义GPIO8
#define GPIO9 9              // 自定义GPIO9

uint8_t WiFi_Connect_First_bit = 1; // WiFi首次连接标志位

// 配置清除指示灯状态枚举
enum ConfigClearStatus {
  CONFIG_NORMAL,     // 正常运行 - LOW
  CONFIG_PREPARING,  // 准备清除 - HIGH
  CONFIG_CLEARING,   // 清除过程中 - 呼吸灯
  CONFIG_COMPLETED   // 清除完成 - 快速闪烁3次
};

NetworkStatus currentNetworkStatus = NET_INITIAL; // 当前网络状态
unsigned long lastBlinkTime = 0; // 上次LED闪烁时间
bool ledState = false; // LED状态
int breatheValue = 0; // 呼吸灯当前亮度值
bool breatheIncreasing = true; // 呼吸灯是否在增加亮度

ConfigClearStatus currentConfigClearStatus = CONFIG_NORMAL; // 当前配置清除状态
unsigned long lastConfigBlinkTime = 0; // 上次配置清除LED闪烁时间
bool configLedState = false; // 配置清除LED状态
int configBreatheValue = 0; // 配置清除呼吸灯当前亮度值
bool configBreatheIncreasing = true; // 配置清除呼吸灯是否在增加亮度

const int SLOW_BLINK_INTERVAL = 1000; // 慢闪间隔（毫秒）
const int FAST_BLINK_INTERVAL = 200; // 快闪间隔（毫秒）
const int BREATHE_INTERVAL = 40; // 呼吸灯更新间隔（毫秒）
const int BREATHE_MIN = 0; // 呼吸灯最小亮度值
const int BREATHE_MAX = 155; // 呼吸灯最大亮度值
const int BREATHE_STEP = 5; // 呼吸灯亮度步进值

const uint16_t MIN_DEVICE_ID = 1000; // 最小设备ID
const uint16_t MAX_DEVICE_ID = 1999; // 最大设备ID

const unsigned long CLEAR_CONFIG_DURATION = 3000; // 清除配置持续时间（毫秒）

Preferences preferences; // Flash存储对象
WiFiManager wifiManager; // WiFi管理器对象

uint16_t currentDeviceId = 0000; // 当前设备ID
bool clearConfigRequested = false; // 清除配置请求标志
bool forceLedOff = false; // 强制关闭LED标志

void configClearLedTask(void *parameter);// 配置清除LED控制任务
void bootButtonMonitorTask(void *parameter);// BOOT按钮监控任务
void checkBootButton();// 检查Boot按钮状态
void clearStoredConfig();// 清除存储的配置
void ledControlTask(void *parameter);// LED控制任务
void setNetworkStatus(NetworkStatus status);// 设置网络状态
void wifiMonitorTask(void *parameter);// WiFi连接监控任务
void WiFiEvent(WiFiEvent_t event);// WiFi事件处理函数
void loadDeviceId();// 加载设备ID
void saveDeviceId();// 保存设备ID

String getFieldNameByProtocolId(int protocolId);// 根据协议ID获取字段名称

/**
 * @brief 根据协议ID获取字段名称
 * 将协议ID映射到对应的字段名称，用于数据序列化和反序列化
 * @param protocolId 协议ID
 * @return 对应的字段名称字符串
 */
String getFieldNameByProtocolId(int protocolId) {
  switch(protocolId) {
    case 1:
      return "heartRate";
    case 2:
      return "breathingRate";
    case 13:
      return "personDetected";
    case 14:
      return "humanActivity";
    case 15:
      return "humanDistance";
    case 16:
      return "humanPosition";
    case 17:
      return "sleepState";
    default:
      return "unknown";
  }
}

/**
 * @brief 检查Boot按钮状态
 * 在启动时检查Boot按钮是否被按下，如果按下则进入配置清除流程
 */
void checkBootButton() {
    Serial.println("🔍 检查Boot按钮状态...");
    
    pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
    
    delay(10);
    
    int buttonState = digitalRead(BOOT_BUTTON_PIN);// 读取Boot按钮状态，LOW表示按下，HIGH表示未按下
    Serial.printf("📊 Boot按钮状态: %s\n", buttonState == LOW ? "按下" : "释放");
    
    if (buttonState == LOW) {
        Serial.println("⚠️ 检测到Boot按钮按下，请释放按钮后继续启动");
        Serial.println("⏰ 等待按钮释放...");
        
        while (digitalRead(BOOT_BUTTON_PIN) == LOW) {
            delay(100);
        }
        
        Serial.println("✅ Boot按钮已释放，正常启动");
    } else {
        Serial.println("✅ Boot按钮未按下，正常启动");
    }
}

/**
 * @brief 加载设备ID
 * 从Flash中读取保存的设备ID
 */
void loadDeviceId() {
  currentDeviceId = preferences.getUShort("deviceId", 1001);
  Serial.printf("从Flash加载设备ID: %u\n", currentDeviceId);
}

/**
 * @brief 保存设备ID
 * 将设备ID保存到Flash中
 */
void saveDeviceId() {
  preferences.putUShort("deviceId", currentDeviceId);
  Serial.printf("设备ID已保存到Flash: %u\n", currentDeviceId);
}

/**
 * @brief 清除存储的配置
 * 清除Flash中保存的所有配置，包括设备ID和WiFi配置
 */
void clearStoredConfig() {
    Serial.println("🧹 开始清除存储的配置...");

    uint16_t oldDeviceId = preferences.getUShort("deviceId", 0);

    preferences.remove("deviceId");
    preferences.remove("wifi_first");

    wifiManager.clearAllConfigs();

    Serial.println("✅ 配置已清除完成");
    Serial.printf("🗑️ 被清除的设备ID: %u\n", oldDeviceId);

    currentDeviceId = 1001;
    WiFi_Connect_First_bit = 1;

    WiFi.disconnect(true);
    setNetworkStatus(NET_DISCONNECTED);

    Serial.println("🔄 已清除Flash与内存中的配置，请重新配置WiFi和设备ID");

    if (deviceConnected) {
        sendStatusToBLE();
    }
}

/**
 * @brief 配置清除LED控制任务
 * 根据配置清除状态控制CONFIG_CLEAR_PIN引脚的LED显示
 * @param parameter 任务参数（未使用）
 */
void configClearLedTask(void *parameter) {
  while (1) {
    switch (currentConfigClearStatus) {
      case CONFIG_NORMAL:
         analogWrite(CONFIG_CLEAR_PIN, 0);
        break;
        
      case CONFIG_PREPARING:
        analogWrite(CONFIG_CLEAR_PIN, 255);
        break;
        
      case CONFIG_CLEARING:
        if (millis() - lastConfigBlinkTime >= BREATHE_INTERVAL) {
          analogWrite(CONFIG_CLEAR_PIN, configBreatheValue);
          
          if (configBreatheIncreasing) {
            configBreatheValue += 5;
            if (configBreatheValue >= BREATHE_MAX) {
              configBreatheValue = BREATHE_MAX;
              configBreatheIncreasing = false;
            }
          } else {
            configBreatheValue -= 5;
            if (configBreatheValue <= BREATHE_MIN) {
              configBreatheValue = BREATHE_MIN;
              configBreatheIncreasing = true;
            }
          }
          lastConfigBlinkTime = millis();
        }
        break;
        
      case CONFIG_COMPLETED:
        if (millis() - lastConfigBlinkTime >= FAST_BLINK_INTERVAL) {
          configLedState = !configLedState;
          digitalWrite(CONFIG_CLEAR_PIN, configLedState ? HIGH : LOW);
          lastConfigBlinkTime = millis();
          
          static int blinkCount = 0;
          blinkCount++;
          
          if (blinkCount >= 6) {
            blinkCount = 0;
            currentConfigClearStatus = CONFIG_NORMAL;
            digitalWrite(CONFIG_CLEAR_PIN, LOW);
          }
        }
        break;
    }
    
    vTaskDelay(10 / portTICK_PERIOD_MS);// 每10ms检查一次状态
  }
}

/**
 * @brief BOOT按钮监控任务
 * 持续监控BOOT按钮状态，检测长按3秒事件并触发配置清除
 * @param parameter 任务参数（未使用）
 */
void bootButtonMonitorTask(void *parameter) {
  Serial.println("🔍 启动BOOT按钮监控任务...");
  
  pinMode(BOOT_BUTTON_PIN, INPUT_PULLUP);
  
  unsigned long buttonPressStartTime = 0;
  bool buttonPressed = false;
  
  while (1) {
    int buttonState = digitalRead(BOOT_BUTTON_PIN);
    
    if (buttonState == LOW && !buttonPressed) {
      buttonPressed = true;
      buttonPressStartTime = millis();
      Serial.println("⚠️ 检测到BOOT按钮按下，长按3秒将清除配置");
      
      currentConfigClearStatus = CONFIG_PREPARING;
    }
    else if (buttonState == HIGH && buttonPressed) {
      if (!clearConfigRequested) {
        currentConfigClearStatus = CONFIG_NORMAL;
        Serial.println("❌ 按钮释放，取消清除操作");
      }
      buttonPressed = false;
    }
    
    if (buttonPressed && (millis() - buttonPressStartTime >= CLEAR_CONFIG_DURATION)) {
      if (!clearConfigRequested) {
        clearConfigRequested = true;
        forceLedOff = true;
        ledcWrite(0, 0);
        Serial.println("✅ 长按3秒确认，将清除配置");
        Serial.println("💡 网络LED已强制熄灭");
        
        clearStoredConfig();
        
        Serial.println("🔄 配置清除完成，LED将闪烁3次表示完成...");
        
         analogWrite(CONFIG_CLEAR_PIN, 0);
        Serial.println("🔄 系统即将重启...");
        
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        ESP.restart();
      }
    }
    
    vTaskDelay(50 / portTICK_PERIOD_MS);
    
    esp_task_wdt_reset();
  }
}

/**
 * @brief LED控制任务
 * 根据网络状态控制NETWORK_LED_PIN引脚的LED显示
 * 支持慢闪、快闪和呼吸灯效果
 * @param parameter 任务参数（未使用）
 */
void ledControlTask(void *parameter) {
  while (1) {
    if (forceLedOff) {
      ledcWrite(0, 0);
      vTaskDelay(10 / portTICK_PERIOD_MS);
      continue;
    }
    
    switch (currentNetworkStatus) {
      case NET_INITIAL:
      case NET_DISCONNECTED:
        if (millis() - lastBlinkTime >= SLOW_BLINK_INTERVAL) {
          ledState = !ledState;
          if(ledState) {
            ledcWrite(0, 255);
          } else {
            ledcWrite(0, 0);
          }
          lastBlinkTime = millis();
        }
        break;
        
      case NET_CONNECTING:
        if (millis() - lastBlinkTime >= FAST_BLINK_INTERVAL) {
          ledState = !ledState;
          if(ledState) {
            ledcWrite(0, 255);
          } else {
            ledcWrite(0, 0);
          }
          lastBlinkTime = millis();
        }
        break;
        
      case NET_CONNECTED:
        if (millis() - lastBlinkTime >= BREATHE_INTERVAL) {
          ledcWrite(0, breatheValue);
          
          if (breatheIncreasing) {
            breatheValue += BREATHE_STEP;
            if (breatheValue >= BREATHE_MAX) {
              breatheValue = BREATHE_MAX;
              breatheIncreasing = false;
            }
          } else {
            breatheValue -= BREATHE_STEP;
            if (breatheValue <= BREATHE_MIN) {
              breatheValue = BREATHE_MIN;
              breatheIncreasing = true;
            }
          }
          lastBlinkTime = millis();
        }
        break;
    }
    
    vTaskDelay(10 / portTICK_PERIOD_MS);
  }
}

/**
 * @brief 设置网络状态
 * 更新当前网络状态，并重置呼吸灯参数
 * @param status 网络状态
 */
void setNetworkStatus(NetworkStatus status) {
  currentNetworkStatus = status;
  
  if (status == NET_CONNECTED) {
    breatheValue = BREATHE_MIN;
    breatheIncreasing = true;
  }
}

/**
 * @brief WiFi事件处理函数
 * 处理WiFi连接状态变化事件，更新网络状态和LED显示
 * @param event WiFi事件类型
 */
void WiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case ARDUINO_EVENT_WIFI_STA_START:
      setNetworkStatus(NET_INITIAL);
      break;
      
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      setNetworkStatus(NET_CONNECTING);
      break;
      
    case ARDUINO_EVENT_WIFI_STA_GOT_IP:
      setNetworkStatus(NET_CONNECTED);
      break;
      
    case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
      setNetworkStatus(NET_DISCONNECTED);
      break;
      
    case ARDUINO_EVENT_WIFI_STA_STOP:
      setNetworkStatus(NET_DISCONNECTED);
      break;
  }
}

/**
 * @brief WiFi监控任务
 * 定期更新WiFi管理器状态，处理WiFi重连等逻辑
 * @param parameter 任务参数（未使用）
 */
void wifiMonitorTask(void *parameter) {
    Serial.println("📡 WiFi监控任务启动");
    
    while(1) {
        wifiManager.update();
        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}

/**
 * @brief 系统初始化函数
 * 初始化所有硬件外设、任务和通信模块
 */
void setup() {
    Serial.begin(115200);
    
    checkBootButton();// 检查Boot按钮状态
    
    analogWrite(CONFIG_CLEAR_PIN, 0);
    
    Serial.println("🚀 ESP32-R60ABD1系统启动");
    Serial.println("🔧 初始化系统组件...");

  pinMode(BOOT_BUTTON_PIN, INPUT);
  pinMode(NETWORK_LED_PIN, OUTPUT);
  pinMode(CONFIG_CLEAR_PIN, OUTPUT);
  pinMode(GPIO8, OUTPUT);
  pinMode(GPIO9, OUTPUT);
  
  digitalWrite(CONFIG_CLEAR_PIN, LOW);
  digitalWrite(GPIO8, LOW);
  digitalWrite(GPIO9, LOW);
  digitalWrite(NETWORK_LED_PIN, LOW);
  digitalWrite(CONFIG_CLEAR_PIN, LOW);
  
  ledcSetup(0, 5000, 8);
  ledcSetup(1, 5000, 8);
  ledcAttachPin(NETWORK_LED_PIN, 0);
  ledcAttachPin(CONFIG_CLEAR_PIN, 1);
  
  WiFi.onEvent(WiFiEvent);// 注册WiFi事件处理函数

  setNetworkStatus(NET_INITIAL);// 设置初始网络状态
    
    esp_task_wdt_init(30, true);
    esp_task_wdt_add(NULL);
    
    preferences.begin("radar_data", false);
    
    wifiManager.begin();
    
    Serial.println("💾 加载设备配置...");
    loadDeviceId();

    Serial.println("🏗️ 初始化雷达管理器...");
    initRadarManager();
    
    xTaskCreate(
        configClearLedTask,
        "Config Clear LED Task",
        2048,
        NULL,
        1,
        NULL
    );
    
    xTaskCreate(
        bootButtonMonitorTask,
        "Boot Button Monitor Task",
        2048,
        NULL,
        1,
        NULL
    );
    
    xTaskCreate(
        ledControlTask,
        "LED Control Task",
        2048,
        NULL,
        1,
        NULL
    );
    
    xTaskCreate(
        wifiMonitorTask,
        "WiFi Monitor Task",
        4096,
        NULL,
        2,
        NULL
    );
    
    Serial.println("✅ FreeRTOS任务创建成功");
    
    Serial.println("📶 初始化BLE服务...");
    String deviceName = "Radar_" + String(currentDeviceId);
    BLEDevice::init(deviceName.c_str());
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());
    
    BLEService *pService = pServer->createService(SERVICE_UUID);
    pCharacteristic = pService->createCharacteristic(
                        CHARACTERISTIC_UUID,
                        BLECharacteristic::PROPERTY_READ |
                        BLECharacteristic::PROPERTY_WRITE |
                        BLECharacteristic::PROPERTY_NOTIFY
                      );
    pCharacteristic->setCallbacks(new MyCallbacks());
    pCharacteristic->addDescriptor(new BLE2902());
    
    pService->start();
    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x06);
    pAdvertising->setMinPreferred(0x12);
    BLEDevice::startAdvertising();
    
    Serial.println(String("BLE已启动，设备名称: Radar_") + String(currentDeviceId));
    
    Serial.println("🌐 检查WiFi配置...");
    if (wifiManager.getSavedNetworkCount() > 0) {
        Serial.printf("💾 检测到 %d 个已保存的WiFi配置，尝试连接...\n", wifiManager.getSavedNetworkCount());
        if (wifiManager.initializeWiFi()) {
            Serial.println("✅ WiFi连接成功！");
        } else {
            Serial.println("❌ WiFi连接失败，请通过BLE重新配置");
        }
    } else {
        Serial.println("⚠️ 未检测到WiFi配置，请通过BLE进行网络配置");
    }

    size_t wifi_first_len = preferences.getBytes("wifi_first", &WiFi_Connect_First_bit, sizeof(WiFi_Connect_First_bit));
    if (wifi_first_len == sizeof(WiFi_Connect_First_bit)) {
        Serial.printf("从Flash读取 WiFi_Connect_First_bit: %u\n", WiFi_Connect_First_bit);
    } else {
        Serial.println("Flash中无 wifi_first 条目，保留内存中原始值");
    }

    if(WiFi_Connect_First_bit == 0)
    {
        unsigned long wifiWaitStart = millis();
        unsigned long lastWifiWaitPrint = 0;
        const unsigned long WIFI_WAIT_TIMEOUT = 15000;
        while (WiFi.status() != WL_CONNECTED && (millis() - wifiWaitStart) < WIFI_WAIT_TIMEOUT) {
            if (millis() - lastWifiWaitPrint >= 1000) {
                Serial.println("等待WiFi连接...");
                lastWifiWaitPrint = millis();
            }
            yield();
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }
    }

    Serial.println("WiFi连接成功！");
    initR60ABD1();
    
    Serial.println("🎉 系统初始化完成，等待雷达数据...");
    
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("🌅 启动时发送睡眠数据到数据库");
        sendSleepDataToInfluxDB();
    }
}

/**
 * @brief 主循环函数
 * 处理BLE连接状态和定期发送雷达命令
 */
void loop() {
    esp_task_wdt_reset();
    
    if (!deviceConnected && oldDeviceConnected) {
        vTaskDelay(500 / portTICK_PERIOD_MS);
        pServer->startAdvertising();
        Serial.println("开始BLE广播");
        oldDeviceConnected = deviceConnected;
    }
    if (deviceConnected && !oldDeviceConnected) {
        oldDeviceConnected = deviceConnected;
    }
    {
        static const uint8_t radar_cmds[][3] = {
            {0x84, 0x81, 0x0F},
            {0x84, 0x8D, 0x0F},
            {0x84, 0x8F, 0x0F},
            {0x84, 0x8E, 0x0F},
            {0x84, 0x91, 0x0F},
            {0x84, 0x92, 0x0F},
            {0x84, 0x83, 0x0F},
            {0x84, 0x84, 0x0F},
            {0x84, 0x85, 0x0F},
            {0x84, 0x86, 0x0F},
            {0x84, 0x90, 0x0F}
        };

        const size_t cmdCount = sizeof(radar_cmds) / sizeof(radar_cmds[0]);
        static size_t cmdIndex = 0;
        static unsigned long lastCmdMillis = 0;
        const unsigned long CMD_INTERVAL = 2000UL;

        unsigned long now = millis();
        if (now - lastCmdMillis >= CMD_INTERVAL) {
            sendRadarCommand(radar_cmds[cmdIndex][0], radar_cmds[cmdIndex][1], radar_cmds[cmdIndex][2]);
            lastCmdMillis = now;
            cmdIndex++;
            if (cmdIndex >= cmdCount) cmdIndex = 0;
        }
    }

    processBLEConfig();
    esp_task_wdt_reset();
    esp_task_wdt_reset();
    
    esp_task_wdt_reset();
}
