#pragma once
#include <luna/EscapeSequence.h>
#include <luna/Utf8.h>
#include <luna/Vector.h>
#include <os/Timer.h>
#include <stdio.h>
#include <termios.h>
#include <ui/Font.h>
#include <ui/Widget.h>

class TerminalWidget : public ui::Widget
{
  public:
    Result<void> init(char* const* args);

    Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) override;

    Result<void> draw(ui::Canvas& canvas) override;

  private:
    ui::Canvas m_terminal_canvas;
    Vector<u8> m_line_buffer;
    int m_pty;
    pid_t m_child_pid;

    struct termios m_settings;

    SharedPtr<ui::Font> m_font;
    SharedPtr<ui::Font> m_bold_font;

    OwnedPtr<os::Timer> m_cursor_timer;
    bool m_cursor_activated = false;
    bool m_cursor_enabled = true;

    long m_last_cursor_tick;

    int m_x_position { 0 };
    int m_y_position { 0 };

    bool m_bold { false };

    ui::Color m_foreground_color { ui::WHITE };
    ui::Color m_background_color { ui::BLACK };

    void tick_cursor();

    Utf8StateDecoder m_decoder;
    Option<EscapeSequenceParser> m_escape_parser;

    void draw_glyph(wchar_t c, int x, int y);
    void erase_current_line();
    void scroll();
    bool should_scroll();
    void next_line();
    void next_char();
    void prev_char();
    void erase_current_char();
    void draw_cursor();
    bool at_end_of_screen();
    bool handle_escape_sequence(wchar_t c);
    Result<bool> putchar(char c);
    bool put_code_point(wchar_t c);
    Result<void> process();
};