"""
パブリッシャーCLIエントリーポイント

コマンドラインからパブリッシャーを起動する。
モードの選択（rapi/dummy）、設定ファイルの指定等が可能。
"""

import argparse
import logging
import signal
import sys
import time

from rich.console import Console
from rich.logging import RichHandler

from ..config import BridgeConfig
from .server import ZmqPublisher
from .dummy import DummyDataGenerator

console = Console()


def setup_logging(verbose: bool = False) -> None:
    """ロギング設定"""
    level = logging.DEBUG if verbose else logging.INFO
    logging.basicConfig(
        level=level,
        format="%(message)s",
        datefmt="[%X]",
        handlers=[RichHandler(
            console=console,
            rich_tracebacks=True,
        )],
    )


def main() -> None:
    """パブリッシャーメインエントリーポイント"""
    parser = argparse.ArgumentParser(
        description="Rithmic Bridge パブリッシャー - MBO & 約定データ配信",
    )
    parser.add_argument(
        "--mode",
        choices=["rapi", "dummy"],
        default="dummy",
        help="動作モード: rapi=R|API+接続, dummy=ダミーデータ (デフォルト: dummy)",
    )
    parser.add_argument(
        "--env-file",
        type=str,
        default=None,
        help=".envファイルのパス (デフォルト: カレントディレクトリの.env)",
    )
    parser.add_argument(
        "--user",
        type=str,
        default=None,
        help="Rithmic ユーザー名",
    )
    parser.add_argument(
        "--password",
        type=str,
        default=None,
        help="Rithmic パスワード",
    )
    parser.add_argument(
        "--rithmic-host",
        type=str,
        default=None,
        help="Rithmic プラグインホスト (デフォルト: 127.0.0.1)",
    )
    parser.add_argument(
        "--rithmic-port",
        type=int,
        default=None,
        help="Rithmic プラグインポート (デフォルト: 56000)",
    )
    parser.add_argument(
        "--symbol",
        type=str,
        default=None,
        help="デフォルトシンボル (例: GCJ6)",
    )
    parser.add_argument(
        "--exchange",
        type=str,
        default=None,
        help="デフォルト取引所 (例: COMEX)",
    )
    parser.add_argument(
        "--bind",
        type=str,
        default=None,
        help="ZeroMQ PUBバインドアドレス (例: tcp://*:5555)",
    )
    parser.add_argument(
        "--rep-port",
        type=int,
        default=None,
        help="ZeroMQ REP (コマンド) ポート (デフォルト: 5556)",
    )
    parser.add_argument(
        "--dll-dir",
        type=str,
        default=None,
        help="R|API+ DLLディレクトリのパス",
    )
    parser.add_argument(
        "--rate",
        type=int,
        default=100,
        help="ダミーモード時の1秒あたりのイベント生成数 (デフォルト: 100)",
    )
    parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="詳細ログを表示",
    )

    args = parser.parse_args()

    # ロギング設定
    setup_logging(verbose=args.verbose)
    logger = logging.getLogger(__name__)

    # 設定読み込み
    config = BridgeConfig.from_env(env_file=args.env_file)

    # コマンドライン引数で上書き
    if args.user:
        config.rithmic.user = args.user
    if args.password:
        config.rithmic.password = args.password
    if args.rithmic_host:
        config.rithmic.host = args.rithmic_host
    if args.rithmic_port:
        config.rithmic.port = args.rithmic_port
    if args.symbol:
        config.rithmic.symbol = args.symbol
    if args.exchange:
        config.rithmic.exchange = args.exchange
    if args.dll_dir:
        config.rithmic.dll_dir = args.dll_dir
        
    if args.bind:
        config.zmq.pub_addr = args.bind
    if args.rep_port:
        config.zmq.rep_port = args.rep_port

    # ヘッダー表示
    console.print("")
    console.print("[bold blue]═══════════════════════════════════════[/]")
    console.print("[bold blue]  Rithmic Bridge パブリッシャー[/]")
    console.print("[bold blue]═══════════════════════════════════════[/]")
    console.print(f"  モード: [bold]{args.mode}[/]")
    console.print(f"  バインド: [bold]{config.get_pub_bind_addr()}[/]")
    console.print(f"  シンボル: [bold]{config.get_symbol_full()}[/]")
    console.print("[bold blue]═══════════════════════════════════════[/]")
    console.print("")

    # パブリッシャーの作成と開始
    publisher = ZmqPublisher(config)
    publisher.start()

    # データソースの設定
    data_source = None

    if args.mode == "dummy":
        # ダミーデータモード
        data_source = DummyDataGenerator(
            publisher=publisher,
            config=config,
            events_per_second=args.rate,
        )
        data_source.start()

    elif args.mode == "rapi":
        # R|API+モード
        from .rapi_bridge import RapiBridge, is_pythonnet_available

        if not is_pythonnet_available():
            console.print(
                "[bold red]✗ pythonnetが利用できません[/]\n"
                "  pip install pythonnet でインストールするか、\n"
                "  --mode dummy でダミーモードを使用してください"
            )
            publisher.stop()
            sys.exit(1)

        bridge = RapiBridge(publisher=publisher, config=config)
        # 接続前にログレベルが反映されていることを確認 (setup_loggingで実施済み)
        if not bridge.connect():
            console.print("[bold red]✗ R|API+への接続に失敗しました[/]")
            publisher.stop()
            sys.exit(1)

        # bridge.subscribe() # 自動購読を無効化 (クライアントからのコマンド待ち)
        data_source = bridge

    # シグナルハンドラー設定 (Ctrl+C で停止)
    shutdown_event = False

    def signal_handler(signum, frame):
        nonlocal shutdown_event
        if not shutdown_event:
            shutdown_event = True
            console.print("\n[yellow]シャットダウン中... (Ctrl+Cを再度押すと強制終了)[/]")

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    # メインループ
    console.print("[green]パブリッシャー稼働中 (Ctrl+C で停止)[/]\n")
    try:
        while not shutdown_event:
            # 定期的な状態表示
            time.sleep(5)
            if publisher.is_running:
                q_size = publisher.queue_size
                if q_size > 0:
                    console.print(
                        f"  [dim]キューサイズ: {q_size}[/]",
                    )
    except KeyboardInterrupt:
        pass

    # クリーンアップ
    console.print("\n[yellow]クリーンアップ中...[/]")

    if data_source:
        if hasattr(data_source, 'stop'):
            data_source.stop()
        elif hasattr(data_source, 'disconnect'):
            data_source.disconnect()

    publisher.stop()

    console.print("[bold green]✓ パブリッシャー正常終了[/]")


if __name__ == "__main__":
    main()
