# -*- coding: utf-8 -*-
# RD Tools - ZIP Utilities (Speed + ETA)
# ---------------------------------------------------------------

import os
import time
import zipfile
import urllib.request
import xbmcgui
import xbmcvfs
from urllib.parse import urlsplit, unquote
from modules import utils

CHUNK_SIZE = 1024 * 128


# =============================================================================
# EXTRACT ZIP
# =============================================================================

def extract_zip():
    src_zip = utils.browse_file_device_fs("Select ZIP file to extract (device filesystem)")
    if not src_zip: return
    dst_folder = utils.browse_folder_kodi_root("Select destination folder (Kodi root)")
    if not dst_folder: return

    dp = xbmcgui.DialogProgressBG()
    dp.create("Extracting ZIP", os.path.basename(src_zip))

    try:
        start_time = time.time()
        with zipfile.ZipFile(xbmcvfs.translatePath(src_zip), 'r') as zf:
            file_list = zf.namelist()
            total = len(file_list)
            total_bytes = sum((info.file_size for info in zf.infolist()))
            extracted_bytes = 0

            for i, member in enumerate(file_list, 1):
                info = zf.getinfo(member)
                zf.extract(member, xbmcvfs.translatePath(dst_folder))
                extracted_bytes += info.file_size
                utils.progress_speed_eta(dp, i, total, extracted_bytes, total_bytes, start_time, member, "Extracting")

        dp.close()
        utils.notify("Extract Complete", f"Extracted {total} files.")
    except Exception as e:
        dp.close()
        xbmcgui.Dialog().ok("Extract Failed", str(e))


# =============================================================================
# ZIP DIRECTORY
# =============================================================================

def zip_directory():
    src_folder = utils.browse_folder_kodi_root("Select directory to zip (Kodi root)")
    if not src_folder: return
    dst_folder = utils.browse_folder_device_fs("Select destination folder (device filesystem)")
    if not dst_folder: return

    zip_name = os.path.basename(src_folder.rstrip('/')) + ".zip"
    dst_zip = utils.join_path(dst_folder, zip_name)

    dp = xbmcgui.DialogProgressBG()
    dp.create("Creating ZIP", zip_name)

    try:
        start_time = time.time()
        all_files, total_bytes = [], 0
        for root, dirs, files in os.walk(xbmcvfs.translatePath(src_folder)):
            for f in files:
                abs_path = os.path.join(root, f)
                size = os.path.getsize(abs_path)
                rel_path = os.path.relpath(abs_path, xbmcvfs.translatePath(src_folder))
                all_files.append((abs_path, rel_path, size))
                total_bytes += size

        total = len(all_files)
        written_bytes = 0

        with zipfile.ZipFile(xbmcvfs.translatePath(dst_zip), 'w', zipfile.ZIP_DEFLATED) as zf:
            for i, (abs_path, rel_path, size) in enumerate(all_files, 1):
                zf.write(abs_path, rel_path)
                written_bytes += size
                utils.progress_speed_eta(dp, i, total, written_bytes, total_bytes, start_time, rel_path, "Zipping")

        dp.close()
        utils.notify("ZIP Complete", f"Created {zip_name}")
    except Exception as e:
        dp.close()
        xbmcgui.Dialog().ok("ZIP Failed", str(e))


# =============================================================================
# DOWNLOAD ZIP
# =============================================================================

def download_zip_from_url():
    url = xbmcgui.Dialog().input("Enter ZIP URL (http/https)")
    if not url: return
    dst_folder = utils.browse_folder_device_fs("Select destination folder (device filesystem)")
    if not dst_folder: return

    fname = unquote(os.path.basename(urlsplit(url).path)) or "download.zip"
    dst_path = utils.join_path(dst_folder, fname)

    dp = xbmcgui.DialogProgressBG()
    dp.create("Downloading ZIP", fname)

    try:
        req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
        with urllib.request.urlopen(req, timeout=45) as resp:
            total_size = int(resp.getheader("Content-Length", "0"))
            bytes_read = 0
            start_time = time.time()

            with xbmcvfs.File(dst_path, 'wb') as out_f:
                while True:
                    chunk = resp.read(CHUNK_SIZE)
                    if not chunk:
                        break
                    out_f.write(chunk)
                    bytes_read += len(chunk)
                    utils.progress_speed_eta(dp, bytes_read, total_size, bytes_read, total_size, start_time, f"{bytes_read/1024/1024:.1f} MB", "Downloading")

        dp.close()
        utils.notify("Download Complete", f"Saved {fname}")
    except Exception as e:
        dp.close()
        xbmcgui.Dialog().ok("Download Failed", str(e))


# =============================================================================
# MENU
# =============================================================================

def zip_menu():
    options = [
        "📦 Extract ZIP (device fs → Kodi root)",
        "🗜️  Zip Directory (Kodi root → device fs)",
        "🌐 Download ZIP from URL",
        "⬅️ Back"
    ]
    while True:
        sel = xbmcgui.Dialog().select("ZIP Tools", options)
        if sel == -1 or sel == 3:
            break
        elif sel == 0:
            extract_zip()
        elif sel == 1:
            zip_directory()
        elif sel == 2:
            download_zip_from_url()
