from __future__ import annotations

import base64
import logging
import shutil
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)

from .pdf_structure_md import DrawingPdfStructureMdMixin


class DrawingPdfImagesMixin:
    @staticmethod
    def render_pdf_to_images(
        file_path: Path,
        max_pages: int = 400,
        dpi: int = 150,
        takeoff_id: str | None = None,
    ) -> list[dict[str, Any]]:
        """Render ALL pages of a PDF drawing to high-resolution PNG images and save to static storage."""
        from app.modules.takeoff.application.vietnamese_cad_font_transcoder import (
            VietnameseCadFontTranscoder,
        )

        rendered_pages: list[dict[str, Any]] = []
        static_drawings_dir = (
            Path(__file__).resolve().parents[2] / "static" / "drawings"
        )
        static_drawings_dir.mkdir(parents=True, exist_ok=True)
        file_path = Path(file_path)
        file_prefix = takeoff_id if takeoff_id else file_path.stem

        # 1. High-Density AI-Friendly Text & Geometry Structure Extraction
        ai_structure = DrawingPdfStructureMdMixin.extract_ai_friendly_pdf_structure(
            file_path, max_pages=min(max_pages, 160)
        )
        full_structured_md = ai_structure.get("structured_markdown", "")

        try:
            import fitz  # PyMuPDF

            doc = fitz.open(str(file_path))
            total_pages = min(len(doc), max_pages)
            for page_idx in range(total_pages):
                page = doc[page_idx]
                zoom = dpi / 72.0
                mat = fitz.Matrix(zoom, zoom)
                pix = page.get_pixmap(matrix=mat)

                # Save high-res PNG to static drawings directory
                page_png_name = f"{file_prefix}_p{page_idx + 1}.png"
                page_png_path = static_drawings_dir / page_png_name
                pix.save(str(page_png_path))

                if page_idx == 0:
                    master_png_path = static_drawings_dir / f"{file_prefix}_master.png"
                    pix.save(str(master_png_path))

                # Encode Base64 for fast LLM Vision
                b64 = base64.b64encode(pix.tobytes("png")).decode("utf-8")

                raw_text = page.get_text("text") or ""
                clean_text = VietnameseCadFontTranscoder.auto_transcode_cad_text(
                    raw_text
                )

                # Generate meaningful sheet title based on content
                title = f"Trang {page_idx + 1}"
                txt_l = clean_text.lower()
                if page_idx == 0:
                    title = "Trang 1: Bìa Hồ Sơ / Mặt Bằng Tổng Thể"
                elif "ép cừ" in txt_l or "cừ thép" in txt_l or "larsen" in txt_l:
                    title = f"Trang {page_idx + 1}: Mặt Bằng & Biện Pháp Ép Cừ"
                elif "móng" in txt_l or "cột" in txt_l:
                    title = f"Trang {page_idx + 1}: Mặt Bằng Móng & Bố Trí Cột"
                elif "thép" in txt_l or "cốt thép" in txt_l:
                    title = f"Trang {page_idx + 1}: Chi Tiết Cốt Thép & Bảng Thống Kê"
                elif "mặt cắt" in txt_l or "phân đoạn" in txt_l:
                    title = f"Trang {page_idx + 1}: Mặt Cắt & Chi Tiết Cấu Kiện"
                elif "mặt bằng" in txt_l and "cống" in txt_l:
                    title = f"Trang {page_idx + 1}: Mặt Bằng Tuyến Cống Hộp"
                elif "bình đồ" in txt_l:
                    title = f"Trang {page_idx + 1}: Bình Đồ Tuyến Công Trình"
                elif "khảo sát" in txt_l:
                    title = f"Trang {page_idx + 1}: Phần I - Khảo Sát Tuyến"
                elif "thiết kế" in txt_l:
                    title = f"Trang {page_idx + 1}: Phần II - Hồ Sơ Thiết Kế"

                # Smart crop title block & high-res details for Vision Model
                crop_b64 = ""
                try:
                    # Crop bottom-right 30% area (Title Block)
                    pw = page.rect.width
                    ph = page.rect.height
                    tb_rect = fitz.Rect(pw * 0.5, ph * 0.65, pw, ph)
                    tb_pix = page.get_pixmap(matrix=fitz.Matrix(2.0, 2.0), clip=tb_rect)
                    crop_b64 = base64.b64encode(tb_pix.tobytes("png")).decode("utf-8")
                except Exception:
                    pass

                rendered_pages.append(
                    {
                        "page_number": page_idx + 1,
                        "title": title,
                        "image_url": f"/static/drawings/{page_png_name}",
                        "image_base64": b64,
                        "crop_image_base64": crop_b64,
                        "mime_type": "image/png",
                        "text_layer": clean_text[:32000],
                        "ai_structured_markdown": full_structured_md
                        if page_idx == 0
                        else "",
                    }
                )
            doc.close()
            return rendered_pages
        except Exception as e:
            logger.warning(
                "[TAKEOFF] PyMuPDF rendering failed: %s. Trying Pillow / raw read...", e
            )

        # Fallback if image file or PyMuPDF fails
        if file_path.suffix.lower() in [".png", ".jpg", ".jpeg", ".webp"]:
            try:
                page_png_name = f"{file_prefix}_master.png"
                target_png = static_drawings_dir / page_png_name
                shutil.copy2(file_path, target_png)
                with open(file_path, "rb") as f:
                    b64 = base64.b64encode(f.read()).decode("utf-8")
                mime = (
                    "image/png" if file_path.suffix.lower() == ".png" else "image/jpeg"
                )
                rendered_pages.append(
                    {
                        "page_number": 1,
                        "title": f"Bản vẽ: {file_path.stem}",
                        "image_url": f"/static/drawings/{page_png_name}",
                        "image_base64": b64,
                        "mime_type": mime,
                        "text_layer": "",
                    }
                )
            except Exception as read_err:
                logger.error(
                    "[TAKEOFF] Failed reading image file %s: %s", file_path, read_err
                )

        return rendered_pages
