#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);

    ui.open_settings();assert(ui.items()==4);
    ui.settings_click(false);assert(ui.menu==Menu::View && ui.items()==2);
    assert(ui.settings_click(false)==UiEffect::ReadReply);
    ui.agent_capabilities(true,true,true,true);assert(ui.items()==3);
    ui.index=2;ui.agent_capabilities(true,true,true,false);assert(ui.index==0 && ui.items()==2);
    ui.agent_capabilities(true,true,true,true);
    ui.index=1;assert(ui.settings_click(false)==UiEffect::History);
    ui.settings_back();assert(ui.menu==Menu::Root);
    ui.index=1;ui.settings_click(false);assert(ui.menu==Menu::Agent);
    for(unsigned i=0;i<ui.agent_count;++i)assert(ui.agent_actions[i]!=UiEffect::History);
    ui.settings_back();ui.index=2;ui.settings_click(false);assert(ui.menu==Menu::DeviceDisplay);
    for(unsigned i=0;i<3;++i) {
        ui.index=i;ui.settings_click(false);
        assert(ui.menu==(i==0?Menu::Device:i==1?Menu::Display:Menu::System));
        ui.index=ui.items()-1;ui.settings_click(false);assert(ui.menu==Menu::DeviceDisplay);
    }
    ui.settings_back();assert(ui.menu==Menu::Root);
    // Settings edits stay drafts until B applies them.
    ui.open_settings();ui.index=2;ui.settings_click(false);assert(ui.menu==Menu::DeviceDisplay);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=2;ui.settings_click(false);assert(ui.menu==Menu::DeviceDisplay);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);
    std::puts("Wearable shell immediate navigation/draft and UTC clock PASS");
}
