from time import sleep
from datetime import datetime
import random

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.layout import Layout
from rich.align import Align
from rich.text import Text
from rich.live import Live

console = Console()

def make_header() -> Panel:
    title = Text("SYSTEM DASHBOARD", style="bold cyan")
    subtitle = Text(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), style="dim")
    return Panel(Align.center(title + "\n" + subtitle), border_style="cyan")

def make_metrics_table(cpu: int, mem: int, qps: int) -> Panel:
    t = Table(show_header=True, header_style="bold magenta", expand=True)
    t.add_column("Metric")
    t.add_column("Value", justify="right")
    t.add_row("CPU", f"{cpu}%")
    t.add_row("Memory", f"{mem}%")
    t.add_row("QPS", str(qps))
    return Panel(t, title="Metrics", border_style="magenta")

def make_status_panel(status: str, logs: list[str]) -> Panel:
    body = "\n".join(logs[-8:]) if logs else "No logs yet."
    text = Text(f"[bold]Status:[/bold] {status}\n\n", style="white")
    text.append(body, style="dim")
    return Panel(text, title="Status / Logs", border_style="green")

def make_footer(msg: str) -> Panel:
    return Panel(Text(msg, style="bold yellow"), border_style="yellow")

def build_layout(cpu: int, mem: int, qps: int, status: str, logs: list[str]) -> Layout:
    layout = Layout()
    layout.split_column(
        Layout(make_header(), name="header", size=5),
        Layout(name="body", ratio=1),
        Layout(make_footer("Press Ctrl+C to exit"), name="footer", size=3),
    )
    layout["body"].split_row(
        Layout(make_metrics_table(cpu, mem, qps), name="left", ratio=1),
        Layout(make_status_panel(status, logs), name="right", ratio=2),
    )
    return layout

def main():
    logs = []
    status = "OK"
    with Live(console=console, refresh_per_second=8, screen=True):
        while True:
            cpu = random.randint(1, 100)
            mem = random.randint(1, 100)
            qps = random.randint(50, 5000)

            if cpu > 85 or mem > 90:
                status = "WARN"
                logs.append(f"{datetime.now().strftime('%H:%M:%S')} - High load detected")
            else:
                status = "OK"
                if random.random() < 0.2:
                    logs.append(f"{datetime.now().strftime('%H:%M:%S')} - Heartbeat")

            layout = build_layout(cpu, mem, qps, status, logs)
            Live.get_renderable = lambda self: layout  # 小技巧：避免重复创建 Live
            sleep(0.15)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        console.print("\nBye!", style="bold red")
