import json
import urllib.request
import urllib.error
import xbmcaddon
import xbmcgui
import xbmc

from ai_prompts import (
    SYSTEM_PROMPT, SPORTS_ANALYSIS, CHANNEL_SEARCH,
    SPORTS_SCHEDULE, RECOMMENDATION, QUICK_QUESTION, GAME_INFO
)
from ai_cache import get_cached, set_cached, hash_prompt, track_usage, get_usage
from tools import debug_log

GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent"
# Available models:
# gemini-3-flash - free tier: 5 RPM, 20 RPD
# gemini-3.1-flash-lite - free tier: 15 RPM, 500 RPD
# gemini-3.5-flash - free tier: 5 RPM, 20 RPD

addon = xbmcaddon.Addon()


def _get_api_key():
    return addon.getSetting('gemini_api_key')


def _get_daily_limit():
    try:
        return int(addon.getSetting('ai_daily_limit') or '100')
    except ValueError:
        return 100


def _get_cache_ttl():
    try:
        return int(addon.getSetting('ai_cache_ttl') or '24') * 3600
    except ValueError:
        return 86400


def is_enabled():
    return addon.getSetting('ai_enabled') == 'true' and bool(_get_api_key())


def _call_gemini(prompt, system=None):
    api_key = _get_api_key()
    if not api_key:
        return None, "API key not configured"

    model = addon.getSetting('gemini_model') or 'gemini-3.1-flash-lite'
    search_enabled = addon.getSetting('ai_search_enabled') == 'true'
    if system is None:
        system = SYSTEM_PROMPT

    payload = {
        "contents": [
            {
                "parts": [
                    {"text": f"{system}\n\nUser: {prompt}"}
                ]
            }
        ],
        "generationConfig": {
            "temperature": 0.7,
            "maxOutputTokens": 200
        }
    }

    if search_enabled:
        payload["tools"] = [
            {
                "google_search": {}
            }
        ]

    url = GEMINI_API_URL.format(model=model) + f"?key={api_key}"
    data = json.dumps(payload).encode('utf-8')

    debug_log(f"AI Request: {url[:50]}... payload_size={len(data)}", xbmc.LOGINFO)

    req = urllib.request.Request(url, data=data, headers={
        'Content-Type': 'application/json'
    })

    try:
        with urllib.request.urlopen(req, timeout=30) as response:
            result = json.loads(response.read().decode('utf-8'))
            debug_log(f"AI Response keys: {list(result.keys())}", xbmc.LOGINFO)
            candidates = result.get('candidates', [])
            if candidates:
                parts = candidates[0].get('content', {}).get('parts', [])
                if parts:
                    text = parts[0].get('text', '').strip()
                    grounding = result.get('groundingMetadata', {})
                    if grounding:
                        debug_log(f"AI Grounding: {json.dumps(grounding)[:500]}", xbmc.LOGINFO)
                    return text, None
            return None, "No response from AI"
    except urllib.error.HTTPError as e:
        try:
            error_body = e.read().decode('utf-8')
        except Exception:
            error_body = str(e)
        debug_log(f"AI HTTP Error {e.code}: {error_body[:500]}", xbmc.LOGERROR)
        if e.code == 400:
            return None, f"Invalid request - check API key format"
        elif e.code == 403:
            return None, "API key invalid or Generative Language API not enabled"
        elif e.code == 429:
            if "limit: 0" in error_body:
                return None, "API key not configured for free tier. Delete key in AI Studio and create a new one."
            return None, f"Rate limited - wait a moment and try again"
        return None, f"API error: {e.code}"
    except urllib.error.URLError as e:
        debug_log(f"AI URL Error: {str(e)}", xbmc.LOGERROR)
        return None, "Network error - check connection"
    except Exception as e:
        debug_log(f"AI Error: {str(e)}", xbmc.LOGERROR)
        return None, f"Error: {str(e)}"


def ask(prompt, use_cache=True):
    if not is_enabled():
        return None, "AI not enabled or no API key"

    usage = get_usage()
    if usage.get('count', 0) >= _get_daily_limit():
        return None, f"Daily limit reached ({_get_daily_limit()})"

    prompt_hash = hash_prompt(prompt)

    if use_cache:
        cached = get_cached(prompt_hash, _get_cache_ttl())
        if cached:
            debug_log(f"AI Cache hit for: {prompt[:50]}...", xbmc.LOGINFO)
            return cached, None

    debug_log(f"AI Prompt: {prompt}", xbmc.LOGINFO)
    response, error = _call_gemini(prompt)
    if error:
        return None, error

    debug_log(f"AI Response: {response}", xbmc.LOGINFO)
    track_usage()
    if use_cache:
        set_cached(prompt_hash, response)

    return response, None


def analyze_game(game_data):
    prompt = SPORTS_ANALYSIS.format(
        team1=game_data.get('team1', 'Team 1'),
        team2=game_data.get('team2', 'Team 2'),
        status=game_data.get('status', 'Unknown'),
        score=game_data.get('score', 'N/A'),
        league=game_data.get('league', 'Unknown'),
        venue=game_data.get('venue', 'Unknown')
    )
    return ask(prompt)


def search_channels(query, channels):
    channel_list = "\n".join([
        f"- {ch.get('name', '')} ({ch.get('id', '')})"
        for ch in channels[:50]
    ])
    prompt = CHANNEL_SEARCH.format(
        query=query,
        channel_list=channel_list
    )
    return ask(prompt)


def get_recommendations(history, available_now, current_time=None):
    from datetime import datetime
    if current_time is None:
        current_time = datetime.now().strftime('%I:%M %p')

    history_text = "\n".join([f"- {h}" for h in history[:10]])
    available_text = "\n".join([f"- {a}" for a in available_now[:10]])

    prompt = RECOMMENDATION.format(
        history=history_text,
        current_time=current_time,
        available_now=available_text
    )
    return ask(prompt)


def get_game_info(game_data):
    prompt = GAME_INFO.format(
        game_title=game_data.get('title', 'Game'),
        league=game_data.get('league', 'Unknown'),
        teams=f"{game_data.get('team1', '')} vs {game_data.get('team2', '')}",
        time=game_data.get('time', 'Unknown'),
        channel=game_data.get('channel', 'Unknown')
    )
    return ask(prompt)


def quick_ask(question):
    prompt = QUICK_QUESTION.format(question=question)
    return ask(prompt)
