#ifndef TRANSTUI_UI_H
#define TRANSTUI_UI_H

#include <curses.h>
#include <time.h>
#include "../config.h"
#include "../rpc.h"
#include "../torrent.h"

typedef enum {
    VIEW_LIST,
    VIEW_DETAIL,
    VIEW_SETTINGS,
    VIEW_HELP,
} ViewMode;

/* Sidebar categories. Order here is the order shown in the left menu. */
typedef enum {
    FILTER_ALL,
    FILTER_DOWNLOADING,
    FILTER_UPLOADING,
    FILTER_PAUSED,
    FILTER_COMPLETED,
    FILTER_COUNT,
} FilterMode;

typedef enum {
    FOCUS_SIDEBAR,
    FOCUS_LIST,
} FocusZone;

typedef enum {
    SORT_NAME,
    SORT_SIZE,
    SORT_PROGRESS,
    SORT_STATUS,
    SORT_DOWN,
    SORT_UP,
    SORT_RATIO,
    SORT_ETA,
    SORT_COUNT,
} SortColumn;

typedef enum {
    DETAIL_GENERAL,
    DETAIL_FILES,
    DETAIL_PEERS,
    DETAIL_TRACKERS,
    DETAIL_TAB_COUNT,
} DetailTab;

/* Color pairs, initialized once in ui_init_colors(). */
enum {
    CP_DEFAULT = 1,
    CP_HEADER,
    CP_SELROW,
    CP_SEEDING,
    CP_DOWNLOADING,
    CP_PAUSED,
    CP_ERROR,
    CP_CHECK,
    CP_BORDER,
    CP_ACCENT,
    CP_SPLASH_WHITE,
};

/* A single "key -> what it does" entry for the footer hint bar. */
typedef struct {
    const char *key;
    const char *desc;
} KeyHint;

typedef struct {
    RpcClient *rpc;
    Config *cfg;
    int running;

    TorrentList list;
    /* indices into list.items after filtering+sorting, rebuilt each frame */
    int *order;
    size_t order_count;
    size_t order_capacity;

    int cursor;    /* index into order[] */
    int top;       /* first visible row, index into order[] */

    SortColumn sort_col;
    int sort_desc;
    FilterMode filter;
    char search[128];

    FocusZone focus;
    int sidebar_cursor;

    ViewMode view;

    int detail_id;
    TorrentDetail detail;
    int detail_loaded;
    DetailTab detail_tab;
    int detail_cursor;

    char status_msg[256];
    time_t status_msg_until;

    struct timespec last_poll;
    int need_poll_now;

    /* set once we've offered (accepted or not) to fix a torrent's download
     * directory permissions this session - see check_download_dir_perms() */
    int perm_fix_offered;
} AppState;

/* startup_msg, if non-NULL, is shown in the status bar in place of the
 * default "Connected to host:port" message once the initial list load
 * succeeds - used to report the result of a --add done before the TUI
 * started. */
int ui_run(RpcClient *rpc, Config *cfg, const char *startup_msg);

/* Shows the startup splash (block-letter logo) and returns once it's been on
 * screen for a bit or the user presses a key, whichever is first. Returns
 * that key (so the caller can act on it immediately instead of discarding
 * it), or ERR if the splash simply timed out. */
int ui_splash_show(void);

/* Offers to fix a broken *local* connection: "no daemon answering" (offer to
 * spawn transmission-daemon) or "daemon answered with 401" (offer to fix its
 * RPC auth via sudo), based on rpc->last_http_status. No-op for non-local
 * hosts (nothing we can sudo into on someone else's machine). Used both at
 * startup and from the settings popup's 'r' retry key. */
void ui_offer_reconnect_help(AppState *st);

/* shared helpers, used across ui_*.c */
void ui_set_status(AppState *st, const char *fmt, ...);
void ui_init_colors(void);
int ui_color_for_status(int status);
void ui_rebuild_order(AppState *st);
int ui_refresh_list(AppState *st);
void ui_open_detail(AppState *st, int torrent_id);
void ui_close_detail(AppState *st);

/* Draws a rounded ╭─╮ box border into win (h x w, starting at 0,0 in win's
 * own coordinates). Shared look for panels and popups. */
void ui_box(WINDOW *win, int h, int w);
/* Draws a title left-aligned into a box's top border, e.g. ui_box_title(win, w, "Filter"). */
void ui_box_title(WINDOW *win, int w, const char *title);
/* Renders a wrapping row of "key description" chips at the bottom `nrows`
 * lines of the screen (nrows capped to 2). Hints that don't fit are dropped. */
void ui_draw_footer(const KeyHint *hints, size_t n, int nrows);

/* modal dialogs (ui_dialogs.c) - block until answered, then redraw caller's view */
int ui_confirm(const char *title, const char *msg);
int ui_prompt(const char *title, const char *initial, char *out, size_t outsize);
void ui_message(const char *title, const char *msg);
/* Directory picker: navigate with arrows/Enter, `space` selects whichever
 * folder is currently open, Backspace goes up, Esc cancels. start_hint (may
 * be NULL/empty/nonexistent) is where browsing begins if it's a real
 * directory; otherwise falls back to the last folder browsed to, then
 * $HOME. Returns 1 with `out` filled on selection, 0 on cancel. */
int ui_folder_browser(const char *start_hint, char *out, size_t outsize);

void ui_dialog_add_torrent(AppState *st);
void ui_dialog_remove(AppState *st, const int *ids, size_t n);
void ui_dialog_speed_limit(AppState *st, const int *ids, size_t n);

/* per-view render+input handlers */
void ui_list_render(AppState *st);
/* Same as ui_list_render() but skips doupdate(), for use as a backdrop
 * under a popup that wants a single atomic flush (see ui_settings.c). */
void ui_list_render_content(AppState *st);
void ui_list_handle_key(AppState *st, int ch);

void ui_detail_render(AppState *st);
void ui_detail_handle_key(AppState *st, int ch);

void ui_settings_render(AppState *st);
void ui_settings_handle_key(AppState *st, int ch);
/* Fetches the daemon's current session settings and, if they don't match
 * what the user last explicitly set via the settings screen, pushes the
 * remembered values back - see reconcile_cache() in ui_settings.c. Called
 * once after the initial connection so an unclean daemon restart gets
 * fixed up even if the user never reopens settings. */
void ui_settings_reconcile_now(AppState *st);

void ui_help_render(AppState *st);
void ui_help_handle_key(AppState *st, int ch);

#endif
