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

import httpx

from fliiq.runtime.google_auth import get_access_token

BASE_URL = "https://docs.googleapis.com/v1/documents"


async def handler(params: dict) -> dict:
    """Handle Google Docs 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 == "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 Docs 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_text(body: dict) -> str:
    """Flatten Docs API body content to plain text."""
    parts = []
    for element in body.get("content", []):
        paragraph = element.get("paragraph")
        if paragraph:
            for pe in paragraph.get("elements", []):
                text_run = pe.get("textRun")
                if text_run:
                    parts.append(text_run.get("content", ""))
        table = element.get("table")
        if table:
            for row in table.get("tableRows", []):
                for cell in row.get("tableCells", []):
                    for cell_element in cell.get("content", []):
                        cell_paragraph = cell_element.get("paragraph")
                        if cell_paragraph:
                            for pe in cell_paragraph.get("elements", []):
                                text_run = pe.get("textRun")
                                if text_run:
                                    parts.append(text_run.get("content", ""))
    return "".join(parts)


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

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

    data = resp.json()
    return {
        "success": True,
        "message": f"Created document '{title}'",
        "data": {
            "document_id": data["documentId"],
            "title": data.get("title", ""),
        },
    }


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

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

    data = resp.json()
    text = _extract_text(data.get("body", {}))

    return {
        "success": True,
        "message": f"Read document '{data.get('title', '')}'",
        "data": {
            "document_id": data["documentId"],
            "title": data.get("title", ""),
            "text": text,
            "raw": data.get("body", {}),
        },
    }


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

    index = params.get("index", 1)

    resp = await client.post(
        f"{BASE_URL}/{document_id}:batchUpdate",
        headers=headers,
        json={
            "requests": [
                {
                    "insertText": {
                        "location": {"index": index},
                        "text": text,
                    }
                }
            ]
        },
    )
    resp.raise_for_status()

    return {
        "success": True,
        "message": f"Inserted {len(text)} character(s) at index {index}",
        "data": {"document_id": document_id},
    }


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

    resp = await client.post(
        f"{BASE_URL}/{document_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": {"document_id": document_id, "replies": replies},
    }
