import base64
import io
import json
import time
from minio import Minio
import redis
import os

DEFAULT_STATE = {
    "text": {
        "showing": False,
        "title": "Wassup"
    },
    "image_popup": {
        "showing": False,
        "image_url": "",
        "caption": ""
    },
    "data_cards": [],
    "settings": {
        "background_url": ""
    }
}

MINIO_CLIENT = Minio(
    "content2.reversed.dev",
    access_key="tv-control",
    secret_key="0gEjOlnVAECrqJx5Nd77y7Hhouc5faVf0WttjcRH",
    secure=True,
)
BUCKET = "tv-control"
r = redis.Redis(host='194.15.36.205',username="default", port=12004, db=12, password=os.getenv("REDIS"))

def _read_state():
    state_json = r.get("tv-control-state")
    if state_json:
        try:
            return json.loads(state_json)
        except json.JSONDecodeError:
            return dict(DEFAULT_STATE)
    else:
        return dict(DEFAULT_STATE)

def _write_state(state):
    r.set("tv-control-state", json.dumps(state))

def main(args):
    route = args.get("route")

    body = args.get("body")
    body = json.loads(body) if body else {}

    if route.startswith("push"):
        if route == "push_text":
            current = _read_state()
            current["text"]["title"] = body.get("title", "")
            current["text"]["showing"] = True
            _write_state(current)
            return {"status": "success"}
        elif route == "push_dismiss_text":
            current = _read_state()
            current["text"]["showing"] = False
            _write_state(current)
            return {"status": "success"}
        elif route == "push_image":
            image_b64 = body.get("image_b64", "")
            caption = body.get("caption", "")
            image_bytes = base64.b64decode(image_b64)
            file_name = f"tv-image-{int(time.time() * 1000)}.jpg"
            MINIO_CLIENT.put_object(
                BUCKET, file_name, io.BytesIO(image_bytes), len(image_bytes), content_type="image/jpeg"
            )
            public_url = f"https://content2.reversed.dev/{BUCKET}/{file_name}"
            current = _read_state()
            current["image_popup"]["image_url"] = public_url
            current["image_popup"]["caption"] = caption
            current["image_popup"]["showing"] = True
            _write_state(current)
            return {"status": "success", "image_url": public_url}
        elif route == "push_dismiss_image":
            current = _read_state()
            current["image_popup"]["showing"] = False
            _write_state(current)
            return {"status": "success"}
        elif route == "push_data_card":
            # Upsert a data card by id
            card = body.get("card")
            if not card or not card.get("id"):
                return {"status": "error", "message": "Missing card or card id"}
            current = _read_state()
            cards = current.get("data_cards", [])
            existing = next((i for i, c in enumerate(cards) if c["id"] == card["id"]), None)
            if existing is not None:
                cards[existing] = card
            else:
                cards.append(card)
            current["data_cards"] = cards
            _write_state(current)
            return {"status": "success"}
        elif route == "push_delete_data_card":
            card_id = body.get("id")
            if not card_id:
                return {"status": "error", "message": "Missing card id"}
            current = _read_state()
            current["data_cards"] = [c for c in current.get("data_cards", []) if c["id"] != card_id]
            _write_state(current)
            return {"status": "success"}
        elif route == "push_settings":
            bg_url = body.get("background_url", "")
            current = _read_state()
            current.setdefault("settings", {})["background_url"] = bg_url
            _write_state(current)
            return {"status": "success"}
        elif route == "push_upload_images":
            # Upload multiple images to MinIO; returns their public URLs (no state change)
            images = body.get("images", [])
            if not images:
                return {"status": "error", "message": "No images provided"}
            urls = []
            ts = int(time.time() * 1000)
            for idx, img in enumerate(images):
                image_b64 = img.get("image_b64", "")
                ext = img.get("ext", "jpg").lstrip(".")
                if not image_b64:
                    continue
                image_bytes = base64.b64decode(image_b64)
                # Normalise ext: strip any URI junk, fall back to jpg
                safe_ext = ext if ext and len(ext) <= 5 and ext.isalnum() else "jpg"
                file_name = f"tv-rotator-{ts}-{idx}.{safe_ext}"
                try:
                    MINIO_CLIENT.put_object(
                        BUCKET, file_name, io.BytesIO(image_bytes), len(image_bytes),
                        content_type=f"image/{safe_ext}",
                    )
                except Exception as e:
                    return {"status": "error", "message": f"MinIO upload failed: {e}"}
                public_url = f"https://content2.reversed.dev/{BUCKET}/{file_name}"
                urls.append(public_url)
            return {"status": "success", "urls": urls}
        else:
            return {"status": "error", "message": "Unknown push route"}
    elif route.startswith("pull"):
        current = _read_state()
        if route == "pull_text":
            return {"status": "success", "text": current.get("text", {})}
        elif route == "pull_image":
            return {"status": "success", "image_popup": current.get("image_popup", {})}
        elif route == "pull_full":
            return {"status": "success", "state": current}
        elif route == "pull_data_cards":
            return {"status": "success", "data_cards": current.get("data_cards", [])}
        else:
            return {"status": "error", "message": "Unknown pull route"}