# -*- coding: utf-8 -*-
"""Runtime conservador das contagens por categoria."""
import time

import xbmc

_MEM_CACHE = {}


def _log(ctx, message, level=xbmc.LOGDEBUG):
    fn = (ctx or {}).get('log_fn')
    if not fn:
        return
    try:
        fn(message, level)
    except TypeError:
        try:
            fn(message)
        except Exception:
            pass
    except Exception:
        pass


def category_count_scope_identity(ctx):
    try:
        base_url = ctx['get_base_url_fn']()
    except Exception:
        base_url = ''
    return ctx['storage_identity_from_values_fn'](base_url, ctx.get('username') or '')


def category_count_media_label(content_endpoint, total_count):
    endpoint = str(content_endpoint or '').strip().lower()
    try:
        total = int(total_count)
    except Exception:
        total = 0
    if endpoint == 'get_live_streams':
        return 'canal' if total == 1 else 'canais'
    if endpoint == 'get_series':
        return 'série' if total == 1 else 'séries'
    return 'conteúdo' if total == 1 else 'conteúdos'


def format_category_title_with_count(title, total_count):
    try:
        total = int(total_count)
    except Exception:
        return str(title or '').strip()
    return f"{str(title or '').strip()} ({total})"


def build_category_count_map_from_data(content_endpoint, data):
    endpoint = str(content_endpoint or '').strip().lower()
    if isinstance(data, list):
        rows = data
    elif isinstance(data, dict):
        rows = list(data.values())
    else:
        rows = []

    id_key = 'series_id' if endpoint == 'get_series' else 'stream_id'
    grouped_ids = {}
    for row in rows:
        if not isinstance(row, dict):
            continue
        category_id = str(row.get('category_id', '') or '').strip()
        item_id = str(row.get(id_key, '') or '').strip()
        if not category_id or not item_id:
            continue
        grouped_ids.setdefault(category_id, set()).add(item_id)
    return {cid: len(ids) for cid, ids in grouped_ids.items()}


def get_category_counts_for_endpoint(ctx, content_endpoint):
    endpoint = str(content_endpoint or '').strip().lower()
    if endpoint not in ('get_live_streams', 'get_vod_streams', 'get_series'):
        return {}

    now_ts = int(time.time())
    scope_identity = category_count_scope_identity(ctx)
    mem_key = f"{ctx['current_server_scope_identity_fn']()}|{scope_identity}|{endpoint}"
    mem_payload = _MEM_CACHE.get(mem_key)
    if isinstance(mem_payload, dict):
        try:
            fetched_at = int(mem_payload.get('fetched_at') or 0)
        except Exception:
            fetched_at = 0
        counts = mem_payload.get('counts') if isinstance(mem_payload.get('counts'), dict) else None
        if counts is not None and mem_payload.get('version') == ctx['cache_version'] and mem_payload.get('scope_identity') == scope_identity and fetched_at > 0 and (now_ts - fetched_at) <= ctx['cache_ttl']:
            return counts

    cache_path = ctx['category_counts_storage_path_fn'](endpoint)
    disk_payload = ctx['load_json_fn'](cache_path, {})
    if not isinstance(disk_payload, dict):
        disk_payload = {}
    disk_counts = disk_payload.get('counts') if isinstance(disk_payload.get('counts'), dict) else {}
    try:
        disk_fetched_at = int(disk_payload.get('fetched_at') or 0)
    except Exception:
        disk_fetched_at = 0

    if disk_counts and disk_payload.get('version') == ctx['cache_version'] and disk_payload.get('scope_identity') == scope_identity and disk_fetched_at > 0 and (now_ts - disk_fetched_at) <= ctx['cache_ttl']:
        _MEM_CACHE[mem_key] = disk_payload
        return disk_counts

    data, error_type, error_message = ctx['fetch_endpoint_fn'](endpoint)
    if data is None:
        if disk_counts:
            _MEM_CACHE[mem_key] = disk_payload
            _log(ctx, f'Contagem por categoria em cache reaproveitada para {endpoint} após falha de atualização: {error_type or error_message}', xbmc.LOGDEBUG)
            return disk_counts
        _log(ctx, f'Falha silenciosa ao atualizar contagem por categoria em {endpoint}: {error_type or error_message}', xbmc.LOGDEBUG)
        return {}

    counts = build_category_count_map_from_data(endpoint, data)
    payload = {
        'version': ctx['cache_version'],
        'endpoint': endpoint,
        'scope_identity': scope_identity,
        'fetched_at': now_ts,
        'counts': counts,
    }
    ctx['save_json_fn'](cache_path, payload)
    _MEM_CACHE[mem_key] = payload
    return counts
