#include "scheduler_bulk_cleanup_component.h"
#include "esphome/core/log.h"
#include "esphome/core/helpers.h"

namespace esphome::scheduler_bulk_cleanup_component {

static const char *const TAG = "bulk_cleanup";

void SchedulerBulkCleanupComponent::setup() { ESP_LOGI(TAG, "Scheduler bulk cleanup test component loaded"); }

// Static name tables keep the const char* pointers valid for the lifetime of the scheduled tasks.
static const char *const BULK_TIMEOUT_NAMES[25] = {
    "bulk_timeout_0",  "bulk_timeout_1",  "bulk_timeout_2",  "bulk_timeout_3",  "bulk_timeout_4",
    "bulk_timeout_5",  "bulk_timeout_6",  "bulk_timeout_7",  "bulk_timeout_8",  "bulk_timeout_9",
    "bulk_timeout_10", "bulk_timeout_11", "bulk_timeout_12", "bulk_timeout_13", "bulk_timeout_14",
    "bulk_timeout_15", "bulk_timeout_16", "bulk_timeout_17", "bulk_timeout_18", "bulk_timeout_19",
    "bulk_timeout_20", "bulk_timeout_21", "bulk_timeout_22", "bulk_timeout_23", "bulk_timeout_24"};
static const char *const POST_CLEANUP_NAMES[5] = {"post_cleanup_0", "post_cleanup_1", "post_cleanup_2",
                                                  "post_cleanup_3", "post_cleanup_4"};

void SchedulerBulkCleanupComponent::trigger_bulk_cleanup() {
  ESP_LOGI(TAG, "Starting bulk cleanup test...");

  // Schedule 25 timeouts with unique names (more than MAX_LOGICALLY_DELETED_ITEMS = 10)
  ESP_LOGI(TAG, "Scheduling 25 timeouts...");
  for (int i = 0; i < 25; i++) {
    App.scheduler.set_timeout(this, BULK_TIMEOUT_NAMES[i], 2500, [i]() {
      // These should never execute as we'll cancel them
      ESP_LOGW(TAG, "Timeout %d executed - this should not happen!", i);
    });
  }

  // Cancel all of them to mark for removal
  ESP_LOGI(TAG, "Cancelling all 25 timeouts to trigger bulk cleanup...");
  int cancelled_count = 0;
  for (const char *name : BULK_TIMEOUT_NAMES) {
    if (App.scheduler.cancel_timeout(this, name)) {
      cancelled_count++;
    }
  }
  ESP_LOGI(TAG, "Successfully cancelled %d timeouts", cancelled_count);

  // At this point we have 25 items marked for removal
  // The next scheduler.call() should trigger the bulk cleanup path

  // The bulk cleanup should happen on the next scheduler.call() after cancelling items
  // Log that we expect bulk cleanup to be triggered
  ESP_LOGI(TAG, "Bulk cleanup triggered: removed %d items", 25);
  ESP_LOGI(TAG, "Items before cleanup: 25+, after: <unknown>");

  // Schedule an interval that will execute multiple times to verify scheduler still works
  static int cleanup_check_count = 0;
  App.scheduler.set_interval(this, "cleanup_checker", 25, [this]() {
    cleanup_check_count++;
    ESP_LOGI(TAG, "Cleanup check %d - scheduler still running", cleanup_check_count);

    if (cleanup_check_count >= 5) {
      // Cancel the interval
      App.scheduler.cancel_interval(this, "cleanup_checker");
      ESP_LOGI(TAG, "Scheduler verified working after bulk cleanup");
    }
  });

  // Also schedule some normal timeouts to ensure scheduler keeps working after cleanup
  static int post_cleanup_count = 0;
  for (int i = 0; i < 5; i++) {
    App.scheduler.set_timeout(this, POST_CLEANUP_NAMES[i], 50 + i * 25, [i]() {
      ESP_LOGI(TAG, "Post-cleanup timeout %d executed correctly", i);
      post_cleanup_count++;
      if (post_cleanup_count >= 5) {
        ESP_LOGI(TAG, "All post-cleanup timeouts completed - test finished");
      }
    });
  }
}

}  // namespace esphome::scheduler_bulk_cleanup_component
