
# -*- coding: utf-8 -*-
# Module: offline_movie
# Purpose: Seznam stažených filmů z dfolder včetně TMDb metadat + přehrání/mazání
# Author: mmirousek (modularizace)
# License: AGPL v3

import os
import re
import xbmc
import xbmcgui
import xbmcplugin
import xbmcaddon
import xbmcvfs
import urllib.parse
from resources.lib.database.metadata_db import db # 🚨 Import databáze
from resources.lib.utils.log_utils import get_logger

log = get_logger()

from datetime import datetime
from typing import Dict, Any, List, Tuple
import json

from urllib.parse import urlencode
from resources.lib.tmdb.tmdb_utils import search_tmdb_movie, get_movie_meta
from resources.lib.tmdb.tmdb_kodi import set_video_info

ADDON_ID = 'plugin.video.mmirousek_v3'
ADDON = xbmcaddon.Addon(ADDON_ID)
IMAGE_BASE_URL = 'https://image.tmdb.org/t/p/w500' 
FANART_BASE_URL = 'https://image.tmdb.org/t/p/original' 


# Pevná základní URL pluginu – aby kontextové akce měly vždy platný cíl
PLUGIN_BASE = f"plugin://{ADDON_ID}"

# Přípustné filmové přípony
MOVIE_EXTS = {'.mkv', '.mp4', '.avi', '.mov', '.m4v', '.mpg', '.mpeg', '.ts', '.m2ts', '.webm'}

MIME_MAP = {
    '.mkv': 'video/x-matroska',
    '.mp4': 'video/mp4',
    '.avi': 'video/x-msvideo',
    '.m4v': 'video/mp4',
    '.ts': 'video/MP2T',
    '.mov': 'video/quicktime',
    '.webm': 'video/webm',
}

def _build_url(**kwargs) -> str:
    """
    Sestaví správné plugin URL: plugin://plugin.video.mmirousek_v3?... (RunPlugin očekává platný PluginPath).
    """
    try:
        return f"{PLUGIN_BASE}?{urlencode(kwargs, encoding='utf-8')}"
    except Exception:
        # Fallback bez explicitního encodingu (starší buildy Pythonu v Kodi)
        return f"{PLUGIN_BASE}?{urlencode(kwargs)}"

def _listdir_files(root: str) -> list:
    """Vrátí absolutní cesty k souborům v kořenu složky – plně kompatibilní se SMB/NFS."""
    if not root or not xbmcvfs.exists(root):
        return []
    try:
        dirs, files = xbmcvfs.listdir(root)
        # Zajistíme správné složení cesty i pro smb:// a nfs://
        return [root.rstrip('/\\') + '/' + f for f in files]
    except Exception as e:
        log.error(f"_listdir_files error: {root} → {e}")
        return []
    
def _nice_title(meta: dict, fallback_name: str) -> str:
    """Title (Year), jinak fallback na filename bez přípony."""
    t = (meta or {}).get('title') or ''
    y = (meta or {}).get('year')
    if t and isinstance(y, int):
        return f"{t} ({y})"
    if t:
        return t
    return os.path.splitext(fallback_name)[0]

def _plot(meta: dict, fallback_name: str) -> str:
    p = (meta or {}).get('overview') or ''
    return p if p else f"Lokální soubor: {fallback_name}"

def _genres(meta: dict) -> str:
    g = (meta or {}).get('genres') or []
    try:
        return ", ".join([s for s in g if isinstance(s, str)]) if g else ""
    except Exception:
        return ""

def _poster(meta: dict) -> str:
    return (meta or {}).get('poster_url') or ''

def _fanart(meta: dict) -> str:
    return (meta or {}).get('backdrop_url') or ''


# ------------------------------------------------------------
# Veřejné funkce volané z routeru (sm3_entry.py → ACTIONS)
# ------------------------------------------------------------


def show_downloaded_movies(handle: int) -> None:
    """Zobrazí stažené filmy z nastavené dfolder – nyní funguje i na síťových discích."""
    xbmcplugin.setPluginCategory(handle, "Stažené filmy")
    dfolder = ADDON.getSetting('dfolder') or ''
    if not dfolder:
        xbmcgui.Dialog().notification("Stažené filmy", "Nenastavena složka pro stahování.", xbmcgui.NOTIFICATION_WARNING, 3000)
        xbmcplugin.endOfDirectory(handle, succeeded=False)
        return

    dest_real = xbmcvfs.translatePath(dfolder)
    if not dest_real:
        xbmcgui.Dialog().notification("Stažené filmy", "Chyba při získání cesty.", xbmcgui.NOTIFICATION_ERROR, 3000)
        xbmcplugin.endOfDirectory(handle, succeeded=False)
        return

    # Zajistíme trailing slash
    if not dest_real.endswith(('/', '\\')):
        dest_real += '/'

    # Kontrola existence přes xbmcvfs (funguje i na SMB/NFS)
    if not xbmcvfs.exists(dest_real):
        xbmcgui.Dialog().notification("Stažené filmy", "Cílová složka neexistuje nebo není dostupná.", xbmcgui.NOTIFICATION_ERROR, 4000)
        xbmcplugin.endOfDirectory(handle, succeeded=False)
        return

    files = [f for f in _listdir_files(dest_real) if os.path.splitext(f)[1].lower() in MOVIE_EXTS]
    if not files:
        xbmcgui.Dialog().notification("Stažené filmy", "Žádné stažené filmy.", xbmcgui.NOTIFICATION_INFO, 2500)
        xbmcplugin.endOfDirectory(handle, succeeded=True)
        return

    # Pokud je složka velká, přeskočíme TMDb lookup
    skip_tmdb = len(files) > 50

    for fpath in sorted(files, key=lambda p: os.path.basename(p).lower()):
        fname = os.path.basename(fpath)
        title = os.path.splitext(fname)[0]
        plot = f"Lokální soubor: {fname}"
        art = {}

        if not skip_tmdb:
            try:
                basic = search_tmdb_movie(fname)
                if basic:
                    title = basic.get('title') or title
                    plot = basic.get('overview') or plot
                    poster = basic.get('poster_path')
                    if poster:
                        art['poster'] = f"https://image.tmdb.org/t/p/w500{poster}"
                        art['thumb'] = art['poster']
                        art['icon'] = art['poster']
            except Exception as e:
                log.warning(f"TMDb lookup error for {fname}: {e}")

        li = xbmcgui.ListItem(label=title)
        tag = li.getVideoInfoTag()
        tag.setTitle(title)
        if plot:
            tag.setPlot(plot)
        tag.setMediaType('movie')
        if art:
            li.setArt(art)
        li.setProperty('IsPlayable', 'true')

        # Kontextové menu
        from resources.lib.utils.context_builder import build_context_menu
        item_data = {
            'file_path': fpath,
            'folder_path': os.path.dirname(fpath)
        }
        ctx = build_context_menu(_build_url, item_data, contexts=['offline_movie_item'])
        if ctx:
            li.addContextMenuItems(ctx, replaceItems=True)

        xbmcplugin.addDirectoryItem(handle, fpath, li, isFolder=False)

    xbmcplugin.endOfDirectory(handle)

def delete_downloaded_file(path: str) -> None:
    """Bezpečné mazání souboru – funguje i na SMB/NFS."""
    try:
        # path už přichází jako plná VFS cesta (smb:// nebo lokální)
        if xbmcvfs.exists(path):
            xbmcvfs.delete(path)
            xbmcgui.Dialog().notification("Stažené filmy", "Soubor smazán.", xbmcgui.NOTIFICATION_INFO, 2500)
        else:
            xbmcgui.Dialog().notification("Stažené filmy", "Soubor nenalezen.", xbmcgui.NOTIFICATION_WARNING, 2500)
    except Exception as e:
        log.error(f"Chyba při mazání {path}: {e}")
        xbmcgui.Dialog().notification("Stažené filmy", "Chyba při mazání souboru.", xbmcgui.NOTIFICATION_ERROR, 3000)
    finally:
        xbmc.executebuiltin("Container.Refresh")


def show_folder(handle: int, path: str) -> None:
    """
    Univerzální náhled obsahu složky (VFS i lokální).
    - Používá xbmcvfs.listdir() a xbmcvfs.exists() => funguje pro smb://, nfs:// i lokál.
    - Skládá cesty ručně (path + '/' + name), aby zůstala VFS semantika.
    """
    try:
        # Normalizace a trailing slash pro VFS kompatibilitu
        folder = path or ''
        if not folder:
            xbmcgui.Dialog().notification("Složka", "Neplatná cesta.", xbmcgui.NOTIFICATION_WARNING, 2500)
            return

        # xbmcvfs: kontrola existence (funguje na VFS i lokálu)
        if not xbmcvfs.exists(folder):
            xbmcgui.Dialog().notification("Složka", "Složka neexistuje nebo není dostupná.", xbmcgui.NOTIFICATION_WARNING, 2500)
            return

        # Zajisti trailing slash (pro správné skládání child cest)
        if not folder.endswith(('/', '\\')):
            folder += '/'

        xbmcplugin.setPluginCategory(handle, os.path.basename(folder.rstrip('/\\')) or "Složka")

        # Listování přes xbmcvfs (vrací 2 seznamy: dirs, files)
        try:
            dirs, files = xbmcvfs.listdir(folder)
        except Exception as e:
            log.error(f"show_folder listdir error: {folder} → {e}")
            xbmcgui.Dialog().notification("Složka", "Chyba při listování.", xbmcgui.NOTIFICATION_ERROR, 2500)
            xbmcplugin.endOfDirectory(handle, succeeded=False)
            return

        # Seřaď abecedně (složky pak soubory)
        dirs = sorted(dirs, key=lambda s: s.lower())
        files = sorted(files, key=lambda s: s.lower())

        # 1) Složky
        for dname in dirs:
            child = folder + dname  # VFS-safe
            li = xbmcgui.ListItem(label=dname)
            li.setArt({'icon': 'DefaultFolder.png'})
            # Rekurzivní odkaz na sebe sama
            xbmcplugin.addDirectoryItem(
                handle,
                _build_url(action='show_folder', path=child),
                li,
                isFolder=True
            )

        # 2) Soubory (přímé přehrání)
        for fname in files:
            fpath = folder + fname  # VFS-safe
            li = xbmcgui.ListItem(label=fname)
            li.setProperty('IsPlayable', 'true')
            # Volitelné: můžeš přidat thumb podle přípony, ale není to nutné
            xbmcplugin.addDirectoryItem(
                handle,
                fpath,
                li,
                isFolder=False
            )

        xbmcplugin.endOfDirectory(handle)

    except Exception as e:
        log.error(f"show_folder fatal error: {e}")
        xbmcgui.Dialog().notification("Složka", "Neočekávaná chyba.", xbmcgui.NOTIFICATION_ERROR, 2500)

def list_watchlist_items(get_url_fn, handle, addon, params: Dict[str, Any]):
    """
    Vypíše filmy z lokální DB, které mají nastaven příznak 'ws_watchlist_ts'.
    Položky jsou řazeny sestupně (nejnovější nahoře).
    
    Argumenty:
        get_url_fn: Funkce pro generování URL pro Kodi.
        handle: Int handler doplňku.
        addon: Objekt doplňku.
        params: Slovník parametrů předaných z routeru.
    """
    
    # 1. Nastavení kategorie a získání typu
    media_type = params.get('type', 'movie')
    addon_name = addon.getAddonInfo('name')
    
    xbmcplugin.setPluginCategory(handle, "Sledovat později (Webshare)")

    try:
        # Načtení dat z DB: Hledáme záznamy typu 'movie', kde ws_watchlist_ts NENÍ NULL
        sql = f"""
            SELECT * FROM media 
            WHERE media_type = ? AND ws_watchlist_ts IS NOT NULL
            ORDER BY ws_watchlist_ts DESC
        """
        # Používáme with db.conn:, aby se zajistila aktuálnost dat
        with db.conn:
            cursor = db.conn.execute(sql, (media_type,))
            
            # Získání názvů sloupců a sestavení slovníků
            cols = [col[0] for col in cursor.description]
            items = [dict(zip(cols, row)) for row in cursor.fetchall()]
        
        # Ošetření prázdného seznamu
        if not items:
            li = xbmcgui.ListItem("Seznam je prázdný.")
            li.setLabel2("Filmy lze přidat přes kontextové menu.")
            xbmcplugin.addDirectoryItem(
                handle, 
                get_url_fn(action=''), 
                li, 
                isFolder=False
            )
            xbmcplugin.endOfDirectory(handle)
            return

        # 2. Vytvoření ListItem pro každou položku
        list_items: List[Tuple[str, xbmcgui.ListItem, bool]] = []

        for item in items:
            tmdb_id = item['tmdb_id']

            # --- 0) Načtení názvů a roku ---
            title_cs   = (item.get('title_cs') or '').strip()
            title_en   = (item.get('title_en') or '').strip()
            title_orig = (item.get('title_original') or '').strip()
            year       = item.get('year')

            # --- 1) CZ / EN titul (s rokem) ---
            if title_cs and title_en and title_cs.lower() != title_en.lower():
                base_title = f"{title_cs} / {title_en}"
            elif title_cs:
                base_title = title_cs
            elif title_en:
                base_title = title_en
            elif title_orig:
                base_title = title_orig
            else:
                base_title = f"Neznámý film ID {tmdb_id}"

            label_title = f"{base_title} ({year})" if isinstance(year, int) else base_title

            # --- 2) Čas přidání do Watchlistu (added_date) ---
            timestamp = item.get('ws_watchlist_ts')  # může být None
            if isinstance(timestamp, (int, float)) and timestamp > 0:
                added_date = datetime.fromtimestamp(timestamp).strftime('%Y-%m-%d %H:%M:%S')
            else:
                added_date = ""

            # --- 3) ListItem a základní info ---
            li = xbmcgui.ListItem(label=label_title)
            li.setLabel2(f"Přidáno: {added_date}" if added_date else "Přidáno: —")

            info = {
                'title': label_title,
                'year': year,
                'plot': item.get('overview_cs') or item.get('overview_en') or "Položka v seznamu 'Sledovat později'.",
                'mediatype': 'movie',
                'rating': item.get('vote_average'),
                'premiered': added_date or ''
            }
            set_video_info(li, info)

            # --- 4) Artwork ---
            if item.get('poster_path'):
                p = str(item['poster_path']).strip()
                li.setArt({
                    'icon':   IMAGE_BASE_URL + p,
                    'thumb':  IMAGE_BASE_URL + p,
                    'poster': IMAGE_BASE_URL + p
                })
            if item.get('backdrop_path'):
                b = str(item['backdrop_path']).strip()
                li.setArt({'fanart': FANART_BASE_URL + b})

            # --- 5) Kontextové menu: Odebrat z Watchlistu ---
            from resources.lib.utils.context_builder import build_context_menu
            item_data = {'tmdb_id': tmdb_id}
            ctx = build_context_menu(get_url_fn, item_data, contexts=['webshare_watchlist_remove'])
            if ctx:
                li.addContextMenuItems(ctx, replaceItems=True)

            # --- 6) Akce při kliknutí: přechod do centrálního search ---
            cz_title  = title_cs
            eng_title = title_en
            year_val  = year if isinstance(year, int) else ''

            play_url = get_url_fn(
                action='show_search_dialog',
                cz_title=cz_title,
                eng_title=eng_title,
                year=str(year_val) if year_val != '' else '',
                tmdb_id=str(tmdb_id),
                mediatype='movie',
                return_after_play_url=xbmc.getInfoLabel('Container.FolderPath') or '',
            )
            
            list_items.append((play_url, li, True)) # isFolder=True pro list_sources

        xbmcplugin.addDirectoryItems(handle, list_items, len(list_items))

    except Exception as e:
        log.error(f"CHYBA při listování watchlistu: {e}")
        xbmcgui.Dialog().notification(addon_name, "Chyba při načítání Watchlistu.", xbmcgui.NOTIFICATION_ERROR)

    xbmcplugin.endOfDirectory(handle)
