
import os
import glob
import shutil
import sqlite3

import xbmc
import xbmcvfs
import xbmcaddon
import xbmcgui

my_addon = xbmcaddon.Addon()
my_addon_name = my_addon.getAddonInfo('name')



def _format_size(size):
    if size >= 1048576:
        return '%.1f MB' % (size / 1048576.0)
    return '%.1f KB' % (size / 1024.0)


def _dir_size(path):
    total = 0
    for root, dirs, files in os.walk(path):
        for fn in files:
            try:
                total += os.path.getsize(os.path.join(root, fn))
            except OSError:
                pass
    return total


def _purge_db(db_file):
    """Wyczyść wszystkie tabele w bazie SQLite i zwolnij miejsce (VACUUM)."""
    conn = sqlite3.connect(db_file)
    try:
        cursor = conn.cursor()
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
        tables = [row[0] for row in cursor.fetchall()]
        for table in tables:
            cursor.execute('DELETE FROM "%s"' % table)
        conn.commit()
        cursor.execute('VACUUM')
    finally:
        conn.close()


def _clear_dir_contents(path, exclude=None):
    """Usuń zawartość folderu, zachowując sam folder."""
    for name in os.listdir(path):
        if exclude and name in exclude:
            continue
        full = os.path.join(path, name)
        if os.path.isdir(full):
            shutil.rmtree(full)
        else:
            os.remove(full)


def _delete_targets(targets, title):
    """Multiselect + potwierdzenie + usunięcie/czyszczenie wybranych elementów.

    Każdy target to krotka (name, path, kind, size) gdzie kind to:
      'file'  - usuń plik
      'dir'   - usuń katalog rekurencyjnie
      'db'    - wyczyść tabele SQLite + VACUUM
      'cache' - wyczyść zawartość katalogu (zachowaj commoncache.db)
    """
    labels = ['%s  [%s]' % (name, _format_size(sz)) for name, path, kind, sz in targets]

    selected = xbmcgui.Dialog().multiselect(title, labels)
    if selected is None or len(selected) == 0:
        return

    chosen = [targets[i] for i in selected]
    total = sum(sz for _, _, _, sz in chosen)
    names = ', '.join(name for name, _, _, _ in chosen)
    msg = 'Usunąć: %s\nŁącznie: %s\n\nKodi wymaga restartu!' % (names, _format_size(total))

    if not xbmcgui.Dialog().yesno("Potwierdzenie", msg):
        return

    errors = 0
    for name, path, kind, sz in chosen:
        try:
            if kind == 'db':
                _purge_db(path)
            elif kind == 'dir':
                shutil.rmtree(path)
            elif kind == 'cache':
                _clear_dir_contents(path, exclude={'commoncache.db'})
            else:
                os.remove(path)
        except Exception as e:
            print('###' + my_addon_name + ' - ERROR removing %s: %s' % (path, e))
            errors += 1

    if errors:
        xbmcgui.Dialog().ok(my_addon_name, "Wyczyszczono z błędami (%d nie usunięto).\nZrestartuj Kodi!" % errors)
    else:
        xbmcgui.Dialog().ok(my_addon_name, "Wyczyszczono pomyślnie!\nZrestartuj Kodi!")


def _find_orphaned_addon_data():
    """Znajdź foldery addon_data bez odpowiadającej zainstalowanej wtyczki."""
    addon_data_path = xbmcvfs.translatePath('special://profile/addon_data')
    addons_path = xbmcvfs.translatePath('special://home/addons')
    orphans = []
    if not os.path.isdir(addon_data_path):
        return orphans
    for name in os.listdir(addon_data_path):
        data_dir = os.path.join(addon_data_path, name)
        if not os.path.isdir(data_dir):
            continue
        if not os.path.isdir(os.path.join(addons_path, name)):
            sz = _dir_size(data_dir)
            if sz > 0:
                orphans.append((name, data_dir, 'dir', sz))
    orphans.sort(key=lambda x: x[3], reverse=True)
    return orphans



def clearCache():
    """Wyczyść pliki tymczasowe Kodi."""
    print('###' + my_addon_name + ' - CLEARING CACHE FILES###')
    targets = []
    for label, special in [('Cache', 'special://home/cache'), ('Temp', 'special://home/temp')]:
        path = xbmcvfs.translatePath(special)
        if os.path.isdir(path):
            sz = _dir_size(path)
            if sz > 0:
                targets.append((label, path, 'cache', sz))

    if not targets:
        xbmcgui.Dialog().ok(my_addon_name, "Nie znaleziono plików tymczasowych.")
        return

    _delete_targets(targets, "Wybierz lokalizacje do wyczyszczenia")


def eraseLogs():
    """Wyczyść logi awarii Kodi."""
    print('###' + my_addon_name + ' - DELETING CRASH LOGS###')
    log_path = xbmcvfs.translatePath('special://logpath')
    targets = []
    for f in glob.glob(os.path.join(log_path, 'xbmc_crashlog*.*')):
        try:
            sz = os.path.getsize(f)
        except OSError:
            continue
        if sz > 0:
            targets.append((os.path.basename(f), f, 'file', sz))

    if not targets:
        xbmcgui.Dialog().ok(my_addon_name, "Nie znaleziono logów awarii.")
        return

    targets.sort(key=lambda x: x[3], reverse=True)
    _delete_targets(targets, "Wybierz logi do usunięcia")


def deletePackages():
    """Wyczyść archiwum pobranych wtyczek."""
    print('###' + my_addon_name + ' - DELETING PACKAGES###')
    path = xbmcvfs.translatePath('special://home/addons/packages')
    if not os.path.isdir(path):
        xbmcgui.Dialog().ok(my_addon_name, "Nie znaleziono katalogu archiwum.")
        return

    targets = []
    for name in os.listdir(path):
        full = os.path.join(path, name)
        is_dir = os.path.isdir(full)
        try:
            sz = _dir_size(full) if is_dir else os.path.getsize(full)
        except OSError:
            continue
        if sz > 0:
            targets.append((name, full, 'dir' if is_dir else 'file', sz))

    if not targets:
        xbmcgui.Dialog().ok(my_addon_name, "Nie znaleziono plików archiwalnych.")
        return

    targets.sort(key=lambda x: x[3], reverse=True)
    _delete_targets(targets, "Wybierz pakiety do usunięcia")


def cleanKodiArtwork():
    """Wyczyść bazy i plakaty Kodi."""
    print('###' + my_addon_name + ' - CLEANING KODI ARTWORK CACHE###')
    db_path = xbmcvfs.translatePath('special://database')
    thumb_path = xbmcvfs.translatePath('special://thumbnails')

    targets = []

    addon_data = xbmcvfs.translatePath(my_addon.getAddonInfo('profile'))
    movies_db = os.path.join(addon_data, 'movies.db')
    if os.path.isfile(movies_db):
        targets.append(('Baza miniaturek Phantom', movies_db, 'db', os.path.getsize(movies_db)))

    for f in glob.glob(os.path.join(db_path, 'Textures*.db')):
        targets.append((os.path.basename(f), f, 'db', os.path.getsize(f)))

    for f in glob.glob(os.path.join(db_path, 'MyVideos*.db')):
        targets.append((os.path.basename(f), f, 'db', os.path.getsize(f)))

    if os.path.isdir(thumb_path):
        sz = _dir_size(thumb_path)
        if sz > 0:
            targets.append(('Thumbnails', thumb_path, 'dir', sz))

    if not targets:
        xbmcgui.Dialog().ok(my_addon_name, "Nie znaleziono plików do wyczyszczenia.")
        return

    _delete_targets(targets, "Wybierz zasoby do wyczyszczenia")


def cleanOrphanedAddons():
    """Wyczyść pozostałości po odinstalowanych wtyczkach."""
    print('###' + my_addon_name + ' - CLEANING ORPHANED ADDON DATA###')
    orphans = _find_orphaned_addon_data()

    if not orphans:
        xbmcgui.Dialog().ok(my_addon_name, "Brak pozostałości po odinstalowanych wtyczkach.")
        return

    total = sum(sz for _, _, _, sz in orphans)
    xbmcgui.Dialog().ok(
        "Pozostałości po wtyczkach",
        "Znaleziono %d folderów (%s) z danymi wtyczek,\n"
        "które nie są już zainstalowane w Kodi.\n"
        "Możesz je bezpiecznie usunąć." % (len(orphans), _format_size(total))
    )

    _delete_targets(orphans, "Wybierz pozostałości do usunięcia")
