"""
Sonarr integration routes for Ohm Stream Downloader API.
"""

import logging
from typing import Optional

from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query
from fastapi.requests import Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel

from app.models import DownloadRequest
from app.models.auth import User
from app.models.sonarr import SonarrConfig, SonarrDownloadRequest, SonarrMapping
from app.routers.router_auth import get_current_user_from_token

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api", tags=["sonarr"])


def get_sonarr_handler():
    from app.sonarr_handler import get_sonarr_handler

    return get_sonarr_handler()


@router.post("/webhook/sonarr")
async def sonarr_webhook(request: Request):
    """Receive and process Sonarr webhook events"""
    from app.models.sonarr import SonarrWebhookPayload

    sonarr_handler = get_sonarr_handler()

    body = await request.body()
    signature = request.headers.get("X-Sonarr-Event", "")
    if not sonarr_handler.verify_hmac(body, signature):
        logger.warning("Invalid HMAC signature for Sonarr webhook")
        raise HTTPException(status_code=403, detail="Invalid signature")

    try:
        payload_data = await request.json()
        payload = SonarrWebhookPayload(**payload_data)
        result = await sonarr_handler.process_webhook(payload)
        return JSONResponse(content=result, status_code=200)
    except Exception as e:
        logger.error(f"Error processing Sonarr webhook: {e}", exc_info=True)
        raise HTTPException(status_code=422, detail=f"Invalid payload: {str(e)}")


@router.post("/webhook/test/sonarr")
async def test_sonarr_webhook(request: Request):
    """Test endpoint for Sonarr webhook configuration"""
    try:
        payload = await request.json()
        logger.info(
            f"Received test Sonarr webhook: {payload.get('eventType', 'unknown')}"
        )
        return {
            "status": "ok",
            "message": "Test webhook received successfully",
            "received_payload": payload,
        }
    except Exception as e:
        logger.error(f"Error in test webhook: {e}")
        return {"status": "error", "message": str(e)}


@router.get("/sonarr/config")
async def get_sonarr_config(
    current_user: User = Depends(get_current_user_from_token),
):
    """Get Sonarr webhook configuration"""
    sonarr_handler = get_sonarr_handler()
    return sonarr_handler.get_config()


@router.put("/sonarr/config")
async def update_sonarr_config(
    config: SonarrConfig,
    current_user: User = Depends(get_current_user_from_token),
):
    """Update Sonarr webhook configuration"""
    sonarr_handler = get_sonarr_handler()
    try:
        updated_config = sonarr_handler.update_config(config)
        return {"status": "success", "config": updated_config}
    except Exception as e:
        logger.error(f"Error updating Sonarr config: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/sonarr/mappings")
async def get_sonarr_mappings(
    current_user: User = Depends(get_current_user_from_token),
):
    """Get all Sonarr to anime mappings"""
    sonarr_handler = get_sonarr_handler()
    return sonarr_handler.get_mappings()


@router.get("/sonarr/mappings/{series_id}")
async def get_sonarr_mapping(
    series_id: int,
    current_user: User = Depends(get_current_user_from_token),
):
    """Get specific mapping by Sonarr series ID"""
    sonarr_handler = get_sonarr_handler()
    mapping = sonarr_handler.get_mapping(series_id)
    if not mapping:
        raise HTTPException(status_code=404, detail="Mapping not found")
    return mapping


@router.post("/sonarr/mappings")
async def create_sonarr_mapping(
    mapping: SonarrMapping,
    current_user: User = Depends(get_current_user_from_token),
):
    """Create or update a Sonarr to anime mapping"""
    sonarr_handler = get_sonarr_handler()
    try:
        mapping = sonarr_handler.add_mapping(mapping)
        return {"status": "success", "mapping": mapping}
    except Exception as e:
        logger.error(f"Error creating mapping: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/sonarr/mappings/{series_id}")
async def delete_sonarr_mapping(
    series_id: int,
    current_user: User = Depends(get_current_user_from_token),
):
    """Delete a Sonarr mapping"""
    sonarr_handler = get_sonarr_handler()
    success = sonarr_handler.delete_mapping(series_id)
    if not success:
        raise HTTPException(status_code=404, detail="Mapping not found")
    return {"status": "success", "message": f"Mapping for series {series_id} deleted"}


@router.get("/sonarr/search")
async def search_anime_for_sonarr(
    q: str = Query(..., description="Series title to search"),
    provider: str = Query("anime-sama", description="Anime provider to search"),
    lang: str = Query("vostfr", description="Language (vostfr, vf)"),
    current_user: User = Depends(get_current_user_from_token),
):
    """Search for anime on providers to create Sonarr mappings"""
    sonarr_handler = get_sonarr_handler()
    try:
        results = await sonarr_handler.search_anime_by_title(q, provider, lang)
        return {
            "status": "success",
            "query": q,
            "provider": provider,
            "lang": lang,
            "results": results,
        }
    except Exception as e:
        logger.error(f"Error searching anime: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/sonarr/episodes")
async def get_anime_episodes(
    url: str = Query(..., description="Anime URL from provider"),
    provider: str = Query("anime-sama", description="Anime provider"),
    lang: str = Query("vostfr", description="Language (vostfr, vf)"),
    current_user: User = Depends(get_current_user_from_token),
):
    """Get episode list for anime"""
    sonarr_handler = get_sonarr_handler()
    try:
        episodes = await sonarr_handler.get_episodes_for_anime(url, provider, lang)
        return {
            "status": "success",
            "url": url,
            "provider": provider,
            "lang": lang,
            "episodes": episodes,
        }
    except Exception as e:
        logger.error(f"Error getting episodes: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/sonarr/suggest")
async def suggest_anime_mapping(
    sonarr_title: str = Query(..., description="Sonarr series title"),
    provider: str = Query("anime-sama", description="Anime provider"),
    lang: str = Query("vostfr", description="Language"),
    current_user: User = Depends(get_current_user_from_token),
):
    """Suggest possible anime mappings based on Sonarr series title"""
    sonarr_handler = get_sonarr_handler()
    try:
        suggestions = await sonarr_handler.suggest_mapping(sonarr_title, provider, lang)
        return {
            "status": "success",
            "sonarr_title": sonarr_title,
            "provider": provider,
            "lang": lang,
            "suggestions": suggestions,
        }
    except Exception as e:
        logger.error(f"Error getting suggestions: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sonarr/download")
async def trigger_sonarr_download(
    request: SonarrDownloadRequest,
    background_tasks: BackgroundTasks,
    current_user: User = Depends(get_current_user_from_token),
):
    """Manually trigger a download based on Sonarr information"""
    from main import download_manager

    sonarr_handler = get_sonarr_handler()

    mapping = sonarr_handler.get_mapping(request.sonarr_series_id)
    if not mapping:
        raise HTTPException(
            status_code=404,
            detail=f"No mapping found for series {request.sonarr_series_id}. Create a mapping first.",
        )

    try:
        episodes = await sonarr_handler.get_episodes_for_anime(
            mapping.anime_url,
            request.provider or mapping.anime_provider,
            request.lang or mapping.lang,
        )

        target_episode = None
        for ep in episodes:
            ep_num = ep.get("episode", 0)
            season_num = ep.get("season", 1)
            if ep_num == request.episode_number and season_num == request.season_number:
                target_episode = ep
                break

        if not target_episode:
            raise HTTPException(
                status_code=404,
                detail=f"Episode S{request.season_number}E{request.episode_number} not found",
            )

        episode_url = target_episode.get("url")
        if not episode_url:
            raise HTTPException(status_code=400, detail="Episode URL not found")

        download_request = DownloadRequest(
            url=episode_url,
            filename=f"{mapping.anime_title} - S{request.season_number}E{request.episode_number}.mp4",
        )

        task = download_manager.create_task(download_request)
        background_tasks.add_task(download_manager.start_download, task.id)

        return {
            "status": "success",
            "task_id": task.id,
            "message": f"Download started for {mapping.anime_title} S{request.season_number}E{request.episode_number}",
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error triggering download: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))
