#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
onion_xml_builder.py  –  plugin.video.torproxy

Converte i dict prodotti da onion_parser.py in ListItem Kodi.
Si occupa anche di gestire i link $doregex inline nei file XML
caricati da hometor.xml o da qualsiasi file .onion.

TIPI ITEM E LORO ROUTING:
  browse / onion / http → onion_browse  (navigazione)
  submenu               → onion_submenu (carica XML remoto)
  play / stream         → onion_play    (riproduzione diretta)
  video / audio         → onion_play
  torrent               → onion_torrent (download .torrent)
  magnet                → aperto da Kodi direttamente
  image                 → onion_image   (visualizzatore)
  search                → onion_search  (ricerca nel sito)
  regex                 → onion_regex   (estrazione con pattern)
  custom                → onion_input   (URL manuale)
  doregex               → onion_doregex (esegue blocco regex inline)
"""

import re
import logging
from typing import List, Dict, Optional

log = logging.getLogger('onion_xml_builder')


# ── Import lazy per evitare import circolari ──────────────────────────
def _var():
    import variables as v
    return v

def _func():
    import functions as f
    return f

def _Item():
    from models import Item
    return Item

def _xbmcplugin():
    import xbmcplugin
    return xbmcplugin


# ======================================================================
# BUILDER PRINCIPALE
# ======================================================================

def build_listitem(entry: Dict, default_mode: str = 'onion_browse') -> None:
    """
    Crea e aggiunge un ListItem Kodi per un item del menu onion.
    Gestisce tutti i tipi definiti in onion_parser.py.
    """
    var   = _var()
    func  = _func()
    Item  = _Item()
    xbp   = _xbmcplugin()

    title  = entry.get('title', '')
    url    = entry.get('url', '').strip()
    thumb  = entry.get('thumb', '') or var.addon_icon
    fanart = entry.get('fanart', '') or var.addon_fanart
    plot   = entry.get('plot', '')
    itype  = entry.get('type', 'http').lower()

    if not title:
        return

    # ── Auto-detect magnet da URL anche se type non è impostato ──────
    if url.startswith('magnet:') and itype not in ('magnet',):
        itype = 'magnet'

    # ── Magnet: aperto direttamente da Kodi ───────────────────────────
    if itype == 'magnet':
        liz = var.list_item(title)
        liz.setArt({'thumb': thumb, 'icon': thumb, 'fanart': fanart})
        liz.setInfo('video', {'title': title, 'plot': plot})
        liz.setProperty('IsPlayable', 'true')
        xbp.addDirectoryItem(var.handle, url, liz, False)
        return

    # ── Torrent: scarica via Tor ──────────────────────────────────────
    if itype == 'torrent':
        func.create_listitem(Item(
            title=title, type='file', mode='onion_torrent',
            link=url, thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Elementum: fetcha dettaglio → estrae magnet → Elementum ──────
    if itype == 'elementum':
        func.create_listitem(Item(
            title=title, type='file', mode='onion_elementum',
            link=url, thumbnail=thumb, fanart=fanart,
            is_media=True,
        ))
        return

    # ── Media diretto: play ───────────────────────────────────────────
    if itype in ('play', 'stream', 'video', 'audio'):
        func.create_listitem(Item(
            title=title, type='file', mode='onion_play',
            link=url, thumbnail=thumb, fanart=fanart,
            is_media=True,
        ))
        return

    # ── Immagine ──────────────────────────────────────────────────────
    if itype == 'image':
        func.create_listitem(Item(
            title=title, type='file', mode='onion_image',
            link=url, thumbnail=thumb or url, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Sottomenu XML remoto ──────────────────────────────────────────
    if itype == 'submenu':
        ref = entry.get('submenu') or url
        func.create_listitem(Item(
            title=title, type='dir', mode='onion_submenu',
            link=ref, thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Link plugin:// interno Kodi ──────────────────────────────────
    if itype == 'plugin' or (url and url.startswith('plugin://')):
        import xbmcplugin as _xbp2
        liz2 = var.list_item(title)
        liz2.setArt({'thumb': thumb, 'icon': thumb, 'fanart': fanart})
        # Se è un URL di riproduzione (Elementum /play o simili)
        # isFolder=False + IsPlayable=true, altrimenti Kodi lo apre
        # come cartella invece di avviare il player.
        is_playable = '/play' in url or 'elementum' in url
        if is_playable:
            liz2.setProperty('IsPlayable', 'true')
        _xbp2.addDirectoryItem(var.handle, url, liz2, not is_playable)
        return

    # ── Blocco doregex inline ─────────────────────────────────────────
    if itype == 'doregex' or (url and url.startswith('$doregex[')):
        rname = ''
        m = re.search(r'\$doregex\[([^\]]+)\]', url)
        if m:
            rname = m.group(1)
        func.create_listitem(Item(
            title=title, type='dir', mode='onion_doregex',
            link=url,          # link contiene "$doregex[name]"
            title2=rname,      # title2 = nome del blocco regex
            thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Ricerca ───────────────────────────────────────────────────────
    if itype == 'search':
        sp = entry.get('search_param', 'q')
        sx = entry.get('search_path', '/search')
        func.create_listitem(Item(
            title=title, type='dir', mode='onion_search',
            link=url, title2=f'{sp}|||{sx}',
            thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Regex: estrazione con pattern ─────────────────────────────────
    if itype == 'regex':
        rx  = entry.get('regex', '')
        grp = entry.get('regex_group', '1')
        func.create_listitem(Item(
            title=title, type='dir', mode='onion_regex',
            link=url, title2=f'{rx}|||{grp}',
            thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── URL personalizzato ────────────────────────────────────────────
    if itype == 'custom' or url == 'CUSTOM':
        func.create_listitem(Item(
            title=title, type='dir', mode='onion_input',
            thumbnail=thumb, fanart=fanart,
            is_media=False,
        ))
        return

    # ── Link .onion / clearnet (default: browse) ──────────────────────
    func.create_listitem(Item(
        title=title, type='dir', mode=default_mode,
        link=url, thumbnail=thumb, fanart=fanart,
        is_media=False,
    ))


def build_listitems(entries: List[Dict], default_mode: str = 'onion_browse') -> None:
    """Crea ListItem per ogni entry nella lista."""
    for entry in entries:
        build_listitem(entry, default_mode)


def onion_elementum_play(detail_url: str) -> Optional[str]:
    """
    Fetcha la pagina dettaglio di un torrent su ilcorsaronero.link
    (o qualsiasi sito con magnet link nella pagina) ed estrae il magnet.
    Restituisce l'URL Elementum o None se non trovato.
    """
    import re
    from urllib.parse import quote

    if not detail_url:
        return None

    # Se è già un magnet, lo passa direttamente a Elementum
    if detail_url.startswith('magnet:'):
        return 'plugin://plugin.video.elementum/play?uri=' + quote(detail_url)

    try:
        import requests as _req
        resp = _req.get(
            detail_url, timeout=15,
            headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
        )
        html = resp.text
    except Exception as e:
        log.error('onion_elementum_play fetch fallito: %s', e)
        return None

    # 1. Cerca magnet completo nella pagina
    m = re.search(r'(magnet:\?xt=urn:btih:[^\s"\'<&]+)', html, re.IGNORECASE)
    if m:
        magnet = m.group(1).rstrip(')')
        log.info('Magnet trovato: %s...', magnet[:60])
        return 'plugin://plugin.video.elementum/play?uri=' + quote(magnet)

    # 2. Cerca solo l'hash btih (costruisce magnet minimale)
    h = re.search(r'[Hh]ash[:\s]*`?([0-9a-fA-F]{40})`?', html)
    if h:
        btih = h.group(1)
        # Estrae il titolo dall'<h1> per il dn= del magnet
        t = re.search(r'<h1[^>]*>\s*([^<]+)\s*</h1>', html)
        dn = quote(t.group(1).strip()) if t else 'torrent'
        magnet = f'magnet:?xt=urn:btih:{btih}&dn={dn}'
        log.info('Magnet da hash: %s', magnet[:80])
        return 'plugin://plugin.video.elementum/play?uri=' + quote(magnet)

    log.warning('Magnet non trovato in: %s', detail_url)
    return None


def items_to_dicts(entries) -> List[Dict]:
    """
    Normalizza una lista mista (dict, tuple, str) in lista di dict.
    Utile per uniformare i risultati di pyFunction e regex mode.
    """
    from onion_parser import _detect_url_type
    result = []
    for row in entries:
        if isinstance(row, dict):
            result.append(row)
        elif isinstance(row, (list, tuple)):
            params = [str(p) for p in row]
            t  = params[0] if len(params) > 0 else ''
            u  = params[1] if len(params) > 1 else ''
            th = params[2] if len(params) > 2 else ''
            if t and u:
                result.append({
                    'title': t,
                    'url'  : u,
                    'thumb': th,
                    'type' : _detect_url_type(u),
                    'plot' : '',
                })
        elif isinstance(row, str) and row:
            result.append({
                'title': row,
                'url'  : row,
                'thumb': '',
                'type' : _detect_url_type(row),
                'plot' : '',
            })
    return result
