"""
Platform Gateway — Kindle integration (send books via SMTP2GO).
"""

import json
import base64
import urllib.request
from pathlib import Path

from config import (
    BOOKLORE_URL, BOOKLORE_BOOKS_DIR, BOOKDROP_DIR,
    SMTP2GO_API_KEY, SMTP2GO_FROM_EMAIL, SMTP2GO_FROM_NAME,
    KINDLE_EMAIL_1, KINDLE_EMAIL_2,
)
from proxy import proxy_request
from integrations.booklore import booklore_auth


def _find_book_file(book_id: str) -> tuple:
    """Find the actual ebook file for a Booklore book ID.
    Returns (file_path, book_metadata) or (None, None)."""
    token = booklore_auth()
    if not token:
        return None, None

    # Get book metadata from Booklore
    s, _, r = proxy_request(
        f"{BOOKLORE_URL}/api/v1/books/{book_id}", "GET",
        {"Authorization": f"Bearer {token}"}, timeout=10
    )
    if s != 200:
        return None, None

    book = json.loads(r)
    meta = book.get("metadata", {})
    title = meta.get("title", "")

    if not title or not BOOKLORE_BOOKS_DIR.exists():
        return None, meta

    # Search for the file in the library directory
    title_lower = title.lower()
    title_words = set(title_lower.split()[:4])  # First 4 words for matching

    best_match = None
    best_score = 0

    for ext in ["epub", "pdf", "mobi", "azw3"]:
        for filepath in BOOKLORE_BOOKS_DIR.rglob(f"*.{ext}"):
            fname = filepath.stem.lower()
            # Check if title words appear in filename
            matches = sum(1 for w in title_words if w in fname)
            score = matches / len(title_words) if title_words else 0
            # Prefer epub > pdf > mobi > azw3
            ext_bonus = {"epub": 0.1, "pdf": 0.05, "mobi": 0.03, "azw3": 0.02}.get(ext, 0)
            score += ext_bonus
            if score > best_score:
                best_score = score
                best_match = filepath

    if best_match and best_score >= 0.5:
        return best_match, meta
    return None, meta


def handle_send_to_kindle(handler, book_id: str, body: bytes):
    """Send a book file to a Kindle email via SMTP2GO API."""
    if not SMTP2GO_API_KEY or not SMTP2GO_FROM_EMAIL:
        handler._send_json({"error": "Email not configured"}, 502)
        return

    try:
        data = json.loads(body)
    except Exception as e:
        handler._send_json({"error": "Invalid JSON"}, 400)
        return

    target = data.get("target", "1")
    kindle_email = KINDLE_EMAIL_1 if target == "1" else KINDLE_EMAIL_2
    if not kindle_email:
        handler._send_json({"error": f"Kindle target {target} not configured"}, 400)
        return

    # Find the book file
    file_path, meta = _find_book_file(book_id)
    if not file_path or not file_path.exists():
        handler._send_json({"error": "Book file not found on disk"}, 404)
        return

    title = meta.get("title", "Book") if meta else "Book"
    author = ", ".join(meta.get("authors", [])) if meta else ""

    # Read file and encode as base64
    file_data = file_path.read_bytes()
    file_b64 = base64.b64encode(file_data).decode("ascii")
    filename = file_path.name

    # Determine MIME type
    ext = file_path.suffix.lower()
    mime_map = {".epub": "application/epub+zip", ".pdf": "application/pdf", ".mobi": "application/x-mobipocket-ebook", ".azw3": "application/x-mobi8-ebook"}
    mime_type = mime_map.get(ext, "application/octet-stream")

    # Send via SMTP2GO API
    email_payload = {
        "api_key": SMTP2GO_API_KEY,
        "sender": f"{SMTP2GO_FROM_NAME} <{SMTP2GO_FROM_EMAIL}>",
        "to": [kindle_email],
        "subject": f"{title}" + (f" - {author}" if author else ""),
        "text_body": f"Sent from Platform: {title}" + (f" by {author}" if author else ""),
        "attachments": [{
            "filename": filename,
            "fileblob": file_b64,
            "mimetype": mime_type,
        }]
    }

    try:
        req_body = json.dumps(email_payload).encode("utf-8")
        req = urllib.request.Request(
            "https://api.smtp2go.com/v3/email/send",
            data=req_body,
            headers={"Content-Type": "application/json"},
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read())

        if result.get("data", {}).get("succeeded", 0) > 0:
            handler._send_json({
                "success": True,
                "title": title,
                "sentTo": kindle_email,
                "format": ext.lstrip(".").upper(),
                "size": len(file_data),
            })
        else:
            handler._send_json({"error": "Email send failed", "detail": result}, 500)
    except Exception as e:
        handler._send_json({"error": f"SMTP2GO error: {str(e)}"}, 500)


def handle_send_file_to_kindle(handler, body: bytes):
    """Send a downloaded file to Kindle by filename from bookdrop directory."""
    if not SMTP2GO_API_KEY or not SMTP2GO_FROM_EMAIL:
        handler._send_json({"error": "Email not configured"}, 502)
        return
    try:
        data = json.loads(body)
    except Exception as e:
        handler._send_json({"error": "Invalid JSON"}, 400)
        return

    filename = data.get("filename", "")
    target = data.get("target", "1")
    title = data.get("title", filename)

    kindle_email = KINDLE_EMAIL_1 if target == "1" else KINDLE_EMAIL_2
    if not kindle_email:
        handler._send_json({"error": f"Kindle target {target} not configured"}, 400)
        return

    # Find file in bookdrop or booklore-books
    file_path = None
    for search_dir in [BOOKDROP_DIR, BOOKLORE_BOOKS_DIR]:
        if not search_dir.exists():
            continue
        for fp in search_dir.rglob("*"):
            if fp.is_file() and fp.name == filename:
                file_path = fp
                break
        if file_path:
            break

    if not file_path or not file_path.exists():
        handler._send_json({"error": f"File not found: {filename}"}, 404)
        return

    file_data = file_path.read_bytes()
    file_b64 = base64.b64encode(file_data).decode("ascii")

    ext = file_path.suffix.lower()
    mime_map = {".epub": "application/epub+zip", ".pdf": "application/pdf", ".mobi": "application/x-mobipocket-ebook", ".azw3": "application/x-mobi8-ebook"}
    mime_type = mime_map.get(ext, "application/octet-stream")

    email_payload = {
        "api_key": SMTP2GO_API_KEY,
        "sender": f"{SMTP2GO_FROM_NAME} <{SMTP2GO_FROM_EMAIL}>",
        "to": [kindle_email],
        "subject": title,
        "text_body": f"Sent from Platform: {title}",
        "attachments": [{"filename": filename, "fileblob": file_b64, "mimetype": mime_type}]
    }
    try:
        req_body = json.dumps(email_payload).encode("utf-8")
        req = urllib.request.Request("https://api.smtp2go.com/v3/email/send", data=req_body, headers={"Content-Type": "application/json"})
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read())
        if result.get("data", {}).get("succeeded", 0) > 0:
            handler._send_json({"success": True, "title": title, "sentTo": kindle_email, "format": ext.lstrip(".").upper()})
        else:
            handler._send_json({"error": "Email send failed", "detail": result}, 500)
    except Exception as e:
        handler._send_json({"error": f"SMTP2GO error: {str(e)}"}, 500)
