import os
import argparse
import urllib.request
import json
from .config import ConfigManager
from .kernel import MMClaw
from .connectors import TelegramConnector, TerminalConnector, WhatsAppConnector, FeishuConnector

def run_setup(existing_config=None):
    print("\n--- 🐈 MMClaw Setup Wizard ---")
    config = existing_config.copy() if existing_config else ConfigManager.DEFAULT_CONFIG.copy()

    def ask(prompt, key, default_val):
        current = config.get(key, default_val)
        if existing_config:
            user_input = input(f"{prompt} [{current}]: ").strip()
            return user_input if user_input else current
        else:
            user_input = input(f"{prompt}: ").strip()
            return user_input if user_input else default_val

    # 1. LLM Configuration
    print("\n[1/3] LLM Engine Setup")
    
    PROVIDERS = [
        {"name": "OpenAI", "url": "https://api.openai.com/v1", "models": ["gpt-4o", "gpt-4o-mini", "o1", "o1-mini"]},
        {"name": "DeepSeek", "url": "https://api.deepseek.com", "models": ["deepseek-chat", "deepseek-reasoner"]},
        {"name": "OpenRouter", "url": "https://openrouter.ai/api/v1", "models": ["anthropic/claude-3.5-sonnet", "google/gemini-flash-1.5"]},
        {"name": "OpenAI-Compatible SDK (Custom URL)", "url": None, "models": []}
    ]

    print("Select Provider:")
    for i, p in enumerate(PROVIDERS, 1):
        print(f"{i}. {p['name']}")
    
    current_engine = str(config.get("engine_type", "1"))
    p_choice = input(f"Choice (1-{len(PROVIDERS)}) [Current: {current_engine}]: ").strip()
    
    if not p_choice and existing_config:
        p_choice = current_engine
    
    idx = int(p_choice) - 1 if p_choice.isdigit() and 1 <= int(p_choice) <= len(PROVIDERS) else 0
    provider = PROVIDERS[idx]
    config["engine_type"] = idx + 1
    
    if provider["url"]:
        config["base_url"] = provider["url"]
        print(f"[*] Base URL set to: {config['base_url']}")
    else:
        config["base_url"] = ask("Enter Base URL", "base_url", "http://localhost:11434/v1")

    config["api_key"] = ask(f"Enter {provider['name']} API Key", "api_key", "sk-xxx")

    # Dynamic Model Fetching
    models = provider["models"]
    if config["api_key"] and config["api_key"] != "sk-xxx":
        print(f"[*] Fetching live models from {provider['name']}...")
        try:
            req = urllib.request.Request(
                f"{config['base_url']}/models", 
                headers={"Authorization": f"Bearer {config['api_key']}"}
            )
            with urllib.request.urlopen(req, timeout=5) as response:
                data = json.loads(response.read().decode("utf-8"))
                fetched = [m["id"] for m in data.get("data", [])]
                if fetched:
                    # Filter and sort to keep the list clean. 
                    # We prioritize short/standard names for popular providers.
                    if "openai.com" in config["base_url"]:
                        fetched = [m for m in fetched if m.startswith(("gpt-", "o1-"))]
                    
                    # Merge fetched models with our static list, ensuring no duplicates
                    models = list(set(fetched + models))
                    
                    # Sort logic: Featured models first, then alphabetical
                    FEATURED = ["gpt-4o", "gpt-4o-mini", "o1", "o1-mini", "deepseek-chat", "deepseek-reasoner"]
                    
                    def sort_key(name):
                        try:
                            # If it's a featured model, give it priority (0 to len-1)
                            return (FEATURED.index(name), name)
                        except ValueError:
                            # Others come after featured models
                            return (len(FEATURED), name)
                    
                    models.sort(key=sort_key)
                    print(f"[✓] Successfully fetched {len(fetched)} models.")
        except Exception:
            print("[!] Could not fetch live models, using default list.")

    if models:
        print(f"\nSelect {provider['name']} Model:")
        for i, m in enumerate(models, 1):
            print(f"{i}. {m}")
        
        print(f"{len(models)+1}. Enter Manually")
        m_choice = input(f"Choice (1-{len(models)+1}) [Current: {config.get('model')}]: ").strip()
        
        if m_choice.isdigit():
            idx_m = int(m_choice)
            if 1 <= idx_m <= len(models):
                config["model"] = models[idx_m-1]
            elif idx_m == len(models) + 1:
                config["model"] = input("Enter Model Name manually: ").strip()
        elif not m_choice and existing_config:
            pass # Keep current
        else:
            config["model"] = models[0]
    else:
        config["model"] = ask("Enter Model Name", "model", "llama3")

    # 2. Mode Selection
    print("\n[2/3] Interaction Mode")
    print(f"Current preferred mode: {config.get('preferred_mode', 'terminal')}")
    print("1. Terminal Mode")
    print("2. Telegram Mode")
    print("3. WhatsApp Mode (Scan QR Code)")
    print("4. Feishu (飞书) Mode")
    
    choice = input("Select mode (1, 2, 3, or 4) [Keep current]: ").strip()

    if choice == "4":
        config["preferred_mode"] = "feishu"
        print("\n--- 🛠 Feishu (飞书) Setup ---")
        print("[*] 第一步：请登录飞书开放平台 (https://open.feishu.cn/app) 并创建一个“企业自建应用”。")
        input("    完成后请按回车键继续...")
        print("[*] 第二步：在“添加应用能力”中，点击机器人下方的“添加”按钮。")
        input("    完成后请按回车键继续...")
        print("[*] 第三步：左侧菜单栏选择“凭证与基础信息”，获取并输入以下信息：")
        config["feishu_app_id"] = ask("App ID", "feishu_app_id", "")
        config["feishu_app_secret"] = ask("App Secret", "feishu_app_secret", "")
        print("[*] 第四步：左侧菜单栏选择“权限管理”，点击“批量导入/导出权限”，复制并粘贴以下 JSON：")
        print("\n{\n  \"scopes\": {\n    \"tenant\": [\n      \"contact:user.base:readonly\",\n      \"im:chat\",\n      \"im:chat:read\",\n      \"im:chat:update\",\n      \"im:message\",\n      \"im:message.group_at_msg:readonly\",\n      \"im:message.p2p_msg:readonly\",\n      \"im:message:send_as_bot\",\n      \"im:resource\"\n    ],\n    \"user\": []\n  }\n}\n")
        print("    然后点击“下一步”，点击“确认新增权限”，然后点击“申请开通”，最后点击“确认”。")
        input("    完成后请按回车键继续...")
        print("\n[*] 第五步：在飞书平台左侧菜单选择“事件与回调”。")
        print("    为了能够开启“长连接”，请在另一个终端运行以下命令（已自动填充您的 ID 和 Secret）：")
        print(f"\n    python3 -c \"import lark_oapi as lark; h=lark.EventDispatcherHandler.builder('','').build(); c=lark.ws.Client(app_id='{config['feishu_app_id']}', app_secret='{config['feishu_app_secret']}', event_handler=h); c.start()\"\n")
        print("    运行后，返回网页，左侧菜单栏选择“事件与回调”，在“事件配置-订阅方式”中选择“使用长连接接收事件”，然后点击“保存”。")
        input("    完成后（且已关闭上述临时终端）请按回车键继续...")
        print("[*] 第六步：在“事件与回调”页面，点击“添加事件”，搜索并添加“接收消息 (im.message.receive_v1)”。")
        input("    完成后请按回车键继续...")
        print("[*] 第七步：左侧菜单选择“版本管理与发布”，点击“创建版本”，输入相关信息，保存后确认发布。")
        input("    完成后请按回车键继续...")

        print("\n[✓] 飞书配置完成！运行 mmclaw 后，在飞书 APP 中搜索刚才创建的应用名，并发送终端显示的 6 位验证码即可完成身份绑定。")
    elif choice == "2":
        config["preferred_mode"] = "telegram"
        print("\n--- 🛠 Telegram Setup ---")
        config["telegram_token"] = ask("Bot API Token", "telegram_token", "")
        user_id = ask("Your User ID", "telegram_authorized_user_id", "0")
        config["telegram_authorized_user_id"] = int(user_id) if str(user_id).isdigit() else 0
    elif choice == "3":
        config["preferred_mode"] = "whatsapp"
        print("\n--- 🛠 WhatsApp Setup ---")
        print("[*] No tokens needed. You will scan a QR code in your terminal on run.")
    elif choice == "1":
        config["preferred_mode"] = "terminal"

    # 3. Save
    ConfigManager.save(config)
    return config

def main():
    import sys
    # Force unbuffered output for nohup/logging
    if hasattr(sys.stdout, 'reconfigure'):
        sys.stdout.reconfigure(line_buffering=True)
        sys.stderr.reconfigure(line_buffering=True)

    parser = argparse.ArgumentParser(description="MMClaw: Your autonomous multimodal AI agent.")
    parser.add_argument("command", nargs="?", help="Command to run (run, config)")
    parser.add_argument("--debug", action="store_true", help="Enable debug output (show raw LLM and Tool data)")
    args = parser.parse_args()

    config = ConfigManager.load()
    
    if args.command == "config":
        run_setup(config)
        return
    
    # Empty command or 'run' both trigger the agent
    if args.command not in [None, "run"]:
        parser.print_help()
        return

    if not config:
        config = run_setup()

    config["debug"] = args.debug  # Store debug state in config dict for easy passing

    # Mode Dispatch
    mode = config.get("preferred_mode")
    if mode == "telegram":
        connector = TelegramConnector(config["telegram_token"], config["telegram_authorized_user_id"])
    elif mode == "whatsapp":
        connector = WhatsAppConnector()
    elif mode == "feishu":
        connector = FeishuConnector(config["feishu_app_id"], config["feishu_app_secret"])
    else:
        connector = TerminalConnector()

    if config["api_key"] == "sk-your-key-here":
        print(f"\n[❌] API Key missing. Please run 'mmclaw config' or edit {ConfigManager.CONFIG_FILE}")
        return
    
    app = MMClaw(config, connector, system_prompt=ConfigManager.get_full_prompt(mode=mode))
    app.run()

if __name__ == "__main__":
    main()