#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <U8g2_for_Adafruit_GFX.h>
#include "game.h"
#include "init.h"
#include "timer.h"
#include "ui.h"
#include "utils.h"

U8G2_FOR_ADAFRUIT_GFX u8g2;  // 给 Adafruit_GFX 套一层 U8g2 的“文字引擎”
using namespace esp32;

#define TFT_MOSI 16
#define TFT_SCLK 15
#define TFT_CS 18
#define TFT_DC 17
#define TFT_RST -1

// 屏幕尺寸为 128x160
Adafruit_ST7735 tft(TFT_CS, TFT_DC, TFT_RST);

using namespace esp32::utils;
using namespace esp32::ui;

const int BTN_LEFT = 12;   // 左按钮
const int BTN_RIGHT = 11;  // 右按钮
const int BTN_UP = 10;     // 上按钮

// 颜色宏兼容已由 utils.h 提供

// 应用状态（主屏轮播）
struct AppState {
    // 轮播：当前索引与动画偏移（像素）
    int currentIndex = 0;         // 0: Timer, 1: Web, 2: Game
    float carouselOffset = 0.0f;  // 动画帧间偏移，完成后归零
    int targetIndex = -1;         // 动画结束时要切换到的索引（无动画=-1）

    // 图标资源
    Icon iconTimer;
    Icon iconWeb;
    Icon iconGame;

    // 场景管理
    enum class Scene : uint8_t { Home = 0, Timer = 1, Game = 2 };
    Scene scene = Scene::Home;
    game::Tetris tetris;
    timer::ClockState clock;
};

static UI appUI;
static AppState app;
static bool prevLeft = false;
static bool prevRight = false;
static bool prevUp = false;

// 布局参数
static const int SCREEN_W = 128;
static const int SCREEN_H = 160;
static const int ICON_W = 48;   // 图标宽度
static const int ICON_H = 48;   // 图标高度
static const int SPACING = 72;  // 图标中心间距（略大于宽度，保证边缘留白）
static const int CENTER_X = (SCREEN_W - ICON_W) / 2;  // 中心图标左上角 X
static const int BASE_Y = 40;       // 图标顶端 Y（上方留空间给标题）
static const int LABEL_MARGIN = 12;  // 图标与文字竖向间距

static const int CHAR_W = 14;
static const int CHAR_H = 14;

// 根据状态输出显示列表
static void buildScene(void* ctx, DisplayList& out) {
    AppState* s = (AppState*)ctx;
    if (s->scene == AppState::Scene::Home) {
        // 顶部标题居中 - 支持中文
        const char* title = "主菜单";  // 中文标题
        out.addText(100, SCREEN_W / 2, 8, WHITE, title, true);  // 使用居中

        // 图标与文字
        for (int i = 0; i < 3; ++i) {
            int rel = i - s->currentIndex;  // 相对索引
            int x = CENTER_X + rel * SPACING + (int)(s->carouselOffset);
            if (x + ICON_W < 0 || x > SCREEN_W)
                continue;
            const Icon* ic = nullptr;
            const char* label = "";
            switch (i) {
                case 0:
                    ic = &s->iconTimer;
                    label = "计时器";  // 中文标签
                    break;
                case 1:
                    ic = &s->iconWeb;
                    label = "网页";    // 中文标签
                    break;
                case 2:
                    ic = &s->iconGame;
                    label = "游戏";    // 中文标签
                    break;
            }
            out.addIcon(10 + i, x, BASE_Y, ic);
            // 标签居中显示
            int labelX = x + ICON_W / 2;  // 图标中心点
            int labelY = BASE_Y + ICON_H + LABEL_MARGIN;
            out.addText(200 + i, labelX, labelY, WHITE, label, true);  // 使用居中
        }
    } else if (s->scene == AppState::Scene::Game) {
        // 游戏画面：棋盘居中
        const int cell = 6;
        int boardW = game::COLS * cell;
        int boardH = game::ROWS * cell;
        int originX = (SCREEN_W - boardW) / 2;
        int originY = 16;
        game::buildScene(s->tetris, out, SCREEN_W, SCREEN_H, cell, originX,
                         originY);
    } else if (s->scene == AppState::Scene::Timer) {
        timer::buildScene(s->clock, out, SCREEN_W, SCREEN_H);
    }
}

void setup() {
    // 按钮:内部下拉
    pinMode(BTN_LEFT, INPUT_PULLDOWN);
    pinMode(BTN_RIGHT, INPUT_PULLDOWN);
    pinMode(BTN_UP, INPUT_PULLDOWN);

    // 1. 把硬件 SPI 绑定到你现有的引脚
    SPI.begin(TFT_SCLK, -1 /*MISO 不用*/, TFT_MOSI, TFT_CS);
    SPI.setFrequency(27000000);  // ST7735 通常 27MHz 左右比较稳

    // 2. 初始化屏幕
    tft.initR(INITR_GREENTAB);
    tft.setRotation(0);
    tft.fillScreen(BLACK);
    tft.setCursor(0, 0);
    // ★ 关键：把 u8g2 挂到 tft 上
    u8g2.begin(tft);
    // 连接到 Adafruit_GFX :contentReference[oaicite:2]{index=2}
    u8g2.setFontMode(1);                    // 透明背景（默认也是 1）
    u8g2.setFontDirection(0);               // 正常从左到右
    u8g2.setForegroundColor(WHITE);  // 文字颜色

    // 使用更小的中文字体
    // u8g2_font_wqy12_t_chinese1: 12像素，常用汉字（约2500字）
    // u8g2_font_wqy12_t_chinese2: 12像素，更多汉字（约6000字）
    // u8g2_font_wqy12_t_chinese3: 12像素，完整汉字（约9000字）
    u8g2.setFont(u8g2_font_wqy12_t_chinese3);  // 12像素字体，比 unifont 小

    tft.setTextColor(WHITE);
    tft.setTextSize(1);

    // 初始化系统(读取配置并连接 WiFi)
    init::initSystem(tft);

    // UI 初始化，传入 u8g2 以支持中文
    appUI.begin(&tft, &u8g2);
    // 启用内存帧缓冲，避免闪烁（若内存不足会返回 false）
    appUI.enableBackBuffer(SCREEN_W, SCREEN_H);

    // 加载图标（LittleFS: /icons/*.r565，格式: [w][h][pixels]）
    // 若不存在，将在渲染时以蓝色占位矩形显示
    UI::loadIconFromFS("/icons/timer.r565", app.iconTimer);
    UI::loadIconFromFS("/icons/web.r565", app.iconWeb);
    UI::loadIconFromFS("/icons/game.r565", app.iconGame);

    // 绑定场景构建器
    appUI.setScene(buildScene, &app);
}

void loop() {
    bool leftPressed = digitalRead(BTN_LEFT) == HIGH;  // 按下=HIGH
    bool rightPressed = digitalRead(BTN_RIGHT) == HIGH;
    bool upPressed = digitalRead(BTN_UP) == HIGH;

    if (app.scene == AppState::Scene::Home) {
        // 主页：左右滑动选择，Up 进入游戏
        if (leftPressed && !prevLeft && !appUI.hasActiveTweens()) {
            if (app.currentIndex > 0 && app.targetIndex == -1) {
                app.targetIndex = app.currentIndex - 1;
                app.carouselOffset = 0.0f;
                appUI.addTweenFloat(&app.carouselOffset, (float)SPACING, 300);
            }
        }
        if (rightPressed && !prevRight && !appUI.hasActiveTweens()) {
            if (app.currentIndex < 2 && app.targetIndex == -1) {
                app.targetIndex = app.currentIndex + 1;
                app.carouselOffset = 0.0f;
                appUI.addTweenFloat(&app.carouselOffset, -(float)SPACING, 300);
            }
        }
        // 进入计时器：index==0
        if (upPressed && !prevUp && app.currentIndex == 0) {
            timer::init(app.clock);
            app.scene = AppState::Scene::Timer;
        }
        // 进入游戏：index==2
        if (upPressed && !prevUp && app.currentIndex == 2) {
            game::init(app.tetris);
            app.scene = AppState::Scene::Game;
        }
    } else {
        if (app.scene == AppState::Scene::Game) {
            // 游戏内：左右移动，Up 硬降；GameOver 时 左=返回主页，右=重玩
            if (leftPressed && !prevLeft) {
                if (app.tetris.state == game::State::GameOver) {
                    app.scene = AppState::Scene::Home;
                    app.targetIndex = -1;
                } else {
                    game::moveLeft(app.tetris);
                }
            }
            if (rightPressed && !prevRight) {
                if (app.tetris.state == game::State::GameOver) {
                    game::reset(app.tetris);
                } else {
                    game::moveRight(app.tetris);
                }
            }
            if (upPressed && !prevUp) {
                if (app.tetris.state == game::State::Playing) {
                    game::hardDrop(app.tetris);
                }
            }
            game::update(app.tetris, millis());
        } else if (app.scene == AppState::Scene::Timer) {
            // 计时器：Left 返回主页，Right 重置，Up 增加 lap 标记
            if (leftPressed && !prevLeft) {
                app.scene = AppState::Scene::Home;
                app.targetIndex = -1;
            }
            if (rightPressed && !prevRight) {
                timer::reset(app.clock);
            }
            if (upPressed && !prevUp) {
                timer::addLap(app.clock);
            }
            timer::update(app.clock, millis());
        }
    }

    prevLeft = leftPressed;
    prevRight = rightPressed;
    prevUp = upPressed;

    // 驱动 UI 帧刷新
    appUI.tick(millis());

    // 动画结束：如果没有活动 tween 且存在 targetIndex，则完成索引切换并重置偏移
    if (app.scene == AppState::Scene::Home) {
        if (!appUI.hasActiveTweens() && app.targetIndex != -1) {
            app.currentIndex = app.targetIndex;
            app.targetIndex = -1;
            app.carouselOffset = 0.0f;
        }
    }

    delay(16);  // 简单节流 ~60FPS
}
