#include "helper.h"

// TODO: move to driver
void clean_bomb(void) {
    // clear pending inputs
    clear_all_pressed_released();
    clear_wires_pressed_released_cut();

    // clear leds
    led_strip_clear(leds);
    led_strip_refresh(leds);

    // clear module timer
    stop_module_timer();
    set_module_time(0);
    uint8_t clear[4] = {0};
    set_module_sseg_raw(clear);

    // clear char lcd
    lcd_clear();
    lcd_set_cursor_vis(false);
    lcd_cursor_home();
}

static const int STRING_MAX_LEN = 8;
void do_star_codes(StarCodeHandler* star_codes, int star_codes_len) {
    KeypadKey key;

    int current_idx = 0;
    char current[STRING_MAX_LEN+1] = {0};

    while (1) {
        while (get_pressed_keypad(&key)) {
            if (key == KeypadKey::star) {
                current[0] = '*';
                for (int i = 1; i < STRING_MAX_LEN; i++) {
                    current[i] = 0;
                }
                current_idx = 1;
            } else if (key == KeypadKey::pound) {
                // submit
                if (current[0] == '\0') {
                    continue;
                }

                bool hit = false;
                for (int i = 0; i < star_codes_len; i++) {
                    StarCodeHandler sch = star_codes[i];
                    if (strcmp(current, sch.code) == 0) {
                        hit = true;
                        lcd_print(1, 2, sch.display_text);
                        vTaskDelay(pdMS_TO_TICKS(2000));
                        if (sch.callback != nullptr) {
                            (sch.callback)();
                        }
                        if (sch.should_exit) {
                            return;
                        }
                        break;
                    }
                }
                
                if (!hit) {
                    lcd_print(1, 2, "Invalid Star Code");
                    vTaskDelay(pdMS_TO_TICKS(2000));
                }
                
                // clear
                for (int i = 0; i < STRING_MAX_LEN; i++) {
                    current[i] = 0;
                }
                current_idx = 0;
            } else {
                // out of room. skip
                if (current_idx >= STRING_MAX_LEN) break;
                // no code started.
                if (current[0] != '*') continue;

                char c = char_of_keypad_key(key);
                current[current_idx++] = c;
            }
            // ESP_LOGI(STEP0_TAG, "Pressed: %c", c);

            lcd_clear();
            lcd_print(1, 1, current);
        }

        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

static lv_style_t game_results_style;
static lv_obj_t* game_results_label;

static char str_buf[10] = {0};
static char* write_time(uint32_t game_time) {
    uint8_t hours = (game_time / (1000*60*60)) % 10;
    uint8_t minutes = (game_time / (1000*60)) % 60;
    uint8_t seconds = (game_time / (1000)) % 60;

    sprintf(str_buf, "%d:%02d:%02d", hours, minutes, seconds);
    return str_buf;
}

extern uint32_t initial_game_time;
void display_game_results(void) {
    if (xSemaphoreTake(xGuiSemaphore, portMAX_DELAY) == pdTRUE) {
        lv_style_init(&game_results_style);
        lv_style_set_text_color(&game_results_style, lv_color_white());
        lv_style_set_bg_color(&game_results_style, lv_color_black());
        lv_style_set_bg_opa(&game_results_style, LV_OPA_100);
        lv_style_set_text_align(&game_results_style, LV_TEXT_ALIGN_CENTER);

        game_results_label = lv_label_create(lv_scr_act());
        lv_obj_align(game_results_label, LV_ALIGN_CENTER, 0, 0);
        lv_obj_add_style(game_results_label, &game_results_style, LV_STATE_DEFAULT);

        char buf[100] = {0};
        int32_t time_s = get_game_time();
        int32_t time_spent = initial_game_time - time_s;
        char* time = write_time(time_spent);
        sprintf(buf, "Finished!\nTotal Time (w/ penalties): %s\nTotal Strikes: %ld", time, total_strikes);

        lv_label_set_text(game_results_label, buf);

        xSemaphoreGive(xGuiSemaphore);
    }
}
