"""Server-gerenderte Seiten mit Jinja2 + HTMX"""
import logging
from aiohttp import web
import aiohttp_jinja2
from app.config import Config
from app.services.queue import QueueService
from app.services.encoder import EncoderService
from app.models.media import MediaFile


def setup_page_routes(app: web.Application, config: Config,
                      queue_service: QueueService) -> None:
    """Registriert Seiten-Routes"""

    def _build_ws_url(request) -> str:
        """Baut WebSocket-URL fuer den Client"""
        srv = config.server_config
        ext_url = srv.get("external_url", "")
        use_https = srv.get("use_https", False)
        ws_path = srv.get("websocket_path", "/ws")
        protocol = "wss" if use_https else "ws"

        if ext_url:
            return f"{protocol}://{ext_url}{ws_path}"
        return f"{protocol}://{request.host}{ws_path}"

    @aiohttp_jinja2.template("dashboard.html")
    async def dashboard(request: web.Request) -> dict:
        """GET / - Dashboard"""
        return {
            "ws_url": _build_ws_url(request),
            "active_jobs": queue_service.get_active_jobs().get("data_convert", {}),
            "queue": queue_service.get_queue_state().get("data_queue", {}),
        }

    @aiohttp_jinja2.template("admin.html")
    async def admin(request: web.Request) -> dict:
        """GET /admin - Einstellungsseite"""
        gpu_available = EncoderService.detect_gpu_available()
        gpu_devices = EncoderService.get_available_render_devices()
        return {
            "settings": config.settings,
            "presets": config.presets,
            "gpu_available": gpu_available,
            "gpu_devices": gpu_devices,
        }

    @aiohttp_jinja2.template("tv_admin.html")
    async def tv_admin(request: web.Request) -> dict:
        """GET /tv-admin - TV Admin-Center"""
        tv = config.settings.get("tv", {})
        return {"tv": tv}

    @aiohttp_jinja2.template("library.html")
    async def library(request: web.Request) -> dict:
        """GET /library - Bibliothek"""
        return {}

    @aiohttp_jinja2.template("statistics.html")
    async def statistics(request: web.Request) -> dict:
        """GET /statistics - Statistik-Seite"""
        entries = await queue_service.get_statistics(limit=50)
        summary = await queue_service.get_statistics_summary()
        return {
            "entries": entries,
            "summary": summary,
            "format_size": MediaFile.format_size,
            "format_time": MediaFile.format_time,
        }

    # --- HTMX Partials ---

    async def htmx_save_settings(request: web.Request) -> web.Response:
        """POST /htmx/settings - Settings via Formular speichern"""
        data = await request.post()

        # Formular-Daten in Settings-Struktur konvertieren
        settings = config.settings

        # Encoding
        settings["encoding"]["mode"] = data.get("encoding_mode", "cpu")
        settings["encoding"]["gpu_device"] = data.get("gpu_device",
                                                       "/dev/dri/renderD128")
        settings["encoding"]["default_preset"] = data.get("default_preset",
                                                           "cpu_av1")
        settings["encoding"]["max_parallel_jobs"] = int(
            data.get("max_parallel_jobs", 1)
        )

        # Files
        settings["files"]["target_container"] = data.get("target_container", "webm")
        settings["files"]["target_folder"] = data.get("target_folder", "same")
        settings["files"]["delete_source"] = data.get("delete_source") == "on"
        settings["files"]["recursive_scan"] = data.get("recursive_scan") == "on"

        # Cleanup
        settings["cleanup"]["enabled"] = data.get("cleanup_enabled") == "on"
        cleanup_ext = data.get("cleanup_extensions", "")
        if cleanup_ext:
            settings["cleanup"]["delete_extensions"] = [
                e.strip() for e in cleanup_ext.split(",") if e.strip()
            ]
        exclude_pat = data.get("cleanup_exclude", "")
        if exclude_pat:
            settings["cleanup"]["exclude_patterns"] = [
                p.strip() for p in exclude_pat.split(",") if p.strip()
            ]

        # Audio
        audio_langs = data.get("audio_languages", "ger,eng,und")
        settings["audio"]["languages"] = [
            l.strip() for l in audio_langs.split(",") if l.strip()
        ]
        settings["audio"]["default_codec"] = data.get("audio_codec", "libopus")
        settings["audio"]["keep_channels"] = data.get("keep_channels") == "on"

        # Subtitle
        sub_langs = data.get("subtitle_languages", "ger,eng")
        settings["subtitle"]["languages"] = [
            l.strip() for l in sub_langs.split(",") if l.strip()
        ]

        # Logging
        settings["logging"]["level"] = data.get("log_level", "INFO")

        # Bibliothek / TVDB
        settings.setdefault("library", {})
        settings["library"]["tvdb_api_key"] = data.get("tvdb_api_key", "")
        settings["library"]["tvdb_pin"] = data.get("tvdb_pin", "")
        settings["library"]["tvdb_language"] = data.get("tvdb_language", "deu")

        config.save_settings()
        logging.info("Settings via Admin-UI gespeichert")

        # Erfolgs-HTML zurueckgeben (HTMX swap)
        return web.Response(
            text='<div class="toast success">Settings gespeichert!</div>',
            content_type="text/html",
        )

    async def htmx_save_tv_settings(request: web.Request) -> web.Response:
        """POST /htmx/tv-settings - TV-Settings via Formular speichern"""
        data = await request.post()
        settings = config.settings
        settings.setdefault("tv", {})

        settings["tv"]["hls_segment_duration"] = int(
            data.get("hls_segment_duration", 4))
        settings["tv"]["hls_init_duration"] = int(
            data.get("hls_init_duration", 1))
        settings["tv"]["hls_session_timeout_min"] = int(
            data.get("hls_session_timeout_min", 5))
        settings["tv"]["hls_max_sessions"] = int(
            data.get("hls_max_sessions", 5))
        settings["tv"]["pause_batch_on_stream"] = (
            data.get("pause_batch_on_stream") == "on")
        settings["tv"]["force_transcode"] = (
            data.get("force_transcode") == "on")
        settings["tv"]["audio_loudnorm"] = (
            data.get("audio_loudnorm") == "on")
        settings["tv"]["audio_dynaudnorm"] = (
            data.get("audio_dynaudnorm") == "on")
        settings["tv"]["watched_threshold_pct"] = int(
            data.get("watched_threshold_pct", 90))

        config.save_settings()
        logging.info("TV-Settings via Admin-UI gespeichert")

        return web.Response(
            text='<div class="toast success">TV-Settings gespeichert!</div>',
            content_type="text/html",
        )

    async def htmx_save_preset(request: web.Request) -> web.Response:
        """POST /htmx/preset/{preset_name} - Preset via Formular speichern"""
        preset_name = request.match_info["preset_name"]
        data = await request.post()

        # Extra-Params parsen (key=value pro Zeile)
        extra_params = {}
        raw_extra = data.get("extra_params", "").strip()
        for line in raw_extra.splitlines():
            line = line.strip()
            if "=" in line:
                k, v = line.split("=", 1)
                extra_params[k.strip()] = v.strip()

        # Speed-Preset: int oder string oder None
        speed_raw = data.get("speed_preset", "").strip()
        speed_preset = None
        if speed_raw:
            try:
                speed_preset = int(speed_raw)
            except ValueError:
                speed_preset = speed_raw

        preset = {
            "name": data.get("name", preset_name),
            "video_codec": data.get("video_codec", "libx264"),
            "container": data.get("container", "mp4"),
            "quality_param": data.get("quality_param", "crf"),
            "quality_value": int(data.get("quality_value", 23)),
            "gop_size": int(data.get("gop_size", 240)),
            "speed_preset": speed_preset,
            "video_filter": data.get("video_filter", ""),
            "hw_init": data.get("hw_init") == "on",
            "extra_params": extra_params,
        }

        config.presets[preset_name] = preset
        config.save_presets()
        logging.info(f"Preset '{preset_name}' via Admin-UI gespeichert")

        return web.Response(
            text='<div class="toast success">Preset gespeichert!</div>',
            content_type="text/html",
        )

    @aiohttp_jinja2.template("partials/stats_table.html")
    async def htmx_stats_table(request: web.Request) -> dict:
        """GET /htmx/stats?page=1 - Paginierte Statistik"""
        page = int(request.query.get("page", 1))
        limit = 25
        offset = (page - 1) * limit
        entries = await queue_service.get_statistics(limit, offset)
        return {
            "entries": entries,
            "page": page,
            "format_size": MediaFile.format_size,
            "format_time": MediaFile.format_time,
        }

    async def redirect_to_library(request: web.Request):
        """GET / -> Weiterleitung zur Bibliothek"""
        raise web.HTTPFound("/library")

    # Routes registrieren
    app.router.add_get("/", redirect_to_library)
    app.router.add_get("/dashboard", dashboard)
    app.router.add_get("/library", library)
    app.router.add_get("/admin", admin)
    app.router.add_get("/tv-admin", tv_admin)
    app.router.add_get("/statistics", statistics)
    app.router.add_post("/htmx/settings", htmx_save_settings)
    app.router.add_post("/htmx/tv-settings", htmx_save_tv_settings)
    app.router.add_post("/htmx/preset/{preset_name}", htmx_save_preset)
    app.router.add_get("/htmx/stats", htmx_stats_table)
