import subprocess
import sys
import time
import datetime

# ----------------------------
# AUTO-IMPORT + AUTO-INSTALLER
# ----------------------------

def try_import(module, pip_name=None):
    pip_name = pip_name or module
    try:
        return __import__(module)
    except ImportError:
        print(f"[ds] Missing module: {module}")
        choice = input(f"Install '{pip_name}' now? (y/n): ").strip().lower()
        if choice == "y":
            try:
                subprocess.check_call([sys.executable, "-m", "pip", "install", pip_name])
                return __import__(module)
            except Exception as e:
                print(f"[ds] Installation failed: {e}")
                return None
        return None


# psutil
psutil = try_import("psutil")

# Pillow
PIL = try_import("PIL", "Pillow")
Image = ImageDraw = ImageFont = None
if PIL:
    from PIL import Image, ImageDraw, ImageFont

# luma.oled
luma_ok = True
try:
    from luma.core.interface.serial import i2c
    from luma.oled.device import ssd1306
except Exception:
    print("[ds] OLED driver not available on this system.")
    print("[ds] Display output disabled.")
    luma_ok = False


# ----------------------------
# OLED INITIALIZATION
# ----------------------------

oled = None
WIDTH = 128
HEIGHT = 64

if luma_ok and PIL:
    try:
        serial = i2c(port=1, address=0x3C)
        oled = ssd1306(serial)
    except Exception as e:
        print(f"[ds] Could not initialize OLED: {e}")
        oled = None


# ----------------------------
# OLED DISPLAY HELPERS
# ----------------------------

def oled_available():
    return oled is not None and PIL is not None


def _display(text: str):
    if not oled_available():
        print("[ds] OLED unavailable: displaying in CLI:\n" + text)
        return

    lines = text.split("\n")
    image = Image.new("1", (WIDTH, HEIGHT))
    draw = ImageDraw.Draw(image)

    y = 0
    for line in lines:
        draw.text((0, y), line, font=ImageFont.load_default(), fill=255)
        y += 10

    oled.display(image)


def _scroll_text(text: str, seconds: int):
    if not oled_available():
        print("[ds] OLED unavailable (scroll simulated):\n" + text)
        time.sleep(seconds)
        return

    image = Image.new("1", (WIDTH, 300))
    draw = ImageDraw.Draw(image)
    font = ImageFont.load_default()

    y = 0
    for line in text.split("\n"):
        draw.text((0, y), line, font=font, fill=255)
        y += 10

    total_height = y
    start = time.time()

    while time.time() - start < seconds:
        for offset in range(0, max(1, total_height - HEIGHT + 1)):
            frame = image.crop((0, offset, WIDTH, offset + HEIGHT))
            oled.display(frame)
            time.sleep(0.05)
            if time.time() - start >= seconds:
                return


# ----------------------------
# COMMANDS
# ----------------------------

def command_idle():
    if psutil is None:
        print("[ds] psutil not installed; cannot read temperatures.")
        return

    while True:
        temps = psutil.sensors_temperatures()
        temp = 0.0
        if temps:
            for name in temps:
                if temps[name]:
                    temp = temps[name][0].current
                    break

        mem = psutil.virtual_memory()
        txt = f"CPU Temp: {temp:.1f}C\nMemory: {mem.percent}%"
        _display(txt)
        time.sleep(1)


def command_write(text: str, duration: int = None):
    if duration is None:
        _display(text)
    else:
        _scroll_text(text, duration)


def command_debug():
    if psutil is None:
        print("[ds] psutil missing; cannot perform debug.")
        return

    cpu = psutil.cpu_percent(interval=1)
    mem = psutil.virtual_memory()
    disk = psutil.disk_usage("/")
    boot = datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")

    sections = [
        f"CPU: {cpu}%",
        f"Memory: {mem.percent}%",
        f"Disk: {disk.percent}% used",
        f"Boot: {boot}"
    ]

    if cpu > 90:
        print("[MAJOR] CPU usage too high")
    if mem.percent > 90:
        print("[MAJOR] Memory usage too high")
    if disk.percent > 90:
        print("[MAJOR] Disk almost full")

    for sec in sections:
        _scroll_text(sec, 3)


# ----------------------------
# ENTRY POINT (FINAL FIX)
# ----------------------------

def run():
    args = sys.argv[2:]  # babicli ds <args>

    if len(args) == 0:
        print("Usage: ds <idle|write|debug>")
        return

    cmd = args[0]

    if cmd == "idle":
        command_idle()

    elif cmd == "write":
        if len(args) < 2:
            print("Usage: ds write \"text\" [seconds]")
            return

        text = args[1]
        if len(args) == 3:
            command_write(text, int(args[2]))
        else:
            command_write(text)

    elif cmd == "debug":
        command_debug()

    else:
        print(f"Unknown command: {cmd}")
