#include "ui/ui_piano.h"

#define PIANO_BLACK_W     11.0f
#define PIANO_BLACK_H_PCT 0.6f

B32 piano_is_black_key(S32 note) {
    S32 n = note % 12;
    return n == 1 || n == 3 || n == 6 || n == 8 || n == 10;
}

// Velocity-based color: blue (vel 0) → green (mid) → red (vel 127)
Clay_Color piano_velocity_color(S32 velocity) {
    F32 t = (F32)velocity / 127.0f;
    F32 r, g, b;
    if (t < 0.5f) {
        F32 s = t * 2.0f;
        r = 40.0f  + s * (76.0f  - 40.0f);
        g = 120.0f + s * (175.0f - 120.0f);
        b = 220.0f + s * (80.0f  - 220.0f);
    } else {
        F32 s = (t - 0.5f) * 2.0f;
        r = 76.0f  + s * (220.0f - 76.0f);
        g = 175.0f + s * (50.0f  - 175.0f);
        b = 80.0f  + s * (40.0f  - 80.0f);
    }
    return (Clay_Color){r, g, b, 255};
}

void ui_piano(UI_PianoState *state, MidiEngine *midi, F32 avail_w, F32 avail_h) {
    Clay_ElementId piano_id = CLAY_ID("PianoContainer");
    CLAY(piano_id,
        .layout = {
            .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
            .layoutDirection = CLAY_LEFT_TO_RIGHT,
        }
    ) {
        // Compute black key size proportional to white keys
        F32 black_key_h = avail_h * PIANO_BLACK_H_PCT;
        if (black_key_h < uis(20)) black_key_h = uis(20);

        F32 white_key_w = avail_w / 52.0f;
        F32 black_key_w = white_key_w * 0.6f;
        if (black_key_w < uis(8)) black_key_w = uis(8);

        // White keys (grow to fill width and height)
        for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
            if (piano_is_black_key(note)) continue;

            B32 midi_held = midi_is_note_held(midi, note);
            B32 mouse_held = state->mouse_note == note;
            Clay_Color bg;
            if (midi_held) {
                bg = piano_velocity_color(midi_get_note_velocity(midi, note));
            } else if (mouse_held) {
                bg = g_theme.accent;
            } else {
                bg = (Clay_Color){240, 240, 240, 255};
            }

            CLAY(CLAY_IDI("PKey", note),
                .layout = {
                    .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() },
                },
                .backgroundColor = bg,
                .border = { .color = {190, 190, 190, 255}, .width = { .right = 1 } },
            ) {}
        }

        // Black keys (floating, attached to left white key)
        for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
            if (!piano_is_black_key(note)) continue;

            Clay_ElementId parent_wkey = CLAY_IDI("PKey", note - 1);
            B32 midi_held = midi_is_note_held(midi, note);
            B32 mouse_held = state->mouse_note == note;
            Clay_Color bg;
            if (midi_held) {
                bg = piano_velocity_color(midi_get_note_velocity(midi, note));
            } else if (mouse_held) {
                bg = g_theme.accent;
            } else {
                bg = (Clay_Color){25, 25, 30, 255};
            }

            CLAY(CLAY_IDI("PKey", note),
                .layout = {
                    .sizing = {
                        .width = CLAY_SIZING_FIXED(black_key_w),
                        .height = CLAY_SIZING_FIXED(black_key_h),
                    },
                },
                .backgroundColor = bg,
                .cornerRadius = { .topLeft = 0, .topRight = 0, .bottomLeft = uis(2), .bottomRight = uis(2) },
                .floating = {
                    .parentId = parent_wkey.id,
                    .zIndex = 100,
                    .attachPoints = {
                        .element = CLAY_ATTACH_POINT_CENTER_TOP,
                        .parent = CLAY_ATTACH_POINT_RIGHT_TOP,
                    },
                    .attachTo = CLAY_ATTACH_TO_ELEMENT_WITH_ID,
                },
            ) {}
        }
    }
}

void ui_piano_update_input(UI_PianoState *state) {
    PlatformInput input = g_wstate.input;

    if (!input.mouse_down) {
        state->mouse_note = -1;
        return;
    }

    // Find hovered piano key — check black keys first (they're on top)
    S32 hovered_note = -1;
    for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
        if (piano_is_black_key(note) && Clay_PointerOver(CLAY_IDI("PKey", note))) {
            hovered_note = note;
            break;
        }
    }
    if (hovered_note == -1) {
        for (S32 note = PIANO_FIRST_NOTE; note <= PIANO_LAST_NOTE; note++) {
            if (!piano_is_black_key(note) && Clay_PointerOver(CLAY_IDI("PKey", note))) {
                hovered_note = note;
                break;
            }
        }
    }

    if (hovered_note != -1) {
        state->mouse_note = hovered_note;
    }
}
