"""
This module defines centralized constants used across the YTSage application.
By storing shared values in one place, it improves consistency, readability,
and maintainability of the codebase.

Constants include:
- Asset paths for icons and notification sounds.
- OS detection and platform-specific directory paths for application data, binaries, logs, and configuration.
- Download URLs for yt-dlp and ffmpeg binaries.
- SUBPROCESS_CREATIONFLAGS: Used to specify subprocess creation flags (e.g., subprocess.CREATE_NO_WINDOW on Windows to hide the console window).
Directories are automatically created when the module is imported, ensuring the required structure exists for the application.
YTSage application constants.

"""

import os
import platform
import subprocess
import sys
from pathlib import Path

# Handle resource paths for both development and installed package
def get_asset_path(asset_relative_path: str) -> Path:
    """
    Get the absolute path to an asset file, works both in development and installed package.
    
    Args:
        asset_relative_path: Relative path to the asset (e.g., "assets/Icon/icon.png")
    
    Returns:
        Path: Absolute path to the asset file
    """
    # Check if running as a frozen executable (PyInstaller, cx_Freeze, etc.)
    if getattr(sys, "frozen", False):
        # Running as a frozen executable
        # Try sys._MEIPASS first (PyInstaller)
        if hasattr(sys, "_MEIPASS"):
            asset_path = Path(sys._MEIPASS) / asset_relative_path
            if asset_path.exists():
                return asset_path
        
        # For cx_Freeze, assets are typically in lib/ directory next to the executable
        executable_dir = Path(sys.executable).parent
        
        # Try with lib/ prefix (cx_Freeze standard structure)
        asset_path = executable_dir / "lib" / asset_relative_path
        if asset_path.exists():
            return asset_path
        
        # Try directly in executable directory
        asset_path = executable_dir / asset_relative_path
        if asset_path.exists():
            return asset_path
    
    # Not frozen - try importlib.resources for installed packages
    try:
        # Use importlib.resources (standard in Python 3.9+)
        import importlib.resources as resources
        try:
            # Navigate to the package root and then to the asset
            package_path = resources.files('ytsage')
            asset_path = package_path / asset_relative_path
            if asset_path.is_file():
                return Path(str(asset_path))
        except (ImportError, AttributeError, FileNotFoundError):
            pass
            
    except Exception:
        pass
    
    # Fallback to relative path (for development environment)
    current_file = Path(__file__)
    # Go up from src/utils to ytsage root, then to asset
    ytsage_root = current_file.parent.parent.parent
    asset_path = ytsage_root / asset_relative_path
    
    return asset_path

# Assets Constants
ICON_PATH: Path = get_asset_path("assets/Icon/icon.png")
SOUND_PATH: Path = get_asset_path("assets/sound/notification.mp3")

OS_NAME: str = platform.system()  # Windows ; Darwin ; Linux

IS_FROZEN = getattr(sys, "frozen", False)
USER_HOME_DIR: Path = Path.home()

# OS Specific Constants
if OS_NAME == "Windows":
    OS_FULL_NAME: str = f"{OS_NAME} {platform.release()}"

    # Always use user data directory for app data, logs, config, and binaries
    # Even when frozen, we don't want to create these folders next to the executable
    APP_DIR: Path = Path(os.environ.get("LOCALAPPDATA", USER_HOME_DIR / "AppData" / "Local")) / "YTSage"
    APP_BIN_DIR: Path = APP_DIR / "bin"
    APP_DATA_DIR: Path = APP_DIR / "data"
    APP_LOG_DIR: Path = APP_DIR / "logs"
    APP_CONFIG_FILE: Path = APP_DATA_DIR / "ytsage_config.json"
    APP_HISTORY_FILE: Path = APP_DATA_DIR / "ytsage_history.json"
    APP_THUMBNAILS_DIR: Path = APP_DATA_DIR / "thumbnails"

    YTDLP_DOWNLOAD_URL: str = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe"
    YTDLP_APP_BIN_PATH: Path = APP_BIN_DIR / "yt-dlp.exe"

    SUBPROCESS_CREATIONFLAGS: int = subprocess.CREATE_NO_WINDOW

elif OS_NAME == "Darwin":  # macOS
    _mac_version = platform.mac_ver()[0]
    OS_FULL_NAME: str = f"macOS {_mac_version}" if _mac_version else "macOS"

    # Always use user data directory for app data, logs, config, and binaries
    # Even when frozen, we don't want to create these folders next to the executable
    APP_DIR: Path = USER_HOME_DIR / "Library" / "Application Support" / "YTSage"
    APP_BIN_DIR: Path = APP_DIR / "bin"
    APP_DATA_DIR: Path = APP_DIR / "data"
    APP_LOG_DIR: Path = APP_DIR / "logs"
    APP_CONFIG_FILE: Path = APP_DATA_DIR / "ytsage_config.json"
    APP_HISTORY_FILE: Path = APP_DATA_DIR / "ytsage_history.json"
    APP_THUMBNAILS_DIR: Path = APP_DATA_DIR / "thumbnails"

    YTDLP_DOWNLOAD_URL: str = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos"
    YTDLP_APP_BIN_PATH: Path = APP_BIN_DIR / "yt-dlp"

    SUBPROCESS_CREATIONFLAGS: int = 0


else:  # Linux and other UNIX-like
    OS_FULL_NAME: str = f"{OS_NAME} {platform.release()}"

    # Always use user data directory for app data, logs, config, and binaries
    # Even when frozen, we don't want to create these folders next to the executable
    APP_DIR: Path = USER_HOME_DIR / ".local" / "share" / "YTSage"
    APP_BIN_DIR: Path = APP_DIR / "bin"
    APP_DATA_DIR: Path = APP_DIR / "data"
    APP_LOG_DIR: Path = APP_DIR / "logs"
    APP_CONFIG_FILE: Path = APP_DATA_DIR / "ytsage_config.json"
    APP_HISTORY_FILE: Path = APP_DATA_DIR / "ytsage_history.json"
    APP_THUMBNAILS_DIR: Path = APP_DATA_DIR / "thumbnails"

    YTDLP_DOWNLOAD_URL: str = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp"
    YTDLP_APP_BIN_PATH: Path = APP_BIN_DIR / "yt-dlp"

    SUBPROCESS_CREATIONFLAGS: int = 0

# Documentation URLs
YTDLP_DOCS_URL: str = "https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#usage-and-options"

# yt-dlp SHA256 checksums URL
YTDLP_SHA256_URL: str = "https://github.com/yt-dlp/yt-dlp/releases/latest/download/SHA2-256SUMS"

# Deno download URLs and paths
if OS_NAME == "Windows":
    DENO_DOWNLOAD_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-pc-windows-msvc.zip"
    DENO_SHA256_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-pc-windows-msvc.zip.sha256sum"
    DENO_APP_BIN_PATH: Path = APP_BIN_DIR / "deno.exe"
elif OS_NAME == "Darwin":  # macOS
    DENO_DOWNLOAD_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-apple-darwin.zip"
    DENO_SHA256_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-apple-darwin.zip.sha256sum"
    DENO_APP_BIN_PATH: Path = APP_BIN_DIR / "deno"
else:  # Linux
    DENO_DOWNLOAD_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-unknown-linux-gnu.zip"
    DENO_SHA256_URL: str = "https://github.com/denoland/deno/releases/latest/download/deno-x86_64-unknown-linux-gnu.zip.sha256sum"
    DENO_APP_BIN_PATH: Path = APP_BIN_DIR / "deno"

# FFmpeg download links (Essentials build - always latest version)
FFMPEG_7Z_DOWNLOAD_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.7z"
FFMPEG_ZIP_DOWNLOAD_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip"
FFMPEG_7Z_SHA256_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.7z.sha256"
FFMPEG_ZIP_SHA256_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip.sha256"
FFMPEG_7Z_VERSION_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.7z.ver"
FFMPEG_ZIP_VERSION_URL = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip.ver"

if __name__ == "__main__":
    # If this file is run directly, print directory information; if imported, create the necessary directories for the application.
    # for debug, to check os specific variable which can be different based on os.
    info = {
        "OS_NAME": OS_NAME,
        "OS_FULL_NAME": OS_FULL_NAME,
        "USER_HOME_DIR": str(USER_HOME_DIR),
        "APP_DIR": str(APP_DIR),
        "APP_BIN_DIR": str(APP_BIN_DIR),
        "APP_DATA_DIR": str(APP_DATA_DIR),
        "APP_LOG_DIR": str(APP_LOG_DIR),
        "APP_CONFIG_FILE": str(APP_CONFIG_FILE),
        "YTDLP_DOWNLOAD_URL": YTDLP_DOWNLOAD_URL,
        "YTDLP_APP_BIN_PATH": YTDLP_APP_BIN_PATH,
        "SUBPROCESS_CREATIONFLAGS": SUBPROCESS_CREATIONFLAGS,
    }
    for key, value in info.items():
        print(f"{key}: {value}")
else:
    APP_DIR.mkdir(parents=True, exist_ok=True)
    APP_BIN_DIR.mkdir(parents=True, exist_ok=True)
    APP_DATA_DIR.mkdir(parents=True, exist_ok=True)
    APP_LOG_DIR.mkdir(parents=True, exist_ok=True)
    APP_THUMBNAILS_DIR.mkdir(parents=True, exist_ok=True)
