#include "ui_state.h"
#include "device_status.h"
#include <cassert>
#include <cstdio>
#include <limits>
using namespace wearable;

int main() {
    DevicePreferences defaults;
    UiState ui;
    ui.boot(defaults);
    assert(ui.app==App::Watch);

    // Single clicks are dispatched immediately around the flat product ring.
    for(auto app:{App::Agent,App::Monitor,App::Help,App::Watch}) {ui.navigate(true);assert(ui.app==app);}
    for(auto app:{App::Help,App::Monitor,App::Agent,App::Watch}) {ui.navigate(false);assert(ui.app==app);}

    // Home preference changes only the boot destination.
    defaults.home_screen=Home::Agent;ui.boot(defaults);assert(ui.app==App::Agent);
    defaults.home_screen=Home::Monitor;ui.boot(defaults);assert(ui.app==App::Monitor);

    // Settings edits stay drafts until B applies them.
    ui.open_settings();ui.index=1;ui.settings_click(false);assert(ui.menu==Menu::Device);
    ui.settings_click(false);assert(ui.menu==Menu::Edit);
    for(int i=0;i<3;++i) assert(ui.settings_click(true)==UiEffect::None);
    assert(ui.preferences.brightness==80 && ui.draft.brightness==10);
    ui.close_settings();assert(ui.app==App::Monitor && ui.preferences.brightness==80);
    ui.open_settings();ui.index=1;ui.settings_click(false);ui.settings_click(false);
    ui.settings_click(true);assert(ui.settings_click(false)==UiEffect::Apply && ui.preferences.brightness==90);
    ui.index=1;ui.settings_click(false);ui.settings_click(true);assert(ui.settings_click(false)==UiEffect::Apply);
    assert(!ui.preferences.vibration_enabled);

    for(auto parent:{Menu::Device,Menu::Display}) {
        for(auto field:{Field::Brightness,Field::Vibration,Field::HomeScreen,Field::Text,Field::Theme}) {
            ui.open_settings();ui.menu=Menu::Edit;ui.editor_parent=parent;ui.field=field;
            Blob before{},after{};assert(encode(ui.preferences,1,before));
            ui.settings_click(true);ui.settings_back();
            assert(ui.menu==parent && ui.settings_open);
            assert(encode(ui.preferences,1,after) && before==after);
            assert(encode(ui.draft,1,after) && before==after);
        }
    }
        WallClock clock;assert(clock.utc_ms(0)==0);
    assert(!clock.sync(0,0) && !clock.sync(std::numeric_limits<double>::infinity(),0));
    assert(!clock.sync(1791072000000.5,0));assert(clock.sync(1791072000000,100));
    assert(clock.utc_ms(6100)==1791072006000); // Keeps advancing without network truth.
    assert(!clock.sync(1,8000) && clock.utc_ms(8100)==1791072008000);

    // ---- Settings > Network information architecture ---------------------
    ui.open_settings();
    // Root is Agent, Device, Display, Network, System, Back.
    assert(ui.items()==6);
    ui.index=3;assert(ui.settings_click(false)==UiEffect::None && ui.menu==Menu::Network);
    assert(ui.items()==4);
    // Network entry 0 opens the confirmed Wi-Fi Setup flow.
    ui.index=0;assert(ui.settings_click(false)==UiEffect::WifiSetup);
    // Entry 1 opens Known Networks.
    ui.index=1;assert(ui.settings_click(false)==UiEffect::None && ui.menu==Menu::KnownNetworks);
    ui.set_known({"Home-WiFi","Office"});
    assert(ui.items()==2+2); // 2 SSIDs + Forget All + Back
    // Selecting an SSID asks the board to forget exactly that network.
    ui.index=0;assert(ui.settings_click(false)==UiEffect::ForgetNetwork);
    ui.index=1;assert(ui.settings_click(false)==UiEffect::ForgetNetwork);
    // Forget All needs two presses: the first only arms the confirmation.
    ui.index=2;assert(ui.settings_click(false)==UiEffect::ForgetAllPending && ui.forget_confirm);
    assert(ui.settings_click(false)==UiEffect::ForgetAll && !ui.forget_confirm);
    // Moving the cursor cancels a pending confirmation.
    ui.index=1;ui.settings_click(false);assert(!ui.forget_confirm);
    ui.index=2;assert(ui.settings_click(false)==UiEffect::ForgetAllPending);
    ui.settings_click(true);assert(!ui.forget_confirm); // A cancels
    // Back returns to Network, then Root, then closes.
    ui.index=ui.items()-1;ui.settings_click(false);assert(ui.menu==Menu::Network);
    ui.index=ui.items()-1;ui.settings_click(false);assert(ui.menu==Menu::Root);
    ui.index=ui.items()-1;assert(ui.settings_click(false)==UiEffect::CloseSettings);
    // Long-B back from Known Networks steps one level, not out of Settings.
    ui.open_settings();ui.menu=Menu::KnownNetworks;
    assert(ui.settings_back()==UiEffect::None && ui.menu==Menu::Network);
    std::puts("Settings Network / Known Networks / Forget All confirmation PASS");
    std::puts("Wearable shell immediate navigation/draft and UTC clock PASS");
}
