"""
Notion integration service with official SDK
"""

import logging
from typing import Optional, Dict, Any, List
from pathlib import Path
from datetime import datetime
import time

try:
    from notion_client import Client
    from notion_client.errors import APIResponseError

    NOTION_AVAILABLE = True
except ImportError:
    NOTION_AVAILABLE = False
    Client = None
    APIResponseError = Exception

from config import settings


class NotionService:
    """Enhanced Notion API integration service"""

    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self._client: Optional[Client] = None
        self._database_id: Optional[str] = None

    def configure(self, token: str, database_id: str) -> None:
        """Configure Notion with official SDK"""
        if not NOTION_AVAILABLE:
            self.logger.error(
                "notion-client not installed. Install with: pip install notion-client"
            )
            return

        self._client = Client(auth=token)
        self._database_id = database_id
        self.logger.info("Notion service configured with official SDK")

    @property
    def is_configured(self) -> bool:
        """Check if Notion is configured"""
        return bool(self._client and self._database_id and NOTION_AVAILABLE)

    def _rate_limited_request(self, func, *args, **kwargs):
        """Execute request with rate limiting and retry"""
        max_retries = 3
        base_delay = 1

        for attempt in range(max_retries):
            try:
                return func(*args, **kwargs)
            except APIResponseError as e:
                if hasattr(e, "code") and e.code == "rate_limited":
                    delay = base_delay * (2**attempt)
                    self.logger.warning(f"Rate limited by Notion, waiting {delay}s")
                    time.sleep(delay)
                else:
                    raise

        raise Exception("Max retries exceeded for Notion API")

    def create_page_with_summary(
        self, title: str, summary: str, metadata: Dict[str, Any]
    ) -> Optional[str]:
        """Create a new page in Notion (database or parent page) with summary content"""
        if not self.is_configured:
            self.logger.warning("Notion not configured, skipping upload")
            return None

        try:
            # Determinar si es database o página padre
            use_as_page = metadata.get("use_as_page", False)

            if use_as_page:
                # Crear página dentro de otra página
                page = self._rate_limited_request(
                    self._client.pages.create,
                    parent={"page_id": self._database_id},
                    properties={"title": [{"text": {"content": title[:100]}}]},
                )
            else:
                # Crear página en database (método original)
                properties = {"Name": {"title": [{"text": {"content": title[:100]}}]}}

                # Agregar status si la DB lo soporta
                if metadata.get("add_status", True):
                    properties["Status"] = {"select": {"name": "Procesado"}}

                # Agregar tipo de archivo si está disponible Y add_status está habilitado
                if metadata.get("add_status", False) and metadata.get("file_type"):
                    properties["Tipo"] = {
                        "select": {" name": metadata["file_type"].upper()}
                    }

                page = self._rate_limited_request(
                    self._client.pages.create,
                    parent={"database_id": self._database_id},
                    properties=properties,
                )

            page_id = page["id"]
            self.logger.info(f"✅ Notion page created: {page_id}")

            # Agregar contenido del resumen como bloques
            self._add_summary_content(page_id, summary, metadata.get("pdf_path"))

            return page_id

        except Exception as e:
            self.logger.error(f"❌ Error creating Notion page: {e}")
            return None

        try:
            # Preparar properties de la página
            properties = {
                "Name": {
                    "title": [
                        {
                            "text": {
                                "content": title[:100]  # Notion limit
                            }
                        }
                    ]
                }
            }

            # Agregar status si la DB lo soporta
            if metadata.get("add_status", True):
                properties["Status"] = {"select": {"name": "Procesado"}}

            # Agregar tipo de archivo si está disponible
            if metadata.get("file_type"):
                properties["Tipo"] = {"select": {"name": metadata["file_type"].upper()}}

            # Crear página
            page = self._rate_limited_request(
                self._client.pages.create,
                parent={"database_id": self._database_id},
                properties=properties,
            )

            page_id = page["id"]
            self.logger.info(f"✅ Notion page created: {page_id}")

            # Agregar contenido del resumen como bloques
            self._add_summary_content(page_id, summary, metadata.get("pdf_path"))

            return page_id

        except Exception as e:
            self.logger.error(f"❌ Error creating Notion page: {e}")
            return None

    def _add_summary_content(
        self, page_id: str, summary: str, pdf_path: Optional[Path] = None
    ) -> bool:
        """Add summary content as Notion blocks"""
        try:
            blocks = []

            # Agregar nota sobre el PDF si existe
            if pdf_path and pdf_path.exists():
                blocks.append(
                    {
                        "object": "block",
                        "type": "callout",
                        "callout": {
                            "rich_text": [
                                {
                                    "type": "text",
                                    "text": {
                                        "content": f"📄 Documento generado automáticamente: {pdf_path.name}"
                                    },
                                }
                            ],
                            "icon": {"emoji": "📄"},
                        },
                    }
                )

            # Agregar bloques del resumen
            summary_blocks = self._parse_markdown_to_blocks(summary)
            blocks.extend(summary_blocks)

            # Agregar footer
            blocks.append({"object": "block", "type": "divider", "divider": {}})
            blocks.append(
                {
                    "object": "block",
                    "type": "paragraph",
                    "paragraph": {
                        "rich_text": [
                            {
                                "type": "text",
                                "text": {
                                    "content": f"Generado por CBCFacil el {datetime.now().strftime('%d/%m/%Y %H:%M')}"
                                },
                                "annotations": {"italic": True, "color": "gray"},
                            }
                        ]
                    },
                }
            )

            # Notion API limita a 100 bloques por request
            if blocks:
                for i in range(0, len(blocks), 100):
                    batch = blocks[i : i + 100]
                    self._rate_limited_request(
                        self._client.blocks.children.append,
                        block_id=page_id,
                        children=batch,
                    )
                self.logger.info(f"✅ Added {len(blocks)} blocks to Notion page")

            return True

        except Exception as e:
            self.logger.error(f"❌ Error adding content blocks: {e}")
            return False

    def _parse_markdown_to_blocks(self, markdown: str) -> List[Dict]:
        """Convert markdown to Notion blocks"""
        blocks = []
        lines = markdown.split("\n")

        for line in lines:
            line = line.strip()

            if not line:
                continue

            # Headings
            if line.startswith("# "):
                text = line[2:].strip()[:2000]
                if text:
                    blocks.append(
                        {
                            "object": "block",
                            "type": "heading_1",
                            "heading_1": {
                                "rich_text": [
                                    {"type": "text", "text": {"content": text}}
                                ]
                            },
                        }
                    )
            elif line.startswith("## "):
                text = line[3:].strip()[:2000]
                if text:
                    blocks.append(
                        {
                            "object": "block",
                            "type": "heading_2",
                            "heading_2": {
                                "rich_text": [
                                    {"type": "text", "text": {"content": text}}
                                ]
                            },
                        }
                    )
            elif line.startswith("### "):
                text = line[4:].strip()[:2000]
                if text:
                    blocks.append(
                        {
                            "object": "block",
                            "type": "heading_3",
                            "heading_3": {
                                "rich_text": [
                                    {"type": "text", "text": {"content": text}}
                                ]
                            },
                        }
                    )
            # Bullet points
            elif line.startswith("- ") or line.startswith("* "):
                text = line[2:].strip()[:2000]
                if text:
                    blocks.append(
                        {
                            "object": "block",
                            "type": "bulleted_list_item",
                            "bulleted_list_item": {
                                "rich_text": [
                                    {"type": "text", "text": {"content": text}}
                                ]
                            },
                        }
                    )
            # Divider
            elif line.strip() == "---":
                blocks.append({"object": "block", "type": "divider", "divider": {}})
            # Paragraph (skip footer lines)
            elif not line.startswith("*Generado por"):
                text = line[:2000]
                if text:
                    blocks.append(
                        {
                            "object": "block",
                            "type": "paragraph",
                            "paragraph": {
                                "rich_text": [
                                    {"type": "text", "text": {"content": text}}
                                ]
                            },
                        }
                    )

        return blocks

    def upload_pdf_legacy(self, pdf_path: Path, title: str) -> bool:
        """Legacy method - creates simple page (backward compatibility)"""
        if not self.is_configured:
            self.logger.warning("Notion not configured, skipping upload")
            return False

        try:
            # Crear página simple
            page_id = self.create_page_with_summary(
                title=title,
                summary=f"Documento procesado: {title}",
                metadata={"file_type": "PDF", "pdf_path": pdf_path},
            )

            return bool(page_id)

        except Exception as e:
            self.logger.error(f"Error uploading PDF to Notion: {e}")
            return False

    # Alias para backward compatibility
    def upload_pdf(self, pdf_path: Path, title: str) -> bool:
        """Upload PDF info to Notion (alias for backward compatibility)"""
        return self.upload_pdf_legacy(pdf_path, title)

    def upload_pdf_as_file(self, pdf_path: Path, title: str) -> bool:
        """Upload PDF info as file (alias for backward compatibility)"""
        return self.upload_pdf_legacy(pdf_path, title)


# Global instance
notion_service = NotionService()


def upload_to_notion(pdf_path: Path, title: str) -> bool:
    """Legacy function for backward compatibility"""
    return notion_service.upload_pdf(pdf_path, title)
