#include "eduwin.h"

#define CANVAS_W  800
#define CANVAS_H  600
#define MAX_BULLETS 50
#define MAX_ENEMIES 30
#define PLAYER_SPEED 5
#define BULLET_SPEED 10
#define ENEMY_BASE_SPEED 2
#define START_HEALTH 100
#define FIRE_COOLDOWN 10

static HWND g_canvas;
static Sprite *g_player;
static Sprite *g_bullet_tpl;
static Sprite *g_enemy_tpl;
static Sprite *g_bullets[MAX_BULLETS];
static Sprite *g_enemies[MAX_ENEMIES];
static int g_score;
static int g_health;
static int g_fire_cd;
static int g_frame;

static void spawn_enemy(void)
{
    int idx = -1;
    for (int i = 0; i < MAX_ENEMIES; i++)
    {
        if (!g_enemies[i]) { idx = i; break; }
    }
    if (idx < 0) return;

    Sprite *e = sprite_clone(g_enemy_tpl);
    if (!e) return;

    float scale = 0.5f + (float)(rand() % 50) / 100.0f;
    sprite_set_scale(e, scale, scale);
    sprite_set_pos(e, (float)(rand() % (CANVAS_W - 40)), -60.0f);

    /* 随机经典web颜色 */
    static const int colors[][3] = {
        {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0},
        {128, 0, 128}, {255, 165, 0}, {0, 255, 255}, {255, 192, 203}
    };
    int ci = rand() % (sizeof(colors) / sizeof(colors[0]));
    sprite_set_color(e, colors[ci][0], colors[ci][1], colors[ci][2], 120);

    g_enemies[idx] = e;
}

static void fire_bullet(void)
{
    int idx = -1;
    for (int i = 0; i < MAX_BULLETS; i++)
    {
        if (!g_bullets[i]) { idx = i; break; }
    }
    if (idx < 0) return;

    Sprite *b = sprite_clone(g_bullet_tpl);
    if (!b) return;

    float px = sprite_get_x(g_player) + sprite_get_w(g_player) * sprite_get_sx(g_player) / 2.0f;
    float py = sprite_get_y(g_player);
    sprite_set_pos(b, px, py);

    g_bullets[idx] = b;
    play_sound(L"shoot.mp3");
}

static void game_loop(void *data)
{
    g_frame++;

    /* ── Input ── */
    float dx = 0, dy = 0;
    if (canvas_is_key_down(g_canvas, 'W') || canvas_is_key_down(g_canvas, VK_UP))    dy -= PLAYER_SPEED;
    if (canvas_is_key_down(g_canvas, 'S') || canvas_is_key_down(g_canvas, VK_DOWN))  dy += PLAYER_SPEED;
    if (canvas_is_key_down(g_canvas, 'A') || canvas_is_key_down(g_canvas, VK_LEFT))  dx -= PLAYER_SPEED;
    if (canvas_is_key_down(g_canvas, 'D') || canvas_is_key_down(g_canvas, VK_RIGHT)) dx += PLAYER_SPEED;

    if (dx != 0 || dy != 0)
        sprite_move(g_player, dx, dy);

    /* clamp player */
    {
        float px = sprite_get_x(g_player);
        float py = sprite_get_y(g_player);
        float pw = sprite_get_w(g_player) * sprite_get_sx(g_player);
        float ph = sprite_get_h(g_player) * sprite_get_sy(g_player);
        if (px < 0) px = 0;
        if (px + pw > (float)CANVAS_W) px = (float)CANVAS_W - pw;
        if (py < 0) py = 0;
        if (py + ph > (float)CANVAS_H) py = (float)CANVAS_H - ph;
        sprite_set_pos(g_player, px, py);
    }

    /* fire */
    if (g_fire_cd > 0) g_fire_cd--;
    if (canvas_is_key_down(g_canvas, 'J') && g_fire_cd == 0)
    {
        fire_bullet();
        g_fire_cd = FIRE_COOLDOWN;
    }

    /* ── Update bullets ── */
    for (int i = 0; i < MAX_BULLETS; i++)
    {
        if (!g_bullets[i]) continue;
        sprite_move(g_bullets[i], 0, -(float)BULLET_SPEED);
        if (sprite_get_y(g_bullets[i]) < -30)
        {
            sprite_destroy(g_bullets[i]);
            g_bullets[i] = NULL;
        }
    }

    /* ── Spawn enemies ── */
    if (g_frame % 30 == 0)
        spawn_enemy();

    /* ── Update enemies ── */
    float speed_up = 1.0f + (float)(g_frame / 1800) * 0.3f;
    for (int i = 0; i < MAX_ENEMIES; i++)
    {
        if (!g_enemies[i]) continue;
        sprite_move(g_enemies[i], 0, (float)ENEMY_BASE_SPEED * speed_up);
        if (sprite_get_y(g_enemies[i]) > (float)CANVAS_H + 60)
        {
            sprite_destroy(g_enemies[i]);
            g_enemies[i] = NULL;
        }
    }

    /* ── Bullet-Enemy collisions ── */
    for (int i = 0; i < MAX_BULLETS; i++)
    {
        if (!g_bullets[i]) continue;
        for (int j = 0; j < MAX_ENEMIES; j++)
        {
            if (!g_enemies[j]) continue;
            if (sprite_collide(g_bullets[i], g_enemies[j]))
            {
                g_score += 10;
                sprite_destroy(g_bullets[i]); g_bullets[i] = NULL;
                sprite_destroy(g_enemies[j]); g_enemies[j] = NULL;
                break;
            }
        }
    }

    /* ── Player-Enemy collisions ── */
    for (int i = 0; i < MAX_ENEMIES; i++)
    {
        if (!g_enemies[i]) continue;
        if (sprite_collide(g_player, g_enemies[i]))
        {
            g_health -= 2;
            sprite_destroy(g_enemies[i]);
            g_enemies[i] = NULL;
            if (g_health < 0) g_health = 0;
        }
    }

    /* ── Draw ── */
    canvas_clear(g_canvas, 20, 20, 40, 255);

    sprite_draw(g_canvas, g_player);

    for (int i = 0; i < MAX_BULLETS; i++)
        if (g_bullets[i]) sprite_draw(g_canvas, g_bullets[i]);

    for (int i = 0; i < MAX_ENEMIES; i++)
        if (g_enemies[i]) sprite_draw(g_canvas, g_enemies[i]);

    /* HUD */
    WCHAR buf[64];
    str_format(buf, 64, L"得分: %d", g_score);
    canvas_draw_text(g_canvas, buf, 10, 10, 255, 255, 255, 255, 14);

    str_format(buf, 64, L"生命: %d", g_health);
    canvas_draw_text(g_canvas, buf, CANVAS_W - 140, 10, 255, 80, 80, 255, 14);

    canvas_draw_text(g_canvas, L"WASD移动  J子弹", CANVAS_W / 2 - 70, 10, 128, 128, 128, 255, 12);

    if (g_health <= 0)
    {
        canvas_draw_text(g_canvas, L"游戏结束!", CANVAS_W / 2 - 100, CANVAS_H / 2 - 20, 255, 30, 30, 255, 44);
        canvas_stop_timer(g_canvas);
    }
}

int main(void)
{
    init_app();

    HWND win = create_window(L"飞机小游戏", CANVAS_W + 16, CANVAS_H + 39);
    if (!win) return 1;

    g_canvas = create_canvas(win, 0, 0, CANVAS_W, CANVAS_H);
    if (!g_canvas) return 1;

    /* Load assets */
    g_player = sprite_create_from_file(L"flight.png");
    if (g_player)
    {
        sprite_set_pos(g_player, (float)(CANVAS_W / 2 - 25), (float)(CANVAS_H - 100));
        sprite_set_rotation(g_player, 180.0f);
    }

    g_bullet_tpl = sprite_create_from_file(L"bullet.png");
    g_enemy_tpl = sprite_create_from_file(L"flight.png");

    if (!g_player || !g_bullet_tpl || !g_enemy_tpl)
    {
        alert(L"错误", L"加载图片失败，请确保 flight.png / bullet.png 存在");
        return 1;
    }

    /* Init state */
    g_score = 0;
    g_health = START_HEALTH;
    g_fire_cd = 0;
    g_frame = 0;
    for (int i = 0; i < MAX_BULLETS; i++) g_bullets[i] = NULL;
    for (int i = 0; i < MAX_ENEMIES;  i++) g_enemies[i] = NULL;

    play_sound_loop(L"bgm.mp3");

    canvas_start_timer(g_canvas, 60, game_loop, NULL);

    show_window(win);
    run_app();
    return 0;
}
