"""Google Slides API v1 integration via raw httpx."""

import httpx

from fliiq.runtime.google_auth import get_access_token

BASE_URL = "https://slides.googleapis.com/v1/presentations"


async def handler(params: dict) -> dict:
    """Handle Google Slides operations."""
    action = params["action"]

    try:
        _, access_token = await get_access_token(params.get("account_email"))
        headers = {
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json",
        }

        async with httpx.AsyncClient(timeout=30) as client:
            if action == "create":
                return await _create(client, headers, params)
            elif action == "read":
                return await _read(client, headers, params)
            elif action == "add_slide":
                return await _add_slide(client, headers, params)
            elif action == "insert_text":
                return await _insert_text(client, headers, params)
            elif action == "batch_update":
                return await _batch_update(client, headers, params)
            else:
                return {
                    "success": False,
                    "message": f"Unknown action: {action}",
                    "data": {},
                }
    except ValueError:
        raise
    except httpx.HTTPStatusError as e:
        error_msg = f"Google Slides API error: {e.response.status_code}"
        try:
            error_data = e.response.json()
            if "error" in error_data:
                detail = error_data["error"]
                if isinstance(detail, dict):
                    error_msg += f" - {detail.get('message', '')}"
                else:
                    error_msg += f" - {detail}"
        except Exception:
            pass
        return {"success": False, "message": error_msg, "data": {}}
    except Exception as e:
        return {"success": False, "message": f"Error: {e}", "data": {}}


def _extract_slide_summary(slide: dict) -> dict:
    """Extract a readable summary from a slide page object."""
    page_elements = slide.get("pageElements", [])
    texts = []
    shapes = []

    for elem in page_elements:
        obj_id = elem.get("objectId", "")
        shape = elem.get("shape")
        if shape:
            shape_type = shape.get("shapeType", "UNKNOWN")
            shapes.append({"object_id": obj_id, "type": shape_type})
            text_content = shape.get("text", {})
            for te in text_content.get("textElements", []):
                text_run = te.get("textRun")
                if text_run:
                    texts.append(text_run.get("content", ""))

    return {
        "object_id": slide.get("objectId", ""),
        "shapes": shapes,
        "text": "".join(texts).strip(),
    }


async def _create(
    client: httpx.AsyncClient, headers: dict, params: dict
) -> dict:
    """Create a new presentation."""
    title = params.get("title", "Untitled Presentation")

    resp = await client.post(
        BASE_URL,
        headers=headers,
        json={"title": title},
    )
    resp.raise_for_status()

    data = resp.json()
    return {
        "success": True,
        "message": f"Created presentation '{title}'",
        "data": {
            "presentation_id": data["presentationId"],
            "title": data.get("title", ""),
        },
    }


async def _read(
    client: httpx.AsyncClient, headers: dict, params: dict
) -> dict:
    """Read presentation structure."""
    presentation_id = params.get("presentation_id")
    if not presentation_id:
        return {
            "success": False,
            "message": "presentation_id is required for read",
            "data": {},
        }

    resp = await client.get(
        f"{BASE_URL}/{presentation_id}",
        headers=headers,
    )
    resp.raise_for_status()

    data = resp.json()
    slides = [_extract_slide_summary(s) for s in data.get("slides", [])]

    return {
        "success": True,
        "message": f"Presentation '{data.get('title', '')}' has {len(slides)} slide(s)",
        "data": {
            "presentation_id": data["presentationId"],
            "title": data.get("title", ""),
            "slides": slides,
        },
    }


async def _add_slide(
    client: httpx.AsyncClient, headers: dict, params: dict
) -> dict:
    """Add a new slide."""
    presentation_id = params.get("presentation_id")
    if not presentation_id:
        return {
            "success": False,
            "message": "presentation_id is required for add_slide",
            "data": {},
        }

    layout = params.get("layout", "BLANK")

    resp = await client.post(
        f"{BASE_URL}/{presentation_id}:batchUpdate",
        headers=headers,
        json={
            "requests": [
                {
                    "createSlide": {
                        "slideLayoutReference": {
                            "predefinedLayout": layout,
                        }
                    }
                }
            ]
        },
    )
    resp.raise_for_status()

    data = resp.json()
    replies = data.get("replies", [{}])
    slide_id = replies[0].get("createSlide", {}).get("objectId", "")

    return {
        "success": True,
        "message": f"Added slide with layout '{layout}'",
        "data": {"presentation_id": presentation_id, "slide_id": slide_id},
    }


async def _insert_text(
    client: httpx.AsyncClient, headers: dict, params: dict
) -> dict:
    """Insert text into a shape."""
    presentation_id = params.get("presentation_id")
    shape_id = params.get("shape_id")
    text = params.get("text")
    if not presentation_id or not shape_id or not text:
        return {
            "success": False,
            "message": "presentation_id, shape_id, and text are required for insert_text",
            "data": {},
        }

    insertion_index = params.get("insertion_index", 0)

    resp = await client.post(
        f"{BASE_URL}/{presentation_id}:batchUpdate",
        headers=headers,
        json={
            "requests": [
                {
                    "insertText": {
                        "objectId": shape_id,
                        "text": text,
                        "insertionIndex": insertion_index,
                    }
                }
            ]
        },
    )
    resp.raise_for_status()

    return {
        "success": True,
        "message": f"Inserted text into shape '{shape_id}'",
        "data": {"presentation_id": presentation_id, "shape_id": shape_id},
    }


async def _batch_update(
    client: httpx.AsyncClient, headers: dict, params: dict
) -> dict:
    """Apply batch updates to a presentation."""
    presentation_id = params.get("presentation_id")
    requests = params.get("requests")
    if not presentation_id or not requests:
        return {
            "success": False,
            "message": "presentation_id and requests are required for batch_update",
            "data": {},
        }

    resp = await client.post(
        f"{BASE_URL}/{presentation_id}:batchUpdate",
        headers=headers,
        json={"requests": requests},
    )
    resp.raise_for_status()

    data = resp.json()
    replies = data.get("replies", [])
    return {
        "success": True,
        "message": f"Applied {len(replies)} update(s)",
        "data": {"presentation_id": presentation_id, "replies": replies},
    }
