"""Summarization entry points using Google Gemini."""
from __future__ import annotations

import logging
import os
from dataclasses import dataclass
from datetime import datetime
from typing import List, Optional

import google.generativeai as genai
from google.generativeai import GenerativeModel

from .web_content import ContentChunk, WebContent, fetch_web_or_pdf


@dataclass
class SummarizationResult:
    """Container for the response generated by Gemini."""

    summary: str
    source_type: str
    extracted_text: str
    image_count: int


DEFAULT_PROMPT = """Answer in English. You are a senior research analyst.
Provide a structured English summary based on both the textual and visual content supplied.
Please cover the following items:
1. Context — what the document or page is about and why it exists.
2. Key Findings — list three to five essential insights or messages.
3. Visual Interpretation — describe any notable charts, tables, or diagrams and explain their meaning.
4. Analyst Takeaways — offer two to three implications or recommendations.
5. Suggested Headline — propose a concise title for the material.

Write clearly and professionally as if preparing content for a briefing memo.
Date: {date}
"""

DEFAULT_PROMPT_JP = """日本語で回答してください。
あなたは上級リサーチアナリストです。
以下に与えられた**テキストおよびビジュアル（図表・画像など）**の内容に基づき、
以下の項目を必ず含めてください：
Context（背景） — そのドキュメントやページが何を扱っているのか、また存在理由（目的）は何か。
Key Findings（主要な発見・ポイント） — 3〜5個の重要な洞察やメッセージを箇条書きで。
Visual Interpretation（ビジュアルの解釈） — 図表・グラフ・表などに注目し、それが何を示しているかを説明。
Analyst Takeaways（アナリストの見解・示唆） — 2〜3個のインプリケーション（含意）または推奨事項を提示。
Suggested Headline（推奨タイトル） — 資料の内容を端的に表す簡潔な英語タイトルを提案。
文体はブリーフィングメモ（報告メモ）向けとして、明瞭かつ専門的に記述してください。
日付：{date}
"""

def _resolve_logger(logger: Optional[logging.Logger]) -> logging.Logger:
    if logger is not None:
        return logger
    default_logger = logging.getLogger("aiknowledge")
    if not default_logger.handlers:
        default_logger.addHandler(logging.NullHandler())
    return default_logger


def _build_prompt(date: datetime, custom_prompt: Optional[str], is_Japanese: bool=True) -> str:
    if custom_prompt:
        return custom_prompt
    if is_Japanese:
        return DEFAULT_PROMPT_JP.format(date=date.strftime("%Y-%m-%d"))
    else:
        return DEFAULT_PROMPT.format(date=date.strftime("%Y-%m-%d"))

def _build_parts(prompt: str, content: WebContent) -> List[object]:
    parts: List[object] = [prompt]
    for image_bytes in content.images:
        parts.append({"mime_type": "image/png", "data": image_bytes})
    text_payload = content.text if content.text.strip() else "No text could be extracted from the source."
    parts.append(
        f"Extracted text from {content.source_type} source (length={len(text_payload)} characters):\n{text_payload}"
    )
    return parts


def _build_chunk_parts(prompt: str, chunk: ContentChunk) -> List[object]:
    parts: List[object] = [prompt]
    for image_bytes in chunk.images:
        parts.append({"mime_type": "image/png", "data": image_bytes})
    text_payload = chunk.text if chunk.text.strip() else "No text could be extracted from the PDF pages."
    parts.append(
        "Text extracted from PDF pages {start}-{end} (length={length} characters):\n{text}".format(
            start=chunk.start_page,
            end=chunk.end_page,
            length=len(text_payload),
            text=text_payload,
        )
    )
    return parts


def _summarize_pdf_chunks(
    model: GenerativeModel,
    prompt_text: str,
    content: WebContent,
    logger: logging.Logger,
) -> str:
    if not content.chunks:
        parts = _build_parts(prompt_text, content)
        response = model.generate_content(parts)
        return response.text or ""

    chunk_notes: List[str] = []
    for chunk in content.chunks:
        logger.debug(
            "Sending PDF chunk covering pages %d-%d to Gemini", chunk.start_page, chunk.end_page
        )
        response = model.generate_content(_build_chunk_parts(prompt_text, chunk))
        note = response.text.strip() if response.text else ""
        chunk_notes.append(
            "Pages {start}-{end}:\n{note}".format(
                start=chunk.start_page,
                end=chunk.end_page,
                note=note or "No summary returned for these pages.",
            )
        )

    aggregated_notes = "\n\n".join(chunk_notes)
    return aggregated_notes or ""


def summarize_url(
    url: str,
    *,
    google_api_key: Optional[str] = None,
    model_name: str = "gemini-2.5-flash",
    prompt: Optional[str] = None,
    logger: Optional[logging.Logger] = None,
    max_chars: int = 6000,
    max_image_mb: float = 4.0,
    max_pdf_pages: int = 300,
    pdf_page_group_size: int = 1,
    request_timeout: int = 20,
    is_Japanese: bool = True
) -> SummarizationResult:
    """Summarize the content of a URL using Gemini.

    Args:
        url: Public URL to a web page or PDF.
        google_api_key: API key for Google Gemini. Falls back to ``GOOGLE_API_KEY`` env var.
        model_name: Name of the Gemini model to use.
        prompt: Optional custom prompt template.
        logger: Optional :class:`logging.Logger`. A default logger is used when omitted.
        max_chars: Maximum number of characters to keep from extracted text.
        max_image_mb: Maximum size of each screenshot in megabytes.
        max_pdf_pages: Maximum number of PDF pages to process.
        pdf_page_group_size: Number of PDF pages to send in each Gemini request.
        request_timeout: Timeout (seconds) for HTTP requests.

    Returns:
        :class:`SummarizationResult` with the Gemini output and extracted metadata.
    """

    resolved_logger = _resolve_logger(logger)
    resolved_logger.debug("Starting summarization for %s", url)

    if pdf_page_group_size <= 0:
        raise ValueError("pdf_page_group_size must be a positive integer.")

    content = fetch_web_or_pdf(
        url,
        logger=resolved_logger,
        max_chars=max_chars,
        max_image_mb=max_image_mb,
        max_pdf_pages=max_pdf_pages,
        pdf_page_group_size=pdf_page_group_size,
        request_timeout=request_timeout,
    )

    api_key = google_api_key or os.getenv("GOOGLE_API_KEY")
    if not api_key:
        raise ValueError("A Google API key must be provided via argument or the GOOGLE_API_KEY environment variable.")

    genai.configure(api_key=api_key)
    model = GenerativeModel(model_name)

    prompt_text = _build_prompt(datetime.utcnow(), prompt, is_Japanese)
    if content.source_type == "pdf":
        summary_text = _summarize_pdf_chunks(model, prompt_text, content, resolved_logger)
    else:
        parts = _build_parts(prompt_text, content)
        resolved_logger.debug("Sending %d parts to Gemini", len(parts))
        response = model.generate_content(parts)
        summary_text = response.text or ""

    resolved_logger.info("Finished summarization for %s", url)
    return SummarizationResult(
        summary=summary_text.strip(),
        source_type=content.source_type,
        extracted_text=content.text,
        image_count=len(content.images),
    )
