// SPDX-License-Identifier: LCL-1.0
// Copyright (c) 2026 Markus Maiwald
// Stewardship: Self Sovereign Society Foundation
//
// This file is part of the Nexus Commonwealth.
// See legal/LICENSE_COMMONWEALTH.md for license terms.

//! Rumpk HAL: UI Layer (The Persona)
//!
//! Bridges microui (C) with the Zig HAL and Framebuffer.
//! Handles GUI rendering, layout management, and the boot animation loop.
//!
//! SAFETY: Integrates with a C-based GUI library via @cImport.
//! Global context is initialized by `init()` before use in the UI fiber.

const std = @import("std");
const fb = @import("framebuffer.zig");

// GPU Driver (extern)
extern fn virtio_gpu_flush() void;
pub const c = @cImport({
    @cInclude("microui.h");
});

// --- STATIC MEMORY ---
// SAFETY(UI): Context is initialized by `c.mu_init(&ctx)` in `init()`.
var ctx: c.mu_Context = undefined;

// --- FONT (The "8-bit" classic) ---
// Minimal placeholder font (0-127 ascii) - 1KB
const font_bitmap: [128][8]u8 = [_][8]u8{[_]u8{0xFF} ** 8} ** 128; // Blocks for now

// --- CALL BACKS ---
fn text_width_cb(font: ?*anyopaque, str: [*c]const u8, len: c_int) callconv(.c) c_int {
    _ = font;
    // assuming 8x8 monospaced

    // If len is -1, treat as null terminated
    var l = len;
    if (l == -1 and str != null) {
        l = 0;
        var s = str;
        while (s[0] != 0) {
            l += 1;
            s += 1;
        }
    }
    return l * 8;
}

fn text_height_cb(font: ?*anyopaque) callconv(.c) c_int {
    _ = font;
    return 8;
}

// --- THE RENDERER (The Paint Brush) ---
pub fn render() void {
    var cmd: [*c]c.mu_Command = null;

    // Iterate over microui command list
    // Note: mu_next_command takes pointers
    while (c.mu_next_command(&ctx, &cmd) != 0) {
        switch (cmd.*.type) {
            c.MU_COMMAND_TEXT => {
                // draw_text(cmd.text.str, cmd.text.pos, cmd.text.color);
                // For now, ignore text drawing to avoid font complexity in step 1
            },
            c.MU_COMMAND_RECT => {
                draw_rect(cmd.*.rect.rect, cmd.*.rect.color);
            },
            c.MU_COMMAND_ICON => {
                // TODO: Draw simple icons (close button X)
                draw_rect(cmd.*.icon.rect, cmd.*.icon.color); // Placeholder
            },
            c.MU_COMMAND_CLIP => {
                // fb.set_clip(cmd.clip.rect);
                // Adaptation needed for C to Zig struct
                fb.set_clip(.{
                    .x = cmd.*.clip.rect.x,
                    .y = cmd.*.clip.rect.y,
                    .w = cmd.*.clip.rect.w,
                    .h = cmd.*.clip.rect.h,
                });
            },
            else => {},
        }
    }

    // PUSH TO HOST (The Retina)
    virtio_gpu_flush();
}

// --- HELPER: Draw Rect ---
fn draw_rect(r: c.mu_Rect, color: c.mu_Color) void {
    // Convert microui Color to ARGB
    const argb = (@as(u32, 255) << 24) |
        (@as(u32, color.r) << 16) |
        (@as(u32, color.g) << 8) |
        @as(u32, color.b);

    // Plot to L0 Framebuffer
    fb.fill_rect(r.x, r.y, r.w, r.h, argb);
}

// --- INITIALIZATION ---
pub fn init() void {
    c.mu_init(&ctx);
    // Hook up text width callback (Required by microui)
    ctx.text_width = text_width_cb;
    ctx.text_height = text_height_cb;
}

// --- KERNEL IMPORTS ---
extern fn fiber_yield() void;

extern fn fiber_sleep(ms: i32) void;
extern fn matrix_init() void;
extern fn matrix_update() bool;

// --- THE UI LOOP (Fiber Entry) ---
export fn ui_fiber_entry() void {
    init();
    matrix_init();

    var matrix_alive: bool = true;

    while (true) {
        if (matrix_alive) {
            // --- THE GREETING (High Compute) ---
            matrix_alive = matrix_update();

            // Push the Rain to the GPU
            virtio_gpu_flush();

            // 33ms Frame Time (~30 FPS)
            fiber_sleep(33);
        } else {
            // --- THE HUD / VOID (Low Compute) ---
            // 1. Begin Frame
            c.mu_begin(&ctx);

            // 2. Define Layout (The Logic)
            if (c.mu_begin_window(&ctx, "Nexus HUD", c.mu_rect(10, 10, 300, 200)) != 0) {
                c.mu_layout_row(&ctx, 1, &[_]i32{-1}, 0);
                c.mu_label(&ctx, "System Status: ONLINE");

                c.mu_layout_row(&ctx, 2, &[_]i32{ 80, -1 }, 0);
                c.mu_label(&ctx, "CPU:");
                c.mu_draw_rect(&ctx, c.mu_rect(100, 50, 150, 20), c.mu_color(0, 255, 0, 255)); // Mock bar

                if (c.mu_button(&ctx, "REBOOT") != 0) {
                    // hal_reboot();
                }

                c.mu_end_window(&ctx);
            }

            // 3. End Frame & Paint
            c.mu_end(&ctx);
            render();

            // 1s Sleep - No need to render UI every 30ms if static
            fiber_sleep(1000);
        }
    }
}
