import asyncio
import json
import os
import time
import cv2
from fastapi import FastAPI, WebSocket
from fastapi.responses import FileResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles

# ---------------- CONFIG ----------------
CAPTURE_EXE = "/home/pi/acc_module/AI0/main"
SAMPLE_QUEUE_MAX = 8000
CAMERA_INDEX = 0
# ----------------------------------------

app = FastAPI(title="玻璃幕墙结构胶检测系统")
app.mount("/static", StaticFiles(directory="static"), name="static")

sample_queue: asyncio.Queue = asyncio.Queue(maxsize=SAMPLE_QUEUE_MAX)
capture_proc = None

# -------- index page --------
@app.get("/")
def index():
    return FileResponse("static/index.html")

# -------- capture subprocess --------
async def start_capture_live():
    global capture_proc
    if capture_proc and capture_proc.returncode is None:
        return  # already running

    capture_proc = await asyncio.create_subprocess_exec(
        CAPTURE_EXE,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )

    async def reader():
        while True:
            line = await capture_proc.stdout.readline()
            if not line:
                break
            line = line.decode().strip()
            if not line:
                continue
            try:
                parts = [float(p) for p in line.split(",")]
                sample = {"t": parts[0], "volt": parts[1], "accel_g": parts[2], "accel_mps2": parts[3]}
                await sample_queue.put(sample)
            except Exception as e:
                print("parse error:", e, "line:", line)

    asyncio.create_task(reader())

@app.post("/start_capture")
async def start_capture():
    await start_capture_live()
    return {"status": "started"}

@app.post("/stop_capture")
async def stop_capture():
    global capture_proc
    if capture_proc and capture_proc.returncode is None:
        capture_proc.terminate()
        await capture_proc.wait()
        capture_proc = None
        return {"status": "stopped"}
    return {"status": "not running"}

# -------- sample websocket --------
@app.websocket("/ws")
async def websocket_samples(websocket: WebSocket):
    await websocket.accept()
    try:
        while True:
            sample = await sample_queue.get()
            await websocket.send_text(json.dumps(sample, ensure_ascii=False))
    except Exception:
        pass

# -------- camera stream --------
def gen_frames():
    cap = cv2.VideoCapture(CAMERA_INDEX)
    if not cap.isOpened():
        print("[camera] cannot open index", CAMERA_INDEX)
        while True:
            time.sleep(0.5)
            yield b''
    try:
        while True:
            success, frame = cap.read()
            if not success:
                time.sleep(0.05)
                continue
            ret, buf = cv2.imencode('.jpg', frame)
            if not ret:
                continue
            frame_bytes = buf.tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
    finally:
        cap.release()

@app.get("/video_feed")
def video_feed():
    return StreamingResponse(gen_frames(), media_type='multipart/x-mixed-replace; boundary=frame')

# -------- startup --------
@app.on_event("startup")
async def on_startup():
    print("Backend started. Ready to capture data and stream video.")
