#include "pingpong_game.h"
#include "pingpong_ball.h"

#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/input_event_key.hpp>
#include <godot_cpp/classes/input.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
#include <godot_cpp/classes/viewport.hpp>

using namespace godot;

// ═══════════════════════════════════════════════════════
// 视觉颜色常量 — 以后替换素材时删除本段
// ═══════════════════════════════════════════════════════
static const Color FIELD_BG_COLOR = Color(0.06f, 0.10f, 0.18f);
static const Color FIELD_BORDER_COLOR = Color(1.0f, 1.0f, 1.0f, 0.25f);
static const Color FIELD_CENTER_LINE_COLOR = Color(1.0f, 1.0f, 1.0f, 0.12f);
static const Color FIELD_CIRCLE_COLOR = Color(1.0f, 1.0f, 1.0f, 0.06f);

void PingPongGame::_bind_methods() {
    // 属性
    ClassDB::bind_method(D_METHOD("get_left_score"), &PingPongGame::get_left_score);
    ClassDB::bind_method(D_METHOD("set_left_score", "value"), &PingPongGame::set_left_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "left_score"), "set_left_score", "get_left_score");

    ClassDB::bind_method(D_METHOD("get_right_score"), &PingPongGame::get_right_score);
    ClassDB::bind_method(D_METHOD("set_right_score", "value"), &PingPongGame::set_right_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "right_score"), "set_right_score", "get_right_score");

    ClassDB::bind_method(D_METHOD("get_max_score"), &PingPongGame::get_max_score);
    ClassDB::bind_method(D_METHOD("set_max_score", "value"), &PingPongGame::set_max_score);
    ClassDB::add_property("PingPongGame", PropertyInfo(Variant::INT, "max_score"), "set_max_score", "get_max_score");

    // 方法
    ClassDB::bind_method(D_METHOD("reset_game"), &PingPongGame::reset_game);
    ClassDB::bind_method(D_METHOD("start_countdown"), &PingPongGame::start_countdown);
    ClassDB::bind_method(D_METHOD("_on_ball_scored", "which"), &PingPongGame::_on_ball_scored);

    // 信号
    ADD_SIGNAL(MethodInfo("game_over", PropertyInfo(Variant::INT, "winner")));
}

PingPongGame::PingPongGame() {
    left_score = 0;
    right_score = 0;
    max_score = 5;
    state = WAITING;
    state_timer = 0.0f;
    countdown_number = COUNTDOWN_START;
}

PingPongGame::~PingPongGame() {
}

void PingPongGame::_ready() {
    // 查找子节点
    left_score_label = Object::cast_to<Label>(get_node_or_null("UI/LeftScore"));
    right_score_label = Object::cast_to<Label>(get_node_or_null("UI/RightScore"));
    message_label = Object::cast_to<Label>(get_node_or_null("UI/Message"));
    ball = Object::cast_to<PingPongBall>(get_node_or_null("Ball"));

    // 连接球的得分信号
    if (ball) {
        ball->connect("scored", Callable(this, "_on_ball_scored"));
    }

    update_score_display();
    show_message("按空格键开始");
}

void PingPongGame::_process(double delta) {
    queue_redraw();

    switch (state) {
    case WAITING:
        // 等待用户按空格（在 _input 中处理）
        break;

    case COUNTDOWN: {
        state_timer -= (float)delta;
        if (state_timer <= 0.0f) {
            countdown_number--;
            if (countdown_number > 0) {
                show_message(String::num_int64(countdown_number));
                state_timer = COUNTDOWN_INTERVAL;
            } else if (countdown_number == 0) {
                show_message("GO!");
                state_timer = COUNTDOWN_INTERVAL * 0.5f;
            } else {
                // 倒计时结束，开始游戏
                show_message("");
                set_state(PLAYING);
                if (ball) {
                    ball->set_active(true);
                    ball->reset();
                }
            }
        }
        break;
    }

    case PLAYING:
        // 正常游戏进行中，球和球拍自行运作
        break;

    case SCORED: {
        state_timer -= (float)delta;
        if (state_timer <= 0.0f) {
            show_message("");
            set_state(PLAYING);
            if (ball) {
                ball->set_active(true);
                ball->reset();
            }
        }
        break;
    }

    case GAME_OVER:
        // 等待用户按空格重置
        break;
    }
}

void PingPongGame::_input(const Ref<InputEvent> &event) {
    // 只有空格键按下事件
    const InputEventKey *key_event = Object::cast_to<InputEventKey>(event.ptr());
    if (!key_event || !key_event->is_pressed()) {
        return;
    }
    if (key_event->get_keycode() != KEY_SPACE) {
        return;
    }

    if (state == WAITING) {
        start_countdown();
    } else if (state == GAME_OVER) {
        reset_game();
        start_countdown();
    }
}

// ═══════════════════════════════════════════════════════
// 视觉层 — 场地绘制（几何体占位）
// 替换方法：删除本方法 → 用 TileMap 或 Sprite2D 铺背景
// ═══════════════════════════════════════════════════════
void PingPongGame::_draw() {
    Viewport *viewport = get_viewport();
    if (!viewport) return;

    Vector2 size = viewport->get_visible_rect().size;
    float w = size.x;
    float h = size.y;
    float cx = w / 2.0f;
    float cy = h / 2.0f;

    // ── 场地背景 ──
    draw_rect(Rect2(Vector2(0, 0), size), FIELD_BG_COLOR);

    // ── 场地边界线 ──
    float l = FIELD_INSET;
    float r = w - FIELD_INSET;
    float t = FIELD_INSET;
    float b = h - FIELD_INSET;
    draw_line(Vector2(l, t), Vector2(r, t), FIELD_BORDER_COLOR, 2.0f);
    draw_line(Vector2(l, b), Vector2(r, b), FIELD_BORDER_COLOR, 2.0f);

    // ── 虚线中线 ──
    float dash_total = CENTER_LINE_DASH + CENTER_LINE_GAP;
    for (float y = t; y < b; y += dash_total) {
        float dash_end = MIN(y + CENTER_LINE_DASH, b);
        draw_line(Vector2(cx, y), Vector2(cx, dash_end), FIELD_CENTER_LINE_COLOR, 1.5f);
    }

    // ── 中央发球圈 ──
    draw_arc(Vector2(cx, cy), 80.0f, 0.0f, Math_PI * 2.0f, 32, FIELD_CIRCLE_COLOR, 1.5f);
}

void PingPongGame::_on_ball_scored(int which) {
    if (which == 0) {
        right_score++;
    } else {
        left_score++;
    }
    update_score_display();

    if (ball) {
        ball->set_active(false);
    }

    // 检查是否有人获胜
    if (left_score >= max_score) {
        show_message("玩家获胜！\n按空格键重新开始");
        set_state(GAME_OVER);
        emit_signal("game_over", 0);
    } else if (right_score >= max_score) {
        show_message("AI 获胜！\n按空格键重新开始");
        set_state(GAME_OVER);
        emit_signal("game_over", 1);
    } else {
        show_message("得分！");
        set_state(SCORED);
    }
}

void PingPongGame::reset_game() {
    left_score = 0;
    right_score = 0;
    update_score_display();
    if (ball) {
        ball->set_active(false);
        ball->reset();
    }
}

void PingPongGame::start_countdown() {
    countdown_number = COUNTDOWN_START;
    state_timer = COUNTDOWN_INTERVAL;
    set_state(COUNTDOWN);
    show_message(String::num_int64(countdown_number));
}

void PingPongGame::set_state(GameState p_state) {
    state = p_state;
    state_timer = 0.0f;

    if (p_state == SCORED) {
        state_timer = SCORED_PAUSE;
    }
}

void PingPongGame::show_message(const String &p_text) {
    if (message_label) {
        message_label->set_text(p_text);
        message_label->set_visible(!p_text.is_empty());
    }
}

void PingPongGame::update_score_display() {
    if (left_score_label) {
        left_score_label->set_text(String::num_int64(left_score));
    }
    if (right_score_label) {
        right_score_label->set_text(String::num_int64(right_score));
    }
}

void PingPongGame::set_left_score(int p_score) {
    left_score = p_score;
    update_score_display();
}

int PingPongGame::get_left_score() const {
    return left_score;
}

void PingPongGame::set_right_score(int p_score) {
    right_score = p_score;
    update_score_display();
}

int PingPongGame::get_right_score() const {
    return right_score;
}

void PingPongGame::set_max_score(int p_score) {
    max_score = p_score;
}

int PingPongGame::get_max_score() const {
    return max_score;
}
