from __future__ import annotations

import os
import datetime
import json
import pathlib
import sys

# Import utility functions
from .file_utils import safe_open_file
from .path_utils import get_path
from .settings_utils import (
    get_chisurf_settings,
    copy_settings_to_user_folder,
    copy_styles_to_user_folder
)
from .cleanup import clear_settings_folder, clear_logging_files
from .path_utils import get_path  # Needed early

# Define Chisurf cache path inside user settings folder
_chisurf_user_cache_dir = get_path('settings') / "cache"

# Set environment variables for Numba and Python bytecode cache
os.environ["NUMBA_CACHE_DIR"] = str(_chisurf_user_cache_dir)
os.environ["PYTHONPYCACHEPREFIX"] = str(_chisurf_user_cache_dir)

# Ensure the cache directory exists
_chisurf_user_cache_dir.mkdir(parents=True, exist_ok=True)

# Path constants
chisurf_settings_path = get_path('settings')
macro_path = get_path('chisurf') / "macros"
plugin_path = get_path('chisurf') / "plugins"
notebook_path = get_path('chisurf') / "notebooks"

# Copy settings files if not already present
copy_settings_to_user_folder()

# Open chisurf settings file
chisurf_settings_file = chisurf_settings_path / 'settings_chisurf.yaml'
# To use the settings in the home folder set to false
# if set to true uses settings in source folder.
cs_settings = get_chisurf_settings(chisurf_settings_file, use_source_folder=False)

# Apply thread-related environment variables as early as possible, before any heavy imports
try:
    import sys as _sys
    import os as _os
    _threads = cs_settings.get('threads', {}) if isinstance(cs_settings, dict) else {}
    # Defaults as requested
    _defaults = {
        'numba_num_threads': "1",
        'numba_threading_layer': "workqueue",
        'mkl_num_threads': "1",
        'omp_num_threads': "1",
        'mkl_threading_layer': "SEQUENTIAL",
    }
    _override = bool(_threads.get('override_existing_env', False))
    def _set_env(var_name: str, value: str):
        if _override or var_name not in _os.environ or _os.environ.get(var_name, "") == "":
            _os.environ[var_name] = str(value)
    # Detect if heavy modules already imported
    _heavy_loaded = any(m in _sys.modules for m in ("numpy", "numba", "umap"))
    if _heavy_loaded:
        # Changing env vars may not take effect if modules already imported
        # We still set them for any modules imported later.
        pass
    _set_env("NUMBA_NUM_THREADS", _threads.get('numba_num_threads', _defaults['numba_num_threads']))
    _set_env("NUMBA_THREADING_LAYER", _threads.get('numba_threading_layer', _defaults['numba_threading_layer']))
    _set_env("MKL_NUM_THREADS", _threads.get('mkl_num_threads', _defaults['mkl_num_threads']))
    _set_env("OMP_NUM_THREADS", _threads.get('omp_num_threads', _defaults['omp_num_threads']))
    _set_env("MKL_THREADING_LAYER", _threads.get('mkl_threading_layer', _defaults['mkl_threading_layer']))
except Exception:
    # Fail silently; settings application is best-effort and should not break startup
    pass

anisotropy = dict()
anisotropy_data = safe_open_file(
    file_path=get_path('chisurf') / "settings" / "anisotropy_corrections.json",
    processor=json.load,
    default_value={},
    error_message="Error opening anisotropy corrections file"
)
anisotropy.update(anisotropy_data)

verbose = False
gui = dict()
parameter = dict()
optimization = dict()
fret = dict()
tcspc = dict()
fps = dict()
locals().update(cs_settings)

# Open color settings file
color_settings_file = chisurf_settings_path / 'settings_colors.yaml'
colors = get_chisurf_settings(color_settings_file)

package_directory = pathlib.Path(__file__).parent
style_sheet_file = package_directory / '..' / 'gui' / 'styles' / gui['style_sheet']
style_sheet = safe_open_file(
    file_path=style_sheet_file,
    default_value="",
    error_message=f"Error opening style sheet file {style_sheet_file}"
)
structure_data = safe_open_file(
    file_path=package_directory / 'constants' / 'structure.json',
    processor=json.load,
    default_value={},
    error_message="Error opening structure.json file"
)

eps = sys.float_info.epsilon
working_path = ''

session_str = datetime.datetime.now().strftime('session_%H_%M_%d_%m_%Y')
# Create logs subfolder
logs_folder = chisurf_settings_path / "logs"
logs_folder.mkdir(exist_ok=True)
session_file = logs_folder / str(session_str + ".py")
session_log = logs_folder / str(session_str + ".log")
