"""Feedback-Router: Nutzer-Feedback per E-Mail an das Team."""
import html
import time
import logging
from collections import defaultdict
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
from typing import List

import aiosmtplib
from fastapi import APIRouter, Depends, HTTPException, status, Form, UploadFile, File

from auth import get_current_user
from config import (
    SMTP_HOST,
    SMTP_PORT,
    SMTP_USER,
    SMTP_PASSWORD,
    SMTP_FROM_EMAIL,
    SMTP_FROM_NAME,
    SMTP_USE_TLS,
)

logger = logging.getLogger("osint.feedback")
router = APIRouter(prefix="/api", tags=["feedback"])

FEEDBACK_EMAIL = "feedback@aegis-sight.de"
CATEGORY_LABELS = {
    "bug": "Fehlerbericht",
    "feature": "Feature-Wunsch",
    "question": "Frage",
    "other": "Sonstiges",
}

# In-Memory Rate-Limiting: max 3 pro Nutzer/Stunde
_user_timestamps: dict[int, list[float]] = defaultdict(list)
_MAX_PER_HOUR = 3
_WINDOW = 3600

_ALLOWED_TYPES = {"image/jpeg", "image/png"}
_MAX_FILE_SIZE = 5 * 1024 * 1024  # 5 MB
_MAX_FILES = 3


@router.post("/feedback", status_code=204)
async def send_feedback(
    category: str = Form(...),
    message: str = Form(..., min_length=10, max_length=5000),
    files: List[UploadFile] = File(default=[]),
    current_user: dict = Depends(get_current_user),
):
    """Feedback per E-Mail an das Team senden (mit optionalen Bild-Anhaengen)."""
    # Kategorie validieren
    if category not in CATEGORY_LABELS:
        raise HTTPException(status_code=422, detail="Ungueltige Kategorie.")

    user_id = current_user["id"]

    # Rate-Limiting
    now = time.time()
    cutoff = now - _WINDOW
    _user_timestamps[user_id] = [t for t in _user_timestamps[user_id] if t > cutoff]
    if len(_user_timestamps[user_id]) >= _MAX_PER_HOUR:
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Maximal 3 Feedback-Nachrichten pro Stunde. Bitte spaeter erneut versuchen.",
        )

    # Dateien validieren
    if len(files) > _MAX_FILES:
        raise HTTPException(status_code=422, detail=f"Maximal {_MAX_FILES} Dateien erlaubt.")
    for f in files:
        if f.content_type not in _ALLOWED_TYPES:
            raise HTTPException(status_code=422, detail=f"Dateityp {f.content_type} nicht erlaubt (nur JPEG/PNG).")

    if not SMTP_HOST:
        logger.warning("SMTP nicht konfiguriert - Feedback nicht gesendet")
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="E-Mail-Versand nicht verfuegbar.",
        )

    email = current_user.get("email", "")
    display_name = email.split("@")[0] if email else "Unbekannt"
    category_label = CATEGORY_LABELS.get(category, category)
    message_escaped = html.escape(message)

    subject = f"[AegisSight Feedback] {category_label} von {display_name}"
    html_body = f"""\
<div style="font-family:Arial,sans-serif;max-width:600px;margin:0 auto;">
  <div style="background:#151D2E;color:#E8ECF4;padding:20px;border-radius:8px 8px 0 0;">
    <h2 style="margin:0;color:#C8A851;">Neues Feedback</h2>
  </div>
  <div style="background:#1A2440;color:#E8ECF4;padding:20px;border-radius:0 0 8px 8px;">
    <table style="border-collapse:collapse;">
      <tr><td style="color:#8896AB;padding:4px 16px 4px 0;">Kategorie:</td><td><strong>{category_label}</strong></td></tr>
      <tr><td style="color:#8896AB;padding:4px 16px 4px 0;">Nutzer:</td><td>{html.escape(display_name)}</td></tr>
      <tr><td style="color:#8896AB;padding:4px 16px 4px 0;">E-Mail:</td><td>{html.escape(email) if email else "nicht hinterlegt"}</td></tr>
    </table>
    <hr style="border:none;border-top:1px solid #1E2D45;margin:16px 0;">
    <div style="white-space:pre-wrap;line-height:1.5;">{message_escaped}</div>
  </div>
</div>"""

    msg = MIMEMultipart("mixed")
    msg["From"] = f"{SMTP_FROM_NAME} <{SMTP_FROM_EMAIL}>"
    msg["To"] = FEEDBACK_EMAIL
    msg["Subject"] = subject
    if email:
        msg["Reply-To"] = email

    # Text-Teil (alternative: plain + html)
    text_part = MIMEMultipart("alternative")
    text_fallback = f"Feedback von {display_name} ({category_label}):\n\n{message}"
    text_part.attach(MIMEText(text_fallback, "plain", "utf-8"))
    text_part.attach(MIMEText(html_body, "html", "utf-8"))
    msg.attach(text_part)

    # Bild-Anhaenge
    for f in files:
        file_data = await f.read()
        if len(file_data) > _MAX_FILE_SIZE:
            raise HTTPException(status_code=422, detail=f"Datei {f.filename} ist groesser als 5 MB.")
        sub_type = (f.content_type or "image/jpeg").split("/")[1]
        attachment = MIMEBase("image", sub_type)
        attachment.set_payload(file_data)
        encoders.encode_base64(attachment)
        attachment.add_header("Content-Disposition", "attachment", filename=f.filename or "bild.jpg")
        msg.attach(attachment)
        logger.debug(f"Anhang: {f.filename} ({len(file_data)} Bytes, {f.content_type})")

    try:
        await aiosmtplib.send(
            msg,
            hostname=SMTP_HOST,
            port=SMTP_PORT,
            username=SMTP_USER if SMTP_USER else None,
            password=SMTP_PASSWORD if SMTP_PASSWORD else None,
            start_tls=SMTP_USE_TLS,
        )
        _user_timestamps[user_id].append(now)
        logger.info(f"Feedback von {display_name} ({category_label}) gesendet, {len(files)} Anhaenge")
    except Exception as e:
        logger.error(f"Feedback-E-Mail fehlgeschlagen: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="E-Mail konnte nicht gesendet werden.",
        )
