"""Handle image uploads from frontend via Daily app messages."""

import asyncio
import base64
from datetime import datetime
from loguru import logger

import httpx
from pipecat.frames.frames import OutputTransportMessageUrgentFrame

from app.services.r2 import upload_bytes

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from bot.core.config import BotSessionState, TranscriptManager


async def _send_rtvi(task, data: dict):
    try:
        frame = OutputTransportMessageUrgentFrame(message={
            "label": "rtvi-ai", "type": "server-message", "data": data,
        })
        await task.queue_frame(frame)
    except Exception as e:
        logger.warning(f"Failed to send RTVI message: {e}")


async def handle_image_upload_url(
    image_url: str,
    image_id: str,
    mime_type: str,
    bot_session: "BotSessionState",
    transcript_manager: "TranscriptManager",
    task,
):
    """Handle image upload where frontend already uploaded to R2 via HTTP.
    The bot just needs to download the image for editing and store session state."""
    if not bot_session.can_upload_image(cooldown=2.0):
        logger.debug("IMAGE_UPLOAD_DEBOUNCED")
        return

    session_id = bot_session.session_id or "unknown"
    logger.info(f"IMAGE_UPLOAD_URL: session={session_id} url={image_url} id={image_id}")

    # Download image so we have base64 for editing
    image_b64 = None
    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.get(image_url)
            response.raise_for_status()
            image_b64 = base64.b64encode(response.content).decode()
    except Exception as e:
        logger.error(f"Failed to download uploaded image: {e}")

    image_info = {
        "data": image_b64,
        "mime_type": mime_type,
        "r2_url": image_url,
        "image_id": image_id,
        "source": "upload",
        "uploaded_at": datetime.now().isoformat(),
    }
    bot_session.set_uploaded_image(image_info)

    transcript_manager.add_image_upload(
        mime_type=mime_type,
        size_bytes=len(image_b64) * 3 // 4 if image_b64 else 0,
        r2_url=image_url,
    )

    await _send_rtvi(task, {
        "type": "image_upload_status",
        "data": {"status": "uploaded", "mime_type": mime_type, "r2_url": image_url, "agent_received": True},
    })
    await _send_rtvi(task, {
        "type": "image_uploaded",
        "data": {"image_url": image_url, "image_id": image_id, "description": "Uploaded image"},
    })


async def handle_image_upload_base64(
    image_b64: str,
    mime_type: str,
    bot_session: "BotSessionState",
    transcript_manager: "TranscriptManager",
    task,
):
    """Handle image upload with base64 data (fallback for platforms that support large messages)."""
    if not bot_session.can_upload_image(cooldown=2.0):
        logger.debug("IMAGE_UPLOAD_DEBOUNCED")
        return

    session_id = bot_session.session_id or "unknown"

    await _send_rtvi(task, {
        "type": "image_upload_status",
        "data": {"status": "uploading", "mime_type": mime_type},
    })

    r2_url = None
    try:
        image_bytes = base64.b64decode(image_b64)
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        ext = "jpg" if "jpeg" in mime_type else mime_type.split("/")[-1]
        r2_key = f"sessions/{session_id}/uploads/user_upload_{timestamp}.{ext}"

        r2_url = await asyncio.to_thread(upload_bytes, image_bytes, r2_key, mime_type)
        logger.info(f"IMAGE_UPLOADED: session={session_id} r2_url={r2_url}")
    except Exception as e:
        logger.error(f"Failed to upload image to R2: {e}", exc_info=True)

    image_info = {
        "data": image_b64,
        "mime_type": mime_type,
        "r2_url": r2_url,
        "source": "upload",
        "uploaded_at": datetime.now().isoformat(),
    }
    bot_session.set_uploaded_image(image_info)

    transcript_manager.add_image_upload(
        mime_type=mime_type,
        size_bytes=len(image_b64) * 3 // 4,
        r2_url=r2_url,
    )

    if r2_url:
        await _send_rtvi(task, {
            "type": "image_upload_status",
            "data": {"status": "uploaded", "mime_type": mime_type, "r2_url": r2_url, "agent_received": True},
        })
        await _send_rtvi(task, {
            "type": "image_uploaded",
            "data": {"image_url": r2_url, "description": "Uploaded image"},
        })
    else:
        await _send_rtvi(task, {
            "type": "image_upload_status",
            "data": {"status": "failed", "mime_type": mime_type, "error": "Failed to upload to R2"},
        })
