# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# Licensed under the MIT License

"""Media routes — extracted from memory.py."""

from __future__ import annotations

import json
import logging
import os
import re
import threading
from datetime import datetime
from pathlib import Path

from flask import Blueprint, Response, jsonify, request, send_file

from ..auth import require_auth
from ..helpers import get_agent, get_service_manager, get_marketplace_catalog, DATA_DIR, safe_error

logger = logging.getLogger(__name__)

bp = Blueprint("media", __name__)


@bp.route("/api/media/radio/search")
@require_auth
def api_media_radio_search():
    """Search radio stations."""
    try:
        from familiar.skills.media.radio import search_stations

        name = request.args.get("name", "")
        tag = request.args.get("tag", "")
        country = request.args.get("country", "")
        limit = int(request.args.get("limit", 25))
        stations = search_stations(name=name, tag=tag, country=country, limit=limit)
        return jsonify({"stations": stations})
    except Exception as e:
        logger.debug("Radio search error: %s", e)
        return jsonify({"stations": [], "error": safe_error(e)}), 502


@bp.route("/api/media/radio/genres")
@require_auth
def api_media_radio_genres():
    """Get popular radio genres."""
    try:
        from familiar.skills.media.radio import get_genres

        limit = int(request.args.get("limit", 50))
        genres = get_genres(limit=limit)
        return jsonify({"genres": genres})
    except Exception as e:
        logger.debug("Radio genres error: %s", e)
        return jsonify({"genres": [], "error": safe_error(e)}), 502


@bp.route("/api/media/radio/popular")
@require_auth
def api_media_radio_popular():
    """Get popular radio stations."""
    try:
        from familiar.skills.media.radio import get_popular

        limit = int(request.args.get("limit", 25))
        stations = get_popular(limit=limit)
        return jsonify({"stations": stations})
    except Exception as e:
        logger.debug("Radio popular error: %s", e)
        return jsonify({"stations": [], "error": safe_error(e)}), 502


@bp.route("/api/media/podcasts/search")
@require_auth
def api_media_podcasts_search():
    """Search podcasts via iTunes."""
    try:
        from familiar.skills.media.podcasts import search_podcasts

        term = request.args.get("term", "")
        limit = int(request.args.get("limit", 25))
        podcasts = search_podcasts(term=term, limit=limit)
        return jsonify({"podcasts": podcasts})
    except Exception as e:
        logger.debug("Podcast search error: %s", e)
        return jsonify({"podcasts": [], "error": safe_error(e)}), 502


@bp.route("/api/media/podcasts/episodes")
@require_auth
def api_media_podcasts_episodes():
    """Get podcast episodes from RSS feed."""
    try:
        from familiar.skills.media.podcasts import get_episodes

        feed_url = request.args.get("feed_url", "")
        limit = int(request.args.get("limit", 20))
        episodes = get_episodes(feed_url=feed_url, limit=limit)
        return jsonify({"episodes": episodes})
    except Exception as e:
        logger.debug("Podcast episodes error: %s", e)
        return jsonify({"episodes": [], "error": safe_error(e)}), 502


@bp.route("/api/media/favorites")
@require_auth
def api_media_favorites():
    """Get saved media favorites."""
    try:
        from familiar.skills.media.skill import get_favorites

        return jsonify({"favorites": get_favorites()})
    except Exception as e:
        logger.debug("Media favorites error: %s", e)
        return jsonify({"favorites": [], "error": safe_error(e)}), 502


@bp.route("/api/media/favorites/add", methods=["POST"])
@require_auth
def api_media_favorites_add():
    """Add a media item to favorites."""
    try:
        from familiar.skills.media.skill import add_favorite

        item = request.get_json() or {}
        added = add_favorite(item)
        return jsonify({"success": added})
    except Exception as e:
        logger.debug("Media favorite add error: %s", e)
        return jsonify({"success": False, "error": safe_error(e)}), 500


@bp.route("/api/media/favorites/remove", methods=["POST"])
@require_auth
def api_media_favorites_remove():
    """Remove a media item from favorites."""
    try:
        from familiar.skills.media.skill import remove_favorite

        item = request.get_json() or {}
        removed = remove_favorite(item)
        return jsonify({"success": removed})
    except Exception as e:
        logger.debug("Media favorite remove error: %s", e)
        return jsonify({"success": False, "error": safe_error(e)}), 500


@bp.route("/api/media/history")
@require_auth
def api_media_history():
    """Get media play history."""
    try:
        from familiar.skills.media.skill import get_history

        return jsonify({"history": get_history()})
    except Exception as e:
        logger.debug("Media history error: %s", e)
        return jsonify({"history": [], "error": safe_error(e)}), 502


# ── Music Vault Endpoints ────────────────────────────────────


MUSIC_EXTS = {".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac", ".wma"}
MUSIC_MIME = {
    ".mp3": "audio/mpeg",
    ".wav": "audio/wav",
    ".ogg": "audio/ogg",
    ".flac": "audio/flac",
    ".m4a": "audio/mp4",
    ".aac": "audio/aac",
    ".wma": "audio/x-ms-wma",
}


@bp.route("/api/media/music/upload", methods=["POST"])
@require_auth
def api_music_upload():
    """Upload a music file to the local music vault."""
    import uuid

    from familiar.skills.media.skill import _get_music_dir, add_to_music_library

    MAX_SIZE = 50 * 1024 * 1024  # 50 MB

    if "file" not in request.files:
        return jsonify({"error": "No file provided", "success": False}), 400

    file = request.files["file"]
    if not file.filename:
        return jsonify({"error": "No filename", "success": False}), 400

    ext = Path(file.filename).suffix.lower()
    if ext not in MUSIC_EXTS:
        return jsonify({"error": f"File type {ext} not supported", "success": False}), 400

    music_dir = _get_music_dir()
    track_id = str(uuid.uuid4())[:12]
    safe_name = re.sub(r"[^\w\-.]", "_", Path(file.filename).stem)[:50]
    dest = music_dir / f"{track_id}_{safe_name}{ext}"
    file.save(str(dest))

    size = dest.stat().st_size
    if size > MAX_SIZE:
        dest.unlink()
        return jsonify({"error": "File exceeds 50 MB limit", "success": False}), 400

    track = {
        "id": track_id,
        "filename": file.filename,
        "path": str(dest),
        "size": size,
        "ext": ext,
        "added_at": datetime.now().isoformat(),
    }
    add_to_music_library(track)

    return jsonify(
        {
            "success": True,
            "track_id": track_id,
            "filename": file.filename,
            "path": str(dest),
            "size": size,
        }
    )


@bp.route("/api/media/music/library")
@require_auth
def api_music_library():
    """List the music library, optionally filtering by search term."""
    from familiar.skills.media.skill import get_music_library

    search = request.args.get("search", "").strip() or None
    tracks = get_music_library(search=search)
    return jsonify({"tracks": tracks})


@bp.route("/api/media/music/stream/<track_id>")
@require_auth
def api_music_stream(track_id):
    """Stream a music file by track ID."""
    if not re.match(r"^[a-f0-9\-]{8,36}$", track_id):
        return jsonify({"error": "Invalid track ID"}), 400

    from familiar.skills.media.skill import get_music_library

    tracks = get_music_library()
    track = next((t for t in tracks if t.get("id") == track_id), None)
    if not track:
        return jsonify({"error": "Track not found"}), 404

    file_path = Path(track["path"])
    if not file_path.is_file():
        return jsonify({"error": "File not found on disk"}), 404

    mime = MUSIC_MIME.get(track.get("ext", ""), "application/octet-stream")
    return send_file(str(file_path), mimetype=mime)


@bp.route("/api/media/music/<track_id>", methods=["DELETE"])
@require_auth
def api_music_delete(track_id):
    """Delete a music track from the library and disk."""
    if not re.match(r"^[a-f0-9\-]{8,36}$", track_id):
        return jsonify({"error": "Invalid track ID"}), 400

    from familiar.skills.media.skill import remove_from_music_library

    removed = remove_from_music_library(track_id)
    if not removed:
        return jsonify({"error": "Track not found"}), 404
    return jsonify({"success": True})


# ── Gallery Vault Endpoints ───────────────────────────────────


