#include "board.h"
#include "ui_state.h"
#include "history_view.h"
#include "agent_history.h"
#include "agent_display.h"
#include "agent_target.h"
#include "watch_status.h"
#include "shell_input_policy.h"
#include <cassert>
#include <cstdio>
#include <cstring>
#include <string>
#define ESP_LOGI(...) ((void)0)
#include "reader_state.inc"
PiState s_pi;
wearable::UiState s_ui;
wearable::ReplyReader s_reply_reader;
wearable::AgentBrowse s_agent_browse;
wearable::AgentHistoryCache s_history_cache;
wearable::HistoryScreen s_history_screen;
InputModal s_input_modal=InputModal::NONE;
std::string s_settings_phase,s_history_request;
bool s_history_loading=false,s_cloud_connected=true,s_message_visible=false;
bool s_watch_task_redraw_pending=false,s_pi_redraw_pending=false;
unsigned draws=0,cancels=0,locks=0;
uint64_t clock_ms=0;
void lock_display() {++locks;}
void unlock_display() {--locks;}
void draw_status(const char* ="ui_event") {++draws;}
uint64_t esp_timer_get_time() {return clock_ms*1000;}
bool pi_snapshot_changes_view(const board_pi_snapshot_t&) {return true;}
bool page_overlay_visible() {return s_input_modal!=InputModal::NONE;}
void stop_speech() {}
void set_pi_tail(const char*) {}
void append_pi_tail(const char*,const char*) {}
std::string selected_target() {return std::string("agent:")+s_pi.agent+":"+s_pi.session_id;}
void cancel_input(bool,const char*) {
    ++cancels;s_reply_reader.clear();s_ui.close_settings();s_input_modal=InputModal::NONE;
}
#include "reader_callbacks.inc"
void enter() {
    s_ui.open_settings();s_input_modal=InputModal::SETTINGS;s_settings_phase="REPLY";
    s_reply_reader.open(selected_target(),s_pi.agent,s_pi.final_text,3);
    s_reply_reader.screen.older();assert(s_reply_reader.screen.page==1);
}
int main() {
    board_pi_snapshot_t message={};message.agent="pi";message.session_id="one";
    message.final_text="cached assistant reply";message.state="DONE";
    board_set_pi_snapshot(&message);assert(locks==0);
    enter();const auto body=s_reply_reader.screen.body();const auto d=draws;
    // Real incoming snapshots with advancing time do not reload or repaint reader.
    for(unsigned i=0;i<12;++i) {clock_ms+=1000;message.elapsed_seconds=i;board_set_pi_snapshot(&message);}
    assert(s_reply_reader.screen.body()==body && s_reply_reader.screen.page==1 && draws==d);
    // Tool events and cleared transient final text cannot replace pinned assistant text.
    board_append_pi_activity("tool","tool log");assert(!s_reply_reader.updated && draws==d);
    message.final_text="";message.state="RUNNING";board_set_pi_snapshot(&message);
    assert(!s_reply_reader.updated && s_reply_reader.screen.page==1 && s_reply_reader.screen.body()==body);
    // New assistant chunks trigger exactly one badge repaint, retaining the page.
    board_append_pi_activity("text","new partial reply");assert(s_reply_reader.updated && draws==d+1);
    board_append_pi_activity("text","more partial reply");assert(draws==d+1);
    message.final_text="new completed reply";message.state="DONE";board_set_pi_snapshot(&message);
    assert(s_reply_reader.screen.page==1 && s_reply_reader.screen.body()==body && draws==d+1);
    // A real session switch closes and clears all prior reading/history state.
    const auto cancellations=cancels;message.session_id="two";board_set_pi_snapshot(&message);
    assert(cancels==cancellations+1 && !s_reply_reader.active && s_reply_reader.screen.empty());
    assert(s_input_modal==InputModal::NONE && !s_ui.settings_open && s_history_request.empty());
    enter();message.final_text="later reply in same session";const auto fresh=draws;board_set_pi_snapshot(&message);
    assert(s_reply_reader.updated && s_reply_reader.screen.page==1 && draws==fresh+1);
    assert(s_reply_reader.screen.body()=="new completed reply" && locks==0);
    std::puts("Production snapshot/activity callbacks: reader frozen, sticky badge, session switch clears/ closes PASS");
}
