import os
import asyncio
from io import BytesIO
from datetime import datetime
from nio import AsyncClient, UploadResponse, RoomSendResponse


async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, comment: str = ""):
    """
    Sends a print order summary + PDF to the specified Matrix room.
    """
    matrix_user = os.environ.get("MATRIX_USER")
    matrix_pass = os.environ.get("MATRIX_PASS")
    homeserver = os.environ.get("MATRIX_HOMESERVER", "http://124.local:8008")

    if not matrix_user or not matrix_pass:
        raise RuntimeError("Missing MATRIX_USER or MATRIX_PASS in environment")

    client = AsyncClient(homeserver, matrix_user)

    try:
        login_resp = await client.login(matrix_pass)
        if getattr(login_resp, "access_token", None) is None:
            raise RuntimeError(f"Failed to login to Matrix: {login_resp}")

        # Determine if document is color or B&W
        has_color = analysis['total_area_color'] > 0
        color_marker = "Farbe" if has_color else "SW"

        # Generate new filename: ISO timestamp, name, price, color marker
        # Format: YYYY-MM-DDTHHMM_Name_PriceEUR_ColorMarker.pdf
        timestamp = datetime.now().strftime("%Y-%m-%dT%H%M")
        # Sanitize name for filename (remove special chars, limit length)
        safe_name = "".join(c for c in name if c.isalnum() or c in (' ', '-', '_')).strip()
        safe_name = safe_name.replace(' ', '_')[:30]  # Max 30 chars
        # Use underscore instead of decimal point/comma for price
        price_str = f"{analysis['grand_total']:.2f}".replace('.', '_')
        new_filename = f"{timestamp}_{safe_name}_{price_str}EUR_{color_marker}.pdf"

        # Build condensed German summary - focus on key info
        summary_lines = [
            "=== NEUER DRUCKAUFTRAG ===",
            "",
            f"Name: {name}",
            f"Preis: {analysis['grand_total']:.2f} EUR",
        ]

        # Add comment prominently if provided
        if comment.strip():
            summary_lines.extend([
                "",
                f"Kommentar:",
                f"{comment.strip()}",
            ])

        # Add compact breakdown
        summary_lines.extend([
            "",
            "Details:",
        ])

        if analysis['total_area_black'] > 0:
            summary_lines.append(
                f"  - S/W: {analysis['total_area_black']:.2f} m2 -> {analysis['total_cost_black']:.2f} EUR"
            )

        if analysis['total_area_color'] > 0:
            summary_lines.append(
                f"  - Farbe: {analysis['total_area_color']:.2f} m2 -> {analysis['total_cost_color']:.2f} EUR"
            )

        # Add page count summary
        total_pages = len(analysis['pages'])
        color_pages = sum(1 for p in analysis['pages'] if p['is_color'])
        bw_pages = total_pages - color_pages
        summary_lines.append(f"  - Seiten: {total_pages} gesamt ({bw_pages} S/W, {color_pages} Farbe)")

        # Optional: Add detailed page breakdown for small documents
        if total_pages <= 5:  # Only show details for small documents
            summary_lines.append("")
            summary_lines.append("Seiten:")
            for page in analysis["pages"]:
                seitenart = "Farbe" if page["is_color"] else "S/W"
                summary_lines.append(
                    f"  - S.{page['page']}: {page['width_m']*1000:.0f}x{page['height_m']*1000:.0f}mm, {seitenart}, {page['cost']:.2f} EUR"
                )

        summary_text = "\n".join(summary_lines)

        # Send summary message
        text_resp = await client.room_send(
            room_id=room_id,
            message_type="m.room.message",
            content={"msgtype": "m.text", "body": summary_text},
        )
        if not (isinstance(text_resp, RoomSendResponse) and text_resp.event_id):
            raise RuntimeError(f"Failed to send order summary: {text_resp}")

        # Upload PDF with new filename
        with open(pdf_path, "rb") as f:
            pdf_bytes = f.read()

        upload_resp, upload_err = await client.upload(
            data_provider=BytesIO(pdf_bytes),
            content_type="application/pdf",
            filename=new_filename,  # Use generated filename
            filesize=len(pdf_bytes),
        )

        if upload_err or not (isinstance(upload_resp, UploadResponse) and upload_resp.content_uri):
            raise RuntimeError(f"Failed to upload PDF: {upload_err or upload_resp}")

        # Send PDF as file message
        file_resp = await client.room_send(
            room_id=room_id,
            message_type="m.room.message",
            content={
                "msgtype": "m.file",
                "body": new_filename,  # Display new filename
                "url": upload_resp.content_uri,
            },
        )
        if not (isinstance(file_resp, RoomSendResponse) and file_resp.event_id):
            raise RuntimeError(f"Failed to send PDF message: {file_resp}")

        print(f"✅ Order sent to room {room_id} as {new_filename}")

    finally:
        await client.logout()
        await client.close()


def send_order_sync(pdf_path: str, analysis: dict, room_id: str, name: str, comment: str = ""):
    asyncio.run(send_order(pdf_path, analysis, room_id, name, comment))
