/*
 * Copyright 2024 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

// FIXME: Wha? We don't use this file directly.
#include "mfg_func_test_buttons.h"

#include "kernel/events.h"
#include "applib/fonts/fonts.h"
#include "applib/ui/ui.h"
#include "drivers/battery.h"
#include "services/common/battery/battery_monitor.h"
#include "services/common/new_timer/new_timer.h"

#include <stdio.h>

typedef struct {
  MfgFuncTestData *app_data;
  char text_top[32];
  TextLayer text_layer_top;
  TextLayer text_layer_center;
  char text_volt[16];
  TextLayer text_layer_volt;
  PathLayer bolt;
  TimerID poll_timer_id;
} BatteryTestData;

static void battery_polling_callback(void *timer_data) {
  BatteryTestData *data = (BatteryTestData*)timer_data;

  sprintf(data->text_volt, "%i mV", battery_get_millivolts());
  text_layer_set_text(&data->text_layer_volt, data->text_volt);

  const bool is_discharging = !battery_get_charge_state().is_charging;
  layer_set_hidden(&data->bolt.layer, is_discharging);
  layer_set_hidden(&data->text_layer_center.layer, !is_discharging);
}

static void stop_battery_polling(BatteryTestData *data) {
  if (data == NULL || data->poll_timer_id == TIMER_INVALID_ID) {
    return;
  }
  new_timer_delete(data->poll_timer_id);
  data->poll_timer_id = TIMER_INVALID_ID;
}

static void start_battery_polling(BatteryTestData *data) {
  if (data == NULL || data->poll_timer_id != TIMER_INVALID_ID) {
    stop_battery_polling(data);
  }
  const uint32_t poll_interval_ms = 300;
  if (data->poll_timer_id == TIMER_INVALID_ID) {
    data->poll_timer_id = new_timer_create();
  }
  new_timer_start(data->poll_timer_id, poll_interval_ms, battery_polling_callback, data, TIMER_START_FLAG_REPEATING);
}

static void battery_window_button_up(ClickRecognizerRef recognizer, void *context) {
  BatteryTestData *data = window_get_user_data(context);
  if (data->app_data->charge_test_done) {
    const bool animated = false;
    window_stack_pop(animated);
  } else {
    if (battery_get_charge_state().is_charging) {
      mfg_func_test_append_bits(MfgFuncTestBitChargeTestPassed);
      data->app_data->charge_test_done = true;
      stop_battery_polling(data);
      layer_set_hidden(&data->text_layer_volt.layer, true);
      layer_set_hidden(&data->bolt.layer, true);
      text_layer_set_text(&data->text_layer_center, "QC OK!");
      layer_set_hidden(&data->text_layer_center.layer, false);
    }
  }
}

static void battery_window_click_config_provider(void *context) {
  for (ButtonId button_id = BUTTON_ID_BACK; button_id < NUM_BUTTONS; ++button_id) {
    window_raw_click_subscribe(button_id, NULL, (ClickHandler) battery_window_button_up, context);
  }
}

static void battery_window_load(Window *window) {
  BatteryTestData *data = window_get_user_data(window);

  // Layout Battery Test Window:
  Layer *root = &window->layer;

  char addr_hex_str[BT_ADDR_FMT_BUFFER_SIZE_BYTES];
  bt_local_id_copy_address_hex_string(addr_hex_str);
  sprintf(data->text_top, "Quality Test\nMAC: %s", addr_hex_str);

  TextLayer *text_layer_top = &data->text_layer_top;
  text_layer_init(text_layer_top, &GRect(0, 0, 144, 168));
  text_layer_set_background_color(text_layer_top, GColorWhite);
  text_layer_set_text_color(text_layer_top, GColorBlack);
  text_layer_set_text(text_layer_top, data->text_top);
  text_layer_set_font(text_layer_top, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD));
  layer_add_child(root, &text_layer_top->layer);

  TextLayer *text_layer_center = &data->text_layer_center;
  text_layer_init(text_layer_center, &GRect(0, 60, 144, 40));
  text_layer_set_background_color(text_layer_center, GColorClear);
  text_layer_set_text_color(text_layer_center, GColorBlack);
  text_layer_set_text(text_layer_center, "Plug Charger");
  text_layer_set_font(text_layer_center, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
  layer_add_child(root, &text_layer_center->layer);

  TextLayer *text_layer_volt = &data->text_layer_volt;
  text_layer_init(text_layer_volt, &GRect(0, 128, 144, 40));
  text_layer_set_background_color(text_layer_volt, GColorBlack);
  text_layer_set_text_color(text_layer_volt, GColorWhite);
  text_layer_set_font(text_layer_volt, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD));
  layer_add_child(root, &text_layer_volt->layer);

  PathLayer *bolt = &data->bolt;
  path_layer_init(bolt, &BOLT_PATH_INFO);
  path_layer_set_fill_color(bolt, GColorBlack);
  path_layer_set_stroke_color(bolt, GColorClear);
  layer_set_frame(&bolt->layer, &GRect(58, 48, 28, 60));
  layer_set_hidden(&bolt->layer, true);
  layer_add_child(root, &bolt->layer);
}

static void battery_window_appear(Window *window) {
  BatteryTestData *data = window_get_user_data(window);
  start_battery_polling(data);
}

static void battery_window_disappear(Window *window) {
  BatteryTestData *data = window_get_user_data(window);
  stop_battery_polling(data);
}

static void push_battery_test_window(MfgFuncTestData *app_data) {
  static BatteryTestData s_battery_test_data;
  s_battery_test_data = (BatteryTestData) {
    .app_data = app_data,
    .poll_timer_id = TIMER_INVALID_ID,
  };

  // Battery Charge test window:
  Window *battery_window = &app_data->battery_window;
  window_init(battery_window, WINDOW_NAME("Mfg Func Test Battery"));
  window_set_overrides_back_button(battery_window, true);
  window_set_user_data(battery_window, app_data);
  window_set_click_config_provider_with_context(battery_window,
      (ClickConfigProvider) battery_window_click_config_provider, battery_window);
  window_set_window_handlers(battery_window, &(WindowHandlers) {
      .load = battery_window_load,
      .appear = battery_window_appear,
      .disappear = battery_window_disappear
  });
  window_set_user_data(battery_window, &s_battery_test_data);
  window_set_fullscreen(battery_window, true);

  const bool animated = false;
  window_stack_push(battery_window, animated);
}

