import subprocess
from pathlib import Path
import streamlit as st
import streamlit_shadcn_ui as ui
from streamlit_option_menu import option_menu
from streamlit_extras.metric_cards import style_metric_cards
from streamlit_extras.stoggle import stoggle
from streamlit_agraph import agraph, Node, Edge, Config
from streamlit_jodit import st_jodit
import markdown
from markdownify import markdownify

from cmdop_claude import Client
from cmdop_claude.models.mcp import ClaudeSettings

def render_auditor(client: Client) -> None:
    """Render the Context Health Auditor with smarter metrics."""
    stats = client.get_project_dashboard_stats()
    
    col_title, col_score = st.columns([3, 1])
    with col_title:
        st.header(f"🚀 {stats.project_name}")
        st.markdown(f"**Cognitive Intelligence Board** — Deep audit of your `.claude` environment.")
    
    with col_score:
        # Simple color mapping for health score
        color = "#4BFF4B" if stats.health_score > 80 else "#FFA500" if stats.health_score > 50 else "#FF4B4B"
        st.markdown(f"""
            <div style="text-align: right; padding: 10px; border-radius: 10px; background: #1E1E1E; border-right: 5px solid {color};">
                <div style="font-size: 0.8rem; color: #888;">HEALTH SCORE</div>
                <div style="font-size: 2rem; font-weight: bold; color: {color};">{int(stats.health_score)}%</div>
            </div>
        """, unsafe_allow_html=True)

    st.write("---")
    
    # Row 1: Key Metrics
    m1, m2, m3, m4 = st.columns(4)
    with m1:
        st.metric("Context Weight", f"{stats.claude_md_lines} L", delta="Lines" if stats.claude_md_lines < 50 else "High Load", delta_color="normal" if stats.claude_md_lines < 50 else "inverse")
    with m2:
        st.metric("Skill Library", f"{stats.skill_count}", delta="Modular")
    with m3:
        st.metric("MCP Servers", f"{stats.mcp_count}", delta="Connected")
    with m4:
        st.metric("Hook Hooks", f"{stats.hook_count}", delta="Active")
        
    style_metric_cards(
        background_color="#1E1E1E",
        border_left_color="#3B82F6",
        border_radius_px=8
    )
    
    st.write("---")
    
    # Row 2: Status and Recommendations
    col_status, col_recs = st.columns([1, 1])
    
    with col_status:
        st.subheader("🛠️ Environment Status")
        if stats.health_score > 80:
            st.success("Claude environment is highly optimized and modular.", icon="✨")
        elif stats.health_score > 50:
            st.warning("Environment is functional but could benefit from refactoring.", icon="⚠️")
        else:
            st.error("Severe cognitive load detected. Project performance may degrade.", icon="🚨")
            
        with st.container(border=True):
            st.markdown("**Active Components**")
            st.write(f"📂 **Project Path:** `{Path('.').absolute()}`")
            st.write(f"🧠 **Primary Memory:** `CLAUDE.md` ({stats.claude_md_lines} lines)")
            st.write(f"🧬 **Skills Registry:** {stats.skill_count} active workflows")
            st.write(f"🔗 **Event Hooks:** {stats.hook_count} configured triggers")

    with col_recs:
        st.subheader("💡 Smart Recommendations")
        if not stats.recommendations:
            st.markdown("No urgent actions needed. Your project structure is elite. 🏆")
        else:
            for rec in stats.recommendations:
                st.info(rec, icon="💡")

def render_skills(client: Client) -> None:
    """Render the Skill Studio."""
    st.header("Skill Studio")
    st.markdown("Manage independent capabilities that Claude can invoke dynamically.")
    
    with st.expander("➕ Create New Skill"):
        with st.form("create_skill_form"):
            new_name = st.text_input("Skill Name (e.g., Code Reviewer)")
            new_desc = st.text_input("Description (helps Claude know when to use it)")
            submitted = st.form_submit_button("Provision Skill")
            if submitted:
                if new_name:
                    try:
                        client.skills.create_skill(new_name, new_desc)
                        st.success(f"Skill '{new_name}' created successfully!", icon="✅")
                        st.rerun()
                    except Exception as e:
                        st.error(f"Failed to create skill: {e}")
                else:
                    st.error("Name is required.")
                    
    st.write("---")
    st.markdown("### 📚 Quick Start Templates")
    st.markdown("Scaffold production-grade community templates in one click.")
    col_t1, col_t2, col_t3 = st.columns(3)
    try:
        with col_t1:
            if ui.button("Code Reviewer", key="btn_tpl_cr"):
                client.skills.create_skill("code_reviewer", "Deep PR review for TypeScript and error handling")
                client.skills.update_skill_content("code_reviewer", "# Code Reviewer\n1. Validate strict types\n2. Check test coverage\n3. Review for obvious security flags")
                st.rerun()
        with col_t2:
            if ui.button("Test Generator", key="btn_tpl_tg"):
                client.skills.create_skill("test_gen", "Outputs TDD tests based on requirement specs")
                client.skills.update_skill_content("test_gen", "# Test Gen\nWhen asked to write a test:\n1. Use pytest or jest\n2. Cover edge cases")
                st.rerun()
        with col_t3:
            if ui.button("Refactoring", key="btn_tpl_ref"):
                client.skills.create_skill("refactor_expert", "Breaks down complex functions safely")
                client.skills.update_skill_content("refactor_expert", "# Refactor Expert\nRules:\n1. Never change business logic\n2. Use pure functions where possible")
                st.rerun()
    except Exception as e:
        st.error(f"Failed to scaffold: {e}")
    
    st.write("---")
    
    skills = client.skills.list_skills()
    
    if not skills:
        st.info("No skills found in the `.claude/skills` directory.")
        return
        
    for name, skill in skills.items():
        with st.container(border=True):
            st.subheader(f"✨ {skill.name or name}")
            
            if skill.description:
                stoggle("View Skill Description", skill.description)
            
            
            st.write("---")
            
            tab_settings, tab_editor = st.tabs(["⚙️ Settings", "📝 Prompt Editor"])
            
            with tab_settings:
                col1, col2, col3 = st.columns([1, 2, 2])
                
                with col1:
                    st.markdown("**Auto-Activation**")
                    is_manual = ui.switch(default_checked=skill.disable_model_invocation, label="Manual Only", key=f"switch_{name}")
                
                with col2:
                    st.markdown("**Allowed Tools**")
                    allowed_tools = st.multiselect("Select Tools", options=["Read", "Write", "Bash"], default=skill.allowed_tools, key=f"tools_{name}", label_visibility="collapsed")
                
                with col3:
                    st.markdown("**Actions**")
                    col_save, col_open = st.columns(2)
                    with col_save:
                        if ui.button("Save Settings", key=f"btn_save_{name}"):
                            skill.disable_model_invocation = is_manual
                            skill.allowed_tools = allowed_tools
                            try:
                                client.skills.update_skill(name, skill)
                                st.success("Updated successfully!", icon="✅")
                            except Exception as e:
                                st.error(f"Failed to update {name}: {e}")
                    with col_open:
                        if st.button("📂 Reveal Folder", key=f"btn_reveal_{name}"):
                            folder_path = client.skills.get_skill_dir_path(name)
                            try:
                                subprocess.run(['open', str(folder_path)], check=True)
                            except Exception as e:
                                st.error(f"Could not open folder: {e}")
            
            with tab_editor:
                current_content = client.skills.get_skill_content(name)
                
                st.markdown("### Markdown Instructions")
                
                # Check for dark mode to apply custom styling
                is_dark = st.session_state.get('theme', 'dark') == 'dark'
                
                if is_dark:
                    st.markdown("""
                        <style>
                        /* Target the Streamlit Iframe that holds Jodit */
                        iframe[title="streamlit_jodit.st_jodit"] {
                            color-scheme: dark;
                        }
                        /* Optional overrides for wrapper containers if needed */
                        </style>
                        """, unsafe_allow_html=True)
                        
                # Convert markdown to HTML for Jodit
                html_content = markdown.markdown(current_content)
                
                # Jodit WYSIWYG Editor
                # Using Streamlit's default dark theme hex: #0e1117
                is_dark = st.session_state.get('theme', 'dark') == 'dark'
                
                jodit_config = {
                    "height": 500,
                    "theme": "dark" if is_dark else "default",
                }
                
                if is_dark:
                    jodit_config["style"] = {
                        "background": "#0e1117",
                        "color": "#fafafa"
                    }
                    # We can try to pass additional config settings for toolbars
                    jodit_config["toolbarButtonSize"] = "middle"
                
                new_html = st_jodit(
                    value=html_content,
                    config=jodit_config,
                    key=f"editor_{name}"
                )
                
                # Save button directly underneath
                if ui.button("Save Prompt", key=f"btn_save_content_{name}"):
                    try:
                        # Convert HTML back to markdown cleanly
                        if new_html:
                            new_markdown = markdownify(new_html, heading_style="ATX", strip=['p']).strip()
                            client.skills.update_skill_content(name, new_markdown)
                            st.success("Prompt instructions saved!", icon="✅")
                    except Exception as e:
                        st.error(f"Failed to save content: {e}")

def render_settings(client: Client) -> None:
    """Render the Settings & Guardrails."""
    st.header("Settings & Security")
    
    tab_p, tab_u, tab_l, tab_guard = st.tabs(["📁 Project", "👤 User", "💻 Local", "🛡️ Guardrails"])
    
    with tab_p:
        st.subheader("Project Settings")
        st.markdown("`.claude/settings.json` — Shared with the team.")
        settings = client.mcp.get_settings("project")
        # Simple JSON editor for now
        new_json = st.text_area("JSON Configuration", value=settings.model_dump_json(indent=2), height=200, key="settings_p")
        if ui.button("Save Project Settings", key="btn_save_settings_p"):
            try:
                client.mcp.write_settings(ClaudeSettings.model_validate_json(new_json), "project")
                st.success("Project settings saved!")
            except Exception as e:
                st.error(f"Invalid JSON: {e}")

    with tab_u:
        st.subheader("Global User Settings")
        st.markdown("`~/.claude/settings.json` — Your personal defaults.")
        settings = client.mcp.get_settings("user")
        new_json = st.text_area("JSON Configuration", value=settings.model_dump_json(indent=2), height=200, key="settings_u")
        if ui.button("Save User Settings", key="btn_save_settings_u"):
            try:
                client.mcp.write_settings(ClaudeSettings.model_validate_json(new_json), "user")
                st.success("User settings saved!")
            except Exception as e:
                st.error(f"Invalid JSON: {e}")

    with tab_l:
        st.subheader("Local Overrides")
        st.markdown("`.claude/settings.local.json` — Ignored by Git.")
        settings = client.mcp.get_settings("local")
        new_json = st.text_area("JSON Configuration", value=settings.model_dump_json(indent=2), height=200, key="settings_l")
        if ui.button("Save Local Settings", key="btn_save_settings_l"):
            try:
                client.mcp.write_settings(ClaudeSettings.model_validate_json(new_json), "local")
                st.success("Local settings saved!")
            except Exception as e:
                st.error(f"Invalid JSON: {e}")

    with tab_guard:
        perms = client.claude.get_permissions()
        if not perms:
            st.info("No `.permissions.json` found.")
        else:
            st.markdown("Control what tools Claude can run globally without confirmation.")
            col1, col2 = st.columns(2)
            with col1:
                with st.container(border=True):
                    st.subheader("📁 File Operations")
                    read_op = ui.switch(default_checked=perms.allowed_operations.file_operations.read, label="Read", key="sw_read")
                    create_op = ui.switch(default_checked=perms.allowed_operations.file_operations.create, label="Create", key="sw_create")
                    edit_op = ui.switch(default_checked=perms.allowed_operations.file_operations.edit, label="Edit", key="sw_edit")
                    delete_op = ui.switch(default_checked=perms.allowed_operations.file_operations.delete, label="Delete", key="sw_delete")
            with col2:
                with st.container(border=True):
                    st.subheader("🛡️ System & Execution")
                    run_scripts_op = ui.switch(default_checked=perms.allowed_operations.code_execution.run_scripts, label="Run Scripts", key="sw_run_scripts")
                    run_tests_op = ui.switch(default_checked=perms.allowed_operations.code_execution.run_tests, label="Run Tests", key="sw_run_tests")
                    install_op = ui.switch(default_checked=perms.allowed_operations.system_operations.install_packages, label="Install Packages", key="sw_install")
                    sudo_op = ui.switch(default_checked=perms.allowed_operations.system_operations.run_as_sudo, label="Run as Sudo", key="sw_sudo")
            
            if ui.button("Save Guardrails", key="btn_save_perms"):
                perms.allowed_operations.file_operations.read = read_op
                # ... same as before but inside tab ...
                perms.allowed_operations.file_operations.create = create_op
                perms.allowed_operations.file_operations.edit = edit_op
                perms.allowed_operations.file_operations.delete = delete_op
                perms.allowed_operations.code_execution.run_scripts = run_scripts_op
                perms.allowed_operations.code_execution.run_tests = run_tests_op
                perms.allowed_operations.system_operations.install_packages = install_op
                perms.allowed_operations.system_operations.run_as_sudo = sudo_op
                try:
                    client.claude.write_permissions(perms)
                    st.success("Guardrails saved!")
                except Exception as e:
                    st.error(f"Failed: {e}")

def render_mcp_studio(client: Client) -> None:
    """Render the MCP Server Studio."""
    st.header("MCP Server Studio")
    st.markdown("Orchestrate **Model Context Protocol** servers to extend Claude's capabilities.")
    
    col_g, col_p = st.columns(2)
    
    with col_g:
        st.subheader("🌍 Global Servers")
        st.markdown("`~/.claude.json`")
        global_cfg = client.mcp.get_global_mcp_config()
        if not global_cfg.mcpServers:
            st.info("No global MCP servers configured.")
        for name, cfg in global_cfg.mcpServers.items():
            with st.container(border=True):
                st.markdown(f"**{name}**")
                st.code(f"{cfg.command} {' '.join(cfg.args)}")
                
    with col_p:
        st.subheader("📁 Project Servers")
        st.markdown("`.mcp.json`")
        project_cfg = client.mcp.get_project_mcp_config()
        if not project_cfg.mcpServers:
            st.info("No project-level MCP servers.")
        for name, cfg in project_cfg.mcpServers.items():
            with st.container(border=True):
                st.markdown(f"**{name}**")
                st.code(f"{cfg.command} {' '.join(cfg.args)}")

    st.write("---")
    with st.expander("➕ Connect New MCP Server"):
        with st.form("add_mcp_form"):
            s_name = st.text_input("Server Name")
            s_cmd = st.text_input("Command (e.g. npx, python)")
            s_args = st.text_input("Arguments (space separated)")
            s_scope = st.selectbox("Scope", ["Project", "Global"])
            submitted = st.form_submit_button("Connect Server")
            if submitted and s_name and s_cmd:
                try:
                    from cmdop_claude.models.mcp import MCPServerConfig
                    new_srv = MCPServerConfig(command=s_cmd, args=s_args.split() if s_args else [])
                    if s_scope == "Project":
                        cfg = client.mcp.get_project_mcp_config()
                        cfg.mcpServers[s_name] = new_srv
                        client.mcp.write_project_mcp_config(cfg)
                    else:
                        cfg = client.mcp.get_global_mcp_config()
                        cfg.mcpServers[s_name] = new_srv
                        client.mcp.write_global_mcp_config(cfg)
                    st.success(f"Server {s_name} connected!")
                    st.rerun()
                except Exception as e:
                    st.error(f"Failed to connect: {e}")

def render_hooks(client: Client) -> None:
    """Render the Hooks Management Studio."""
    st.header("Hooks Management Studio")
    st.markdown("Deterministically enforce guardrails via pre and post tool hooks.")
    
    hooks = client.hooks.list_hooks()
    
    if not hooks:
        st.info("No hooks found in the `.claude/hooks` directory.")
        return
        
    for name, hook in hooks.items():
        with st.container(border=True):
            st.subheader(f"🪝 {name}.json")
            st.write("---")
            
            tab_cfg, tab_editor = st.tabs(["⚙️ Configuration", "📝 Script Editor"])
            
            with tab_cfg:
                col1, col2 = st.columns(2)
                with col1:
                    st.markdown("**Events (Triggers)**")
                    st.code(", ".join(hook.events))
                with col2:
                    st.markdown("**Target Script**")
                    st.code(hook.script)
                    if hook.args:
                        st.markdown("**Arguments**")
                        st.code(" ".join(hook.args))
            
            with tab_editor:
                current_script = client.hooks.get_hook_script(hook.script)
                if current_script:
                    new_script = st.text_area("Shell Script", value=current_script, height=200, key=f"script_{name}")
                    if ui.button("Save Script", key=f"btn_save_script_{name}"):
                        try:
                            client.hooks.update_hook_script(hook.script, new_script)
                            st.success("Script updated successfully!", icon="✅")
                        except Exception as e:
                            st.error(f"Failed to update script: {e}")
                else:
                    st.error(f"Target script not found: {hook.script}", icon="🚨")

def render_graph(client: Client) -> None:
    """Render the Context Dependency Graph (Trigger Matrix)."""
    st.header("Context Dependency Graph")
    st.markdown("Visual matrix of how your `.claude` folder routes context between elements.")
    
    nodes = []
    edges = []
    
    # Root Node
    nodes.append(Node(id="CLAUDE", label="CLAUDE.md", size=25, color="#FF4B4B", shape="diamond"))
    
    # Add Skills
    skills = client.skills.list_skills()
    for i, (name, skill) in enumerate(skills.items()):
        node_id = f"skill_{name}"
        nodes.append(Node(id=node_id, label=name, size=15, color="#4BFF4B", shape="hexagon"))
        edges.append(Edge(source="CLAUDE", target=node_id, label="agent" if not skill.disable_model_invocation else "manual"))
        
    # Add Hooks
    hooks = client.hooks.list_hooks()
    for name, hook in hooks.items():
        node_id = f"hook_{name}"
        nodes.append(Node(id=node_id, label=name, size=15, color="#4B4BFF", shape="dot"))
        edges.append(Edge(source="CLAUDE", target=node_id, label=",".join(hook.events)))

    config = Config(width="100%", height=600, directed=True, physics=True, hierarchical=False)
    
    if len(nodes) > 1:
        agraph(nodes=nodes, edges=edges, config=config)
    else:
        st.info("Add some skills and hooks to see the dependency graph.")

def render_sidecar(client: Client) -> None:
    """Render the Sidecar Monitor tab."""
    st.header("Sidecar Monitor")
    st.markdown("Documentation librarian — finds staleness, contradictions, and gaps in `.claude/` files.")

    status = client.sidecar.get_status()

    # Status row
    s1, s2, s3, s4 = st.columns(4)
    with s1:
        st.metric("Last Scan", status.last_run.strftime("%Y-%m-%d") if status.last_run else "Never")
    with s2:
        st.metric("Pending Items", status.pending_items)
    with s3:
        st.metric("Suppressed", status.suppressed_items)
    with s4:
        st.metric("Tokens Today", status.tokens_today)

    style_metric_cards(
        background_color="#1E1E1E",
        border_left_color="#8B5CF6",
        border_radius_px=8,
    )

    # MCP Registration
    mcp_registered = client.sidecar.is_mcp_registered()
    st.write("---")
    mcp_col1, mcp_col2 = st.columns([3, 1])
    with mcp_col1:
        if mcp_registered:
            st.success("MCP server registered in .mcp.json")
        else:
            st.warning("MCP server not registered — Claude cannot call sidecar tools")
    with mcp_col2:
        if mcp_registered:
            if ui.button("Unregister MCP", key="btn_mcp_unreg"):
                client.sidecar.unregister_mcp()
                st.rerun()
        else:
            if ui.button("Register MCP", key="btn_mcp_reg"):
                client.sidecar.register_mcp()
                st.rerun()

    st.write("---")

    # Actions
    col_scan, col_status = st.columns(2)
    with col_scan:
        if ui.button("Run Scan Now", key="btn_sidecar_scan"):
            with st.spinner("Scanning documentation..."):
                try:
                    result = client.sidecar.generate_review()
                    st.success(f"Review generated: {len(result.items)} items found ({result.tokens_used} tokens)")
                    st.rerun()
                except RuntimeError as e:
                    st.warning(f"Skipped: {e}")
                except Exception as e:
                    st.error(f"Scan failed: {e}")

    with col_status:
        if ui.button("Refresh Status", key="btn_sidecar_refresh"):
            st.rerun()

    st.write("---")

    # Current review
    sidecar_dir = Path(client._config.claude_dir_path) / ".sidecar"
    review_path = sidecar_dir / "review.md"

    if review_path.exists():
        st.subheader("Current Review")
        review_text = review_path.read_text(encoding="utf-8")
        st.markdown(review_text)

        # Acknowledge buttons
        st.write("---")
        st.subheader("Manage Items")
        st.markdown("Suppress an item by entering its ID (shown in parentheses in the review).")
        with st.form("acknowledge_form"):
            ack_id = st.text_input("Item ID to suppress")
            ack_days = st.number_input("Suppress for N days", min_value=1, max_value=365, value=30)
            if st.form_submit_button("Suppress"):
                if ack_id:
                    client.sidecar.acknowledge(ack_id, int(ack_days))
                    st.success(f"Suppressed {ack_id} for {ack_days} days")
    else:
        st.info("No review yet. Click 'Run Scan Now' to generate the first review.")

    # History
    history_dir = sidecar_dir / "history"
    if history_dir.exists():
        history_files = sorted(history_dir.glob("*.md"), reverse=True)
        if history_files:
            st.write("---")
            with st.expander("Past Reviews"):
                for hf in history_files[:10]:
                    st.markdown(f"**{hf.stem}**")
                    st.text(hf.read_text(encoding="utf-8")[:500])
                    st.write("---")


def render_project_map(client: Client) -> None:
    """Render the Project Map tab."""
    st.header("Project Map")
    st.markdown("Auto-generated navigable project structure with LLM annotations.")

    # Actions
    col_gen, col_refresh = st.columns(2)
    with col_gen:
        if ui.button("Generate / Update Map", key="btn_map_gen"):
            with st.spinner("Generating project map..."):
                try:
                    result = client.sidecar.generate_map()
                    st.success(
                        f"Map updated: {len(result.directories)} dirs, "
                        f"{len(result.entry_points)} entry points "
                        f"({result.tokens_used} tokens, {result.model_used})"
                    )
                    st.rerun()
                except Exception as e:
                    st.error(f"Map generation failed: {e}")
    with col_refresh:
        if ui.button("Refresh View", key="btn_map_refresh"):
            st.rerun()

    st.write("---")

    # Display current map
    map_content = client.sidecar.get_current_map()
    if map_content:
        st.markdown(map_content)
    else:
        st.info("No project map yet. Click 'Generate / Update Map' to create one.")


def render_task_queue(client: Client) -> None:
    """Render the Task Queue tab."""
    st.header("Task Queue")
    st.markdown("Structured tasks from sidecar reviews and manual entries.")

    # Create task form
    with st.expander("➕ Create New Task"):
        with st.form("create_task_form"):
            t_title = st.text_input("Title")
            t_desc = st.text_area("Description (markdown)")
            t_priority = st.selectbox("Priority", ["medium", "high", "critical", "low"])
            t_files = st.text_input("Context Files (comma separated)")
            submitted = st.form_submit_button("Create Task")
            if submitted and t_title and t_desc:
                try:
                    files = [f.strip() for f in t_files.split(",") if f.strip()] if t_files else None
                    task = client.sidecar.create_task(
                        title=t_title,
                        description=t_desc,
                        priority=t_priority,
                        context_files=files,
                    )
                    st.success(f"Created task {task.id}: {task.title}")
                    st.rerun()
                except Exception as e:
                    st.error(f"Failed to create task: {e}")

    st.write("---")

    # Filter
    status_filter = st.selectbox(
        "Filter by status",
        ["all", "pending", "in_progress", "completed", "dismissed"],
        key="task_status_filter",
    )

    tasks = client.sidecar.list_tasks(
        status=status_filter if status_filter != "all" else None
    )

    if not tasks:
        st.info("No tasks found.")
        return

    # Summary metrics
    t1, t2, t3, t4 = st.columns(4)
    all_tasks = client.sidecar.list_tasks()
    pending_count = sum(1 for t in all_tasks if t.status == "pending")
    in_progress_count = sum(1 for t in all_tasks if t.status == "in_progress")
    completed_count = sum(1 for t in all_tasks if t.status == "completed")
    with t1:
        st.metric("Total", len(all_tasks))
    with t2:
        st.metric("Pending", pending_count)
    with t3:
        st.metric("In Progress", in_progress_count)
    with t4:
        st.metric("Completed", completed_count)

    style_metric_cards(
        background_color="#1E1E1E",
        border_left_color="#F59E0B",
        border_radius_px=8,
    )

    st.write("---")

    # Task list
    priority_colors = {
        "critical": "#FF4B4B",
        "high": "#F59E0B",
        "medium": "#3B82F6",
        "low": "#6B7280",
    }

    for task in tasks:
        color = priority_colors.get(task.priority, "#6B7280")
        with st.container(border=True):
            col_info, col_actions = st.columns([3, 1])
            with col_info:
                st.markdown(
                    f"<span style='color:{color};font-weight:bold;'>[{task.priority}]</span> "
                    f"**{task.title}** <small>(id: {task.id}, status: {task.status})</small>",
                    unsafe_allow_html=True,
                )
                if task.context_files:
                    st.caption(f"Files: {', '.join(task.context_files)}")
                with st.expander("Description"):
                    st.markdown(task.description)

            with col_actions:
                if task.status == "pending":
                    if ui.button("Start", key=f"btn_start_{task.id}"):
                        client.sidecar.update_task_status(task.id, "in_progress")
                        st.rerun()
                    if ui.button("Dismiss", key=f"btn_dismiss_{task.id}"):
                        client.sidecar.update_task_status(task.id, "dismissed")
                        st.rerun()
                elif task.status == "in_progress":
                    if ui.button("Complete", key=f"btn_complete_{task.id}"):
                        client.sidecar.update_task_status(task.id, "completed")
                        st.rerun()


def main() -> None:
    """Main application loop."""
    st.set_page_config(
        page_title="Claude Control Plane",
        page_icon="🤖",
        layout="wide",
        initial_sidebar_state="expanded"
    )
    
    # Initialize the client
    client = Client()

    with st.sidebar:
        st.markdown("### 🤖 Command Center")
        selected = option_menu(
            menu_title=None,
            options=["Health Auditor", "Skill Studio", "MCP Studio", "Hooks Manager", "Sidecar Monitor", "Project Map", "Task Queue", "Settings & Security", "Trigger Graph"],
            icons=["heart-pulse", "stars", "box", "plug", "book", "map", "list-task", "shield-lock", "diagram-project"],
            menu_icon="cast",
            default_index=0,
            styles={
                "nav-link": {"font-size": "14px", "text-align": "left", "margin": "0px", "--hover-color": "#2c2c2c"},
                "nav-link-selected": {"background-color": "#FF4B4B"},
            }
        )
    
    # Render the selected tab
    if selected == "Health Auditor":
        render_auditor(client)
    elif selected == "Skill Studio":
        render_skills(client)
    elif selected == "MCP Studio":
        render_mcp_studio(client)
    elif selected == "Hooks Manager":
        render_hooks(client)
    elif selected == "Sidecar Monitor":
        render_sidecar(client)
    elif selected == "Project Map":
        render_project_map(client)
    elif selected == "Task Queue":
        render_task_queue(client)
    elif selected == "Settings & Security":
        render_settings(client)
    elif selected == "Trigger Graph":
        render_graph(client)

if __name__ == "__main__":
    main()
