#!/usr/bin/env python3
"""
Gold AutoTrade — One-Click Trial Launcher

This is what trial users run. It:
  1. Auto-detects MT5 installation
  2. Configures DeepSeek API key (required for AI-driven trading)
  3. Auto-claims a 14-day trial license (no server, no signup)
  4. Risk disclosure compliance
  5. Starts paper trading engine + AI macro direction daemon
  6. Launches the GUI dashboard
  7. Opens the browser to the dashboard

Usage:
  python3 start_trial.py
  python3 start_trial.py --live    (only after onboarding complete)
"""
from __future__ import annotations

import json
import os
import subprocess
import sys
import time
from pathlib import Path

ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT))

# ─── ASCII Banner ──────────────────────────────────────────────────

BANNER = r"""
   ____       _     _         _                  _
  / ___| ___ | | __| |       / \   _ __ ___     / \   _ __  _ __
 | |  _ / _ \| |/ _| |_____ / _ \ | '_ ` _ \   / _ \ | '_ \| '_ \
 | |_| | (_) | | |_| |_____/ ___ \| | | | | | / ___ \| |_) | |_) |
  \____|\___/|_|\__|     /_/   \_\_| |_| |_|/_/   \_\ .__/| .__/
                                                     |_|   |_|
"""


def main():
    print(BANNER)
    print("Gold AutoTrade — 14-Day Free Trial")
    print("=" * 55)
    print()

    # ── Step 1: MT5 Detection ──────────────────────────────────────
    print("[1/6] Detecting MT5 installation...")
    mt5_path, mt5_found = _detect_mt5()
    if mt5_found:
        print(f"  ✓ MT5 found: {mt5_path}")
    else:
        print(f"  ⚠ MT5 not auto-detected.")
        print(f"  Expected at: {mt5_path}")
        print(f"  Make sure MT5 is running with the Bridge EA installed.")
    print()

    # ── Step 2: DeepSeek API Key ───────────────────────────────────
    print("[2/6] Configuring DeepSeek API key...")
    _ensure_api_key()
    print()

    # ── Step 3: Trial License ──────────────────────────────────────
    print("[3/6] Activating 14-day trial license...")
    try:
        from src.license.trial import claim_trial, get_trial_status
        trial_status = get_trial_status()

        if trial_status["status"] == "TRIAL_ACTIVE":
            print(f"  ✓ Trial active — {trial_status['days_left']} days remaining")
        elif trial_status["status"] == "PAID_LICENSE":
            print(f"  ✓ Paid license active — tier: {trial_status.get('tier', 'pro')}")
        elif trial_status["status"] == "TRIAL_EXPIRED":
            print(f"  ✗ Trial expired.")
            _print_purchase_info()
            _wait_and_exit(1)
        else:
            result = claim_trial()
            if result["ok"]:
                print(f"  ✓ Trial activated — {result['days_left']} days remaining")
                print(f"    Expires: {result['expires']}")
            else:
                print(f"  ✗ Cannot activate trial: {result.get('message', 'Unknown error')}")
                _wait_and_exit(1)
    except ImportError as e:
        print(f"  ✗ License module error: {e}")
        _wait_and_exit(1)
    print()

    # ── Step 4: Compliance ─────────────────────────────────────────
    print("[4/6] Risk disclosure...")
    try:
        from src.compliance.disclaimers import has_accepted_risk_disclosure, RISK_DISCLOSURE_V1
        if not has_accepted_risk_disclosure():
            print()
            print(RISK_DISCLOSURE_V1)
            print()
            response = input("I have read and accept the risk disclosure (yes/no): ").strip().lower()
            if response in ("yes", "y"):
                from src.compliance.disclaimers import accept_risk_disclosure
                accept_risk_disclosure()
                print("  ✓ Risk disclosure accepted")
            else:
                print("  ✗ You must accept the risk disclosure to use this software.")
                _wait_and_exit(1)
        else:
            print("  ✓ Risk disclosure previously accepted")
    except ImportError:
        print("  ⚠ Compliance module not available — skipping")
    print()

    # ── Step 5: Start Engines ──────────────────────────────────────
    print("[5/6] Starting trading engines...")
    _start_engines()
    print()

    # ── Step 6: Launch GUI Dashboard ─────────────────────────────
    print("[6/6] Launching dashboard...")
    gui_url = "http://127.0.0.1:18790"
    try:
        env = os.environ.copy()
        env["GUI_PORT"] = "18790"
        _launch_background(
            [sys.executable, str(ROOT / "gui_backend.py")],
            ROOT / "logs" / "gui_backend.log",
            env=env,
        )
        print(f"  ✓ Dashboard: {gui_url}")
        _open_browser(gui_url)
    except Exception as e:
        print(f"  ⚠ GUI launch issue: {e}")

    # ── Done ───────────────────────────────────────────────────────
    print()
    print("=" * 55)
    print("Trial Ready!")
    print()
    print(f"  Dashboard:     {gui_url}")
    print(f"  Engine log:    tail -f logs/engine.log")
    print(f"  Daemon log:    tail -f logs/daemon.log")
    print(f"  GUI log:       tail -f logs/gui_backend.log")
    print(f"  Add license:   python3 -m src.license.activate --key <key>")
    print()
    print(f"  Trial expires in 14 days. No credit card required.")
    print(f"  WeChat/QQ: goldautotrade | Email: support@goldauto.top")
    print("=" * 55)

    # Keep running — periodically check license validity online
    _last_online_check = 0
    ONLINE_CHECK_SECONDS = 3600  # check revocation every hour
    try:
        while True:
            time.sleep(60)
            now = time.time()
            if now - _last_online_check >= ONLINE_CHECK_SECONDS:
                _last_online_check = now
                try:
                    from src.license.validator import check_online
                    from src.license.activate import DEFAULT_SERVER
                    result = check_online(DEFAULT_SERVER)
                    if result.get("error"):
                        print(f"\n  ⚠ License issue: {result['error']}")
                        print(f"  WeChat/QQ: goldautotrade | Email: support@goldauto.top\n")
                except Exception:
                    pass  # offline — silently allow
    except KeyboardInterrupt:
        print("\nShutting down. Thanks for trying Gold AutoTrade!")
        sys.exit(0)


# ─── Helpers ────────────────────────────────────────────────────────

def _detect_mt5() -> tuple[str, bool]:
    """Auto-detect MT5 terminal path."""
    home = Path.home()
    candidates = [
        # macOS (Wine/CrossOver)
        home / "Library" / "Application Support" / "net.metaquotes.wine.metatrader5",
        # Windows
        Path("C:/Program Files/MetaTrader 5"),
        Path("C:/Program Files (x86)/MetaTrader 5"),
        # Custom
        Path(os.environ.get("MT5_PATH", "")),
    ]
    for c in candidates:
        if c.exists():
            return str(c), True
    return str(candidates[0]), False


def _ensure_api_key() -> None:
    """Ensure DEEPSEEK_API_KEY is configured, prompting the user if needed."""
    existing = os.environ.get("DEEPSEEK_API_KEY", "")
    if not existing:
        try:
            import config_manager
            app_config = config_manager.load_app_config()
            existing = app_config.get("DEEPSEEK_API_KEY", "")
        except Exception:
            pass

    if existing and existing != "YOUR_DEEPSEEK_API_KEY_HERE":
        masked = existing[:8] + "****" + existing[-4:] if len(existing) >= 12 else "****"
        print(f"  ✓ API key configured: {masked}")
        return

    print("  DeepSeek API key is required for AI-driven trading decisions.")
    print("  Get your key at: https://platform.deepseek.com/api_keys")
    print()
    api_key = input("  Paste your DeepSeek API key (sk-...): ").strip()
    if not api_key:
        print("  ⚠ No API key provided. AI macro direction will fall back to technical analysis only.")
        print("    You can configure it later in the Dashboard or by setting DEEPSEEK_API_KEY.")
        return

    try:
        import config_manager
        config_manager.save_app_config({"DEEPSEEK_API_KEY": api_key})
        os.environ["DEEPSEEK_API_KEY"] = api_key
        masked = api_key[:8] + "****" + api_key[-4:] if len(api_key) >= 12 else "****"
        print(f"  ✓ API key saved: {masked}")
    except Exception as e:
        print(f"  ⚠ Could not save API key: {e}")
        print(f"  Set it manually: export DEEPSEEK_API_KEY={api_key}")


def _start_engines() -> None:
    """Start pipeline.py (signal engine) and gold_trader.py (AI macro daemon)."""
    # ── Pipeline (signal generation + dispatch) ──
    pipeline_started = False
    pipeline_pid_file = ROOT / "logs" / "pipeline.pid"
    try:
        if pipeline_pid_file.exists():
            try:
                pid = int(pipeline_pid_file.read_text().strip())
                os.kill(pid, 0)
                print(f"  ✓ Pipeline already running (PID: {pid})")
                pipeline_started = True
            except (ValueError, OSError):
                pass

        if not pipeline_started:
            cmd = [
                sys.executable, str(ROOT / "src" / "pipeline.py"),
                "--source", "mt5",
                "--runtime-intent", "paper_trade",
                "--symbol", "XAUUSD",
                "--timeframe", "M5",
                "--execution-mode", "mock",
                "--poll-seconds", "5",
                "--enable-incident-autofix", "true",
                "--input-path", str(ROOT / "data" / "inbox" / "request.json"),
                "--output-path", str(ROOT / "data" / "outbox" / "signal.json"),
            ]
            _launch_background(cmd, ROOT / "logs" / "engine.log")
            print(f"  ✓ Pipeline started (signal engine)")
    except Exception as e:
        print(f"  ⚠ Pipeline start failed: {e}")

    # ── Gold Trader Daemon (AI macro direction + watchdog + bridge) ──
    daemon_started = False
    daemon_pid_file = ROOT / "logs" / "gold_trader.pid"
    try:
        if daemon_pid_file.exists():
            try:
                pid = int(daemon_pid_file.read_text().strip())
                os.kill(pid, 0)
                print(f"  ✓ Gold Trader daemon already running (PID: {pid})")
                daemon_started = True
            except (ValueError, OSError):
                pass

        if not daemon_started:
            # --monitor-only: gold_trader runs bridge adapter + daemon threads
            # (AI macro direction, watchdog, daily tasks) without duplicating
            # signal generation — pipeline owns that.
            cmd = [
                sys.executable, str(ROOT / "bridge" / "gold_trader.py"),
                "--fg",
                "--monitor-only",
            ]
            _launch_background(cmd, ROOT / "logs" / "daemon.log")
            print(f"  ✓ Gold Trader daemon started (AI macro direction + watchdog)")
    except Exception as e:
        print(f"  ⚠ Gold Trader daemon start failed: {e}")

    print(f"    Logs: logs/engine.log  logs/daemon.log")


def _print_purchase_info() -> None:
    """Print license purchase contact info."""
    print()
    print("  To purchase a formal license:")
    print("    WeChat/QQ: goldautotrade")
    print("    Email:     support@goldauto.top")
    print("    Website:   https://goldauto.top/license")
    print()


def _launch_background(cmd: list[str], log_path: Path, env: dict = None) -> None:
    """Launch a subprocess in background, logging to file."""
    log_path.parent.mkdir(parents=True, exist_ok=True)
    with open(log_path, "a") as log:
        subprocess.Popen(
            cmd,
            stdout=log,
            stderr=subprocess.STDOUT,
            start_new_session=True,
            env=env,
        )


def _open_browser(url: str) -> None:
    """Open browser to the given URL."""
    import webbrowser
    import time
    time.sleep(2)
    try:
        webbrowser.open(url)
    except Exception:
        pass


def _wait_and_exit(code: int) -> None:
    print()
    input("Press Enter to exit...")
    sys.exit(code)


if __name__ == "__main__":
    main()
