"""Command-line entrypoint for the MTG Python Deckbuilder.

Launches directly into the interactive deck builder. On first run (or if the
card database is missing), it automatically performs initial setup and tagging.
"""
from __future__ import annotations

# Standard library imports
import sys
from pathlib import Path
import json
from typing import NoReturn

# Ensure local package resolution in frozen builds
import os
if getattr(sys, 'frozen', False):  # PyInstaller frozen
    base = os.path.dirname(sys.executable)
    code_dir = os.path.join(base, 'code')
    if os.path.isdir(code_dir) and code_dir not in sys.path:
        sys.path.insert(0, code_dir)

# Local imports
from deck_builder import DeckBuilder
from file_setup.setup import initial_setup
from tagging import tagger
import logging_util
from settings import CSV_DIRECTORY

# Create logger for this module
logger = logging_util.logging.getLogger(__name__)
logger.setLevel(logging_util.LOG_LEVEL)
logger.addHandler(logging_util.file_handler)
logger.addHandler(logging_util.stream_handler)

builder = DeckBuilder()

def _ensure_data_ready() -> None:
    logger.info("Starting MTG Python Deckbuilder")
    Path('csv_files').mkdir(parents=True, exist_ok=True)
    Path('deck_files').mkdir(parents=True, exist_ok=True)
    Path('logs').mkdir(parents=True, exist_ok=True)

    # Ensure required CSVs exist and are tagged before proceeding
    try:
        import time
        import json as _json
        from datetime import datetime as _dt
        cards_path = os.path.join(CSV_DIRECTORY, 'cards.csv')
        flag_path = os.path.join(CSV_DIRECTORY, '.tagging_complete.json')
        refresh_needed = False
        # Missing CSV forces refresh
        if not os.path.exists(cards_path):
            logger.info("cards.csv not found. Running initial setup and tagging...")
            refresh_needed = True
        else:
            # Stale CSV (>7 days) forces refresh
            try:
                age_seconds = time.time() - os.path.getmtime(cards_path)
                if age_seconds > 7 * 24 * 60 * 60:
                    logger.info("cards.csv is older than 7 days. Refreshing data (setup + tagging)...")
                    refresh_needed = True
            except Exception:
                pass
        # Missing tagging flag forces refresh
        if not os.path.exists(flag_path):
            logger.info("Tagging completion flag not found. Performing full tagging...")
            refresh_needed = True
        if refresh_needed:
            initial_setup()
            tagger.run_tagging()
            # Write tagging completion flag
            try:
                os.makedirs(CSV_DIRECTORY, exist_ok=True)
                with open(flag_path, 'w', encoding='utf-8') as _fh:
                    _json.dump({
                        'tagged_at': _dt.now().isoformat(timespec='seconds')
                    }, _fh)
            except Exception:
                logger.warning("Failed to write tagging completion flag (non-fatal).")
            logger.info("Initial setup and tagging completed.")
    except Exception as e:
        logger.error(f"Failed ensuring CSVs are ready: {e}")


def _interactive_loop() -> None:
    while True:
        try:
            # Fresh builder instance for each deck to avoid state carryover
            DeckBuilder().build_deck_full()
        except Exception as e:
            logger.error(f"Unexpected error in deck builder: {e}")

        # Prompt to build another deck or return to main menu
        try:
            resp = input("\nBuild another deck? (y/n): ").strip().lower()
        except KeyboardInterrupt:
            resp = 'n'
            print("")
        if resp not in ('y', 'yes'):
            break


def run_menu() -> NoReturn:
    """Launch directly into the deck builder after ensuring data files exist.

    Creates required directories, ensures card CSVs are present (running setup
    and tagging if needed), then starts the full deck build flow. Exits when done.
    """
    _ensure_data_ready()

    # Auto headless mode for container runs (no menu prompt)
    auto_mode = os.getenv('DECK_MODE', '').strip().lower()
    if auto_mode in ("headless", "noninteractive", "auto"):
        try:
            from headless_runner import _main as headless_main
            headless_main()
        except Exception as e:
            logger.error(f"Headless run failed: {e}")
        logger.info("Exiting application")
        sys.exit(0)

    # Menu-driven selection
    def _run_headless_with_config(selected_config: str | None) -> None:
        """Run headless runner, optionally forcing a specific config path for this invocation."""
        try:
            from headless_runner import _main as headless_main
            # Temporarily override DECK_CONFIG for this run if provided
            prev_cfg = os.environ.get('DECK_CONFIG')
            try:
                if selected_config:
                    os.environ['DECK_CONFIG'] = selected_config
                headless_main()
            finally:
                if selected_config is not None:
                    if prev_cfg is not None:
                        os.environ['DECK_CONFIG'] = prev_cfg
                    else:
                        os.environ.pop('DECK_CONFIG', None)
        except Exception as e:
            logger.error(f"Headless run failed: {e}")

    def _headless_submenu() -> None:
        """Submenu to choose a JSON config and run the headless builder.

        Behavior:
        - If DECK_CONFIG points to a file, run it immediately.
        - Else, search for *.json in (DECK_CONFIG as dir) or /app/config or ./config.
          - If one file is found, run it immediately.
          - If multiple files, list them for selection.
          - If none, fall back to running headless using env/CLI/defaults.
        """
        cfg_target = os.getenv('DECK_CONFIG')
        # Case 1: DECK_CONFIG is an explicit file
        if cfg_target and os.path.isfile(cfg_target):
            print(f"\nRunning headless with config: {cfg_target}")
            _run_headless_with_config(cfg_target)
            return

        # Determine directory to scan for JSON configs
        if cfg_target and os.path.isdir(cfg_target):
            cfg_dir = cfg_target
        elif os.path.isdir('/app/config'):
            cfg_dir = '/app/config'
        else:
            cfg_dir = 'config'

        try:
            p = Path(cfg_dir)
            files = sorted([str(fp) for fp in p.glob('*.json')]) if p.exists() else []
        except Exception:
            files = []

        # No configs found: run headless with current env/CLI/defaults
        if not files:
            print("\nNo JSON configs found in '" + cfg_dir + "'. Running headless with env/CLI/defaults...")
            _run_headless_with_config(None)
            return

        # Single config: run automatically
        if len(files) == 1:
            print(f"\nFound one JSON config: {files[0]}\nRunning it now...")
            _run_headless_with_config(files[0])
            return

        # Multiple configs: list and select
        def _config_label(p: str) -> str:
            try:
                with open(p, 'r', encoding='utf-8') as fh:
                    data = json.load(fh)
                cmd = str(data.get('commander') or '').strip() or 'Unknown Commander'
                themes = [t for t in [data.get('primary_tag'), data.get('secondary_tag'), data.get('tertiary_tag')] if isinstance(t, str) and t.strip()]
                name = os.path.basename(p).lower()
                if name == 'deck.json':
                    return 'Default'
                return f"{cmd} - {', '.join(themes)}" if themes else cmd
            except Exception:
                return p

        print("\nAvailable JSON configs:")
        labels = [_config_label(f) for f in files]
        for idx, label in enumerate(labels, start=1):
            print(f"  {idx}) {label}")
        print("  0) Back to main menu")
        while True:
            try:
                sel = input("Select a config to run [0]: ").strip() or '0'
            except KeyboardInterrupt:
                print("")
                sel = '0'
            if sel == '0':
                return
            try:
                i = int(sel)
                if 1 <= i <= len(files):
                    _run_headless_with_config(files[i - 1])
                    return
            except ValueError:
                pass
            print("Invalid selection. Try again.")

    while True:
        print("\n==== MTG Deckbuilder ====")
        print("1) Interactive deck build")
        print("2) Headless (env/JSON-configured) run")
        print("   - Will auto-run a single config if found, or let you choose from many")
        print("q) Quit")
        try:
            choice = input("Select an option [1]: ").strip().lower() or '1'
        except KeyboardInterrupt:
            print("")
            choice = 'q'

        if choice in ('1', 'i', 'interactive'):
            _interactive_loop()
            # loop returns to main menu
        elif choice in ('2', 'h', 'headless', 'noninteractive'):
            _headless_submenu()
            # after one headless run, return to menu
        elif choice in ('q', 'quit', 'exit'):
            logger.info("Exiting application")
            sys.exit(0)
        else:
            print("Invalid selection. Please try again.")

if __name__ == "__main__":
    run_menu()