#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/ledc.h"

#define BUTTON_A_PIN 5
#define BUTTON_B_PIN 6
#define BUTTON_C_PIN 7
#define LED_PIN 16
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_HIGH_SPEED_MODE
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_RESOLUTION LEDC_TIMER_13_BIT
#define LEDC_FREQ_HZ 5000

int led_brightness = 0;

void button_a_handler(void* arg)
{
    int button_a_state = gpio_get_level(BUTTON_A_PIN);
    if (button_a_state == 0) {
        led_brightness += 1;
        if (led_brightness > 100) {
            led_brightness = 100;
        }
        ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, ledc_percent_to_duty(LEDC_RESOLUTION, led_brightness));
        ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
    } else {
        int button_a_count = 0;
        while (gpio_get_level(BUTTON_A_PIN) == 1) {
            vTaskDelay(pdMS_TO_TICKS(500));
            button_a_count += 1;
            if (button_a_count >= 5) {
                led_brightness -= 1;
                if (led_brightness < 0) {
                    led_brightness = 0;
                }
                ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, ledc_percent_to_duty(LEDC_RESOLUTION, led_brightness));
                ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
                button_a_count = 0;
            }
        }
    }
}

void button_b_handler(void* arg)
{
    int button_b_state = gpio_get_level(BUTTON_B_PIN);
    if (button_b_state == 0) {
        led_brightness -= 1;
        if (led_brightness < 0) {
            led_brightness = 0;
        }
        ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, ledc_percent_to_duty(LEDC_RESOLUTION, led_brightness));
        ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
    } else {
        int button_b_count = 0;
        while (gpio_get_level(BUTTON_B_PIN) == 1) {
            vTaskDelay(pdMS_TO_TICKS(500));
            button_b_count += 1;
            if (button_b_count >= 5) {
                led_brightness += 1;
                if (led_brightness > 100) {
                    led_brightness = 100;
                }
                ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, ledc_percent_to_duty(LEDC_RESOLUTION, led_brightness));
                ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
                button_b_count = 0;
            }
        }
    }
}

void button_c_handler(void* arg)
{
    int button_c_state = gpio_get_level(BUTTON_C_PIN);
    if (button_c_state == 0) {
        int led_state = gpio_get_level(LED_PIN);
        gpio_set_level(LED_PIN, !led_state);
    }
}

void app_main()
{
    gpio_set_direction(BUTTON_A_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(BUTTON_A_PIN, GPIO_PULLUP_ONLY);
    gpio_set_direction(BUTTON_B_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(BUTTON_B_PIN, GPIO_PULLUP_ONLY);
    gpio_set_direction(BUTTON_C_PIN, GPIO_MODE_INPUT);
    gpio_set_pull_mode(BUTTON_C_PIN, GPIO_PULLUP_ONLY);
    gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);

    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_RESOLUTION,
        .freq_hz = LEDC_FREQ_HZ,
        .speed_mode = LEDC_MODE,
        .timer_num = LEDC_TIMER
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t ledc_channel = {
        .channel = LEDC_CHANNEL,
        .duty = 0,
        .gpio_num = LED_PIN,
        .speed_mode = LEDC_MODE,
        .timer_sel = LEDC_TIMER,
        .hpoint = 0,
        .intr_type = LEDC_INTR_DISABLE
    };
    ledc_channel_config(&ledc_channel);

    gpio_install_isr_service(0);
    gpio_isr_handler_add(BUTTON_A_PIN, button_a_handler, NULL);
    gpio_isr_handler_add(BUTTON_B_PIN, button_b_handler, NULL);
    gpio_isr_handler_add(BUTTON_C_PIN, button_c_handler, NULL);

    while (1) {
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}