# --- Standard Library Imports ---
import sys
import os
import time
import traceback

# --- PyQt5 Imports ---
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.QtCore import QCoreApplication

# --- Local Application Imports ---
from src.ui.main_window import DownloaderApp
from src.ui.dialogs.TourDialog import TourDialog
from src.config.constants import CONFIG_ORGANIZATION_NAME, CONFIG_APP_NAME_MAIN

# --- Define APP_BASE_DIR globally and make available early ---
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
    APP_BASE_DIR = sys._MEIPASS
else:
    APP_BASE_DIR = os.path.abspath(os.path.dirname(__file__))

# Optional: Set a global variable or pass it into modules if needed
# Or re-export it via constants.py for cleaner imports

def handle_uncaught_exception(exc_type, exc_value, exc_traceback):
    """
    Handles uncaught exceptions by logging them to a file for easier debugging,
    especially for bundled applications.
    """
    # Use APP_BASE_DIR to determine logging location
    log_dir = os.path.join(APP_BASE_DIR, "logs")
    log_file_path = os.path.join(log_dir, "uncaught_exceptions.log")

    try:
        os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
        with open(log_file_path, "a", encoding="utf-8") as f:
            f.write(f"Timestamp: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
            traceback.print_exception(exc_type, exc_value, exc_traceback, file=f)
            f.write("-" * 80 + "\n\n")
    except Exception as log_ex:
        # Fallback to stderr if logging to file fails
        print(f"CRITICAL: Failed to write to uncaught_exceptions.log: {log_ex}", file=sys.stderr)
        traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr)
    
    # Also call the default excepthook
    sys.__excepthook__(exc_type, exc_value, exc_traceback)


def main():
    """Main entry point for the Kemono Downloader application."""
    
    # Set up global exception handling
    sys.excepthook = handle_uncaught_exception

    try:
        # Set up application metadata for QSettings
        QCoreApplication.setOrganizationName(CONFIG_ORGANIZATION_NAME)
        QCoreApplication.setApplicationName(CONFIG_APP_NAME_MAIN)
        
        qt_app = QApplication(sys.argv)

        # Create the main application window
        downloader_app_instance = DownloaderApp()

        # --- Window Sizing and Positioning ---
        primary_screen = QApplication.primaryScreen()
        if not primary_screen:
            downloader_app_instance.resize(1024, 768)
        else:
            available_geo = primary_screen.availableGeometry()
            screen_width = available_geo.width()
            screen_height = available_geo.height()
            
            min_app_width, min_app_height = 960, 680
            desired_width_ratio, desired_height_ratio = 0.80, 0.85

            app_width = max(min_app_width, int(screen_width * desired_width_ratio))
            app_height = max(min_app_height, int(screen_height * desired_height_ratio))

            app_width = min(app_width, screen_width)
            app_height = min(app_height, screen_height)
            
            downloader_app_instance.resize(app_width, app_height)

        # Show and center the main window
        downloader_app_instance.show()
        if hasattr(downloader_app_instance, '_center_on_screen'):
            downloader_app_instance._center_on_screen()

        # --- First-Run Welcome Tour ---
        if TourDialog.should_show_tour():
            tour_dialog = TourDialog(parent_app=downloader_app_instance)
            tour_dialog.exec_()

        # --- Start Application ---
        exit_code = qt_app.exec_()
        print(f"Application finished with exit code: {exit_code}")
        sys.exit(exit_code)

    except SystemExit:
        pass
    except Exception as e:
        print("--- CRITICAL APPLICATION STARTUP ERROR ---")
        print(f"An unhandled exception occurred during application startup: {e}")
        traceback.print_exc()
        print("--- END CRITICAL ERROR ---")


if __name__ == '__main__':
    main()
