"""Dashboard command implementations for telemetry CLI.

Provides interactive HTML dashboard generation for telemetry data.

Copyright 2025 Smart-AI-Memory
Licensed under the Apache License, Version 2.0
"""

import http.server
import socketserver
import tempfile
import webbrowser
from collections import Counter
from datetime import datetime
from typing import Any

from ..usage_tracker import UsageTracker


def cmd_telemetry_dashboard(args: Any) -> int:
    """Open interactive telemetry dashboard in browser.

    Args:
        args: Parsed command-line arguments

    Returns:
        Exit code (0 for success)

    """
    tracker = UsageTracker.get_instance()
    entries = tracker.export_to_dict(days=getattr(args, "days", 30))

    if not entries:
        print("No telemetry data available.")
        return 0

    # Calculate statistics
    total_cost = sum(e.get("cost", 0) for e in entries)
    total_calls = len(entries)
    avg_duration = (
        sum(e.get("duration_ms", 0) for e in entries) / total_calls if total_calls > 0 else 0
    )

    # Tier distribution
    tiers = [e.get("tier", "UNKNOWN") for e in entries]
    tier_counts = Counter(tiers)
    tier_distribution = {tier: (count / total_calls) * 100 for tier, count in tier_counts.items()}

    # Calculate savings (baseline: all PREMIUM tier)
    premium_input_cost = 0.015 / 1000  # per token
    premium_output_cost = 0.075 / 1000  # per token

    baseline_cost = sum(
        (e.get("tokens", {}).get("input", 0) * premium_input_cost)
        + (e.get("tokens", {}).get("output", 0) * premium_output_cost)
        for e in entries
    )

    saved = baseline_cost - total_cost
    savings_pct = (saved / baseline_cost * 100) if baseline_cost > 0 else 0

    # Generate HTML
    html_content = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Empathy Telemetry Dashboard</title>
    <style>
        * {{ margin: 0; padding: 0; box-sizing: border-box; }}
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            padding: 20px;
            min-height: 100vh;
        }}
        .container {{
            max-width: 1400px;
            margin: 0 auto;
        }}
        .header {{
            color: white;
            text-align: center;
            margin-bottom: 40px;
        }}
        .header h1 {{
            font-size: 48px;
            font-weight: 700;
            margin-bottom: 10px;
        }}
        .header p {{
            font-size: 18px;
            opacity: 0.9;
        }}
        .stats-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }}
        .stat-card {{
            background: white;
            border-radius: 12px;
            padding: 30px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }}
        .savings-card {{
            grid-column: span 2;
            background: linear-gradient(135deg, #4caf50 0%, #45a049 100%);
            color: white;
        }}
        .stat-label {{
            font-size: 14px;
            text-transform: uppercase;
            letter-spacing: 1px;
            margin-bottom: 10px;
            opacity: 0.8;
        }}
        .stat-value {{
            font-size: 56px;
            font-weight: 700;
            margin-bottom: 5px;
        }}
        .stat-sublabel {{
            font-size: 16px;
            opacity: 0.7;
        }}
        .tier-distribution {{
            display: flex;
            gap: 10px;
            margin-top: 15px;
            height: 50px;
        }}
        .tier-bar {{
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 8px;
            font-weight: 600;
            color: white;
            font-size: 14px;
        }}
        .tier-premium {{ background: linear-gradient(135deg, #9c27b0, #7b1fa2); }}
        .tier-capable {{ background: linear-gradient(135deg, #2196f3, #1976d2); }}
        .tier-cheap {{ background: linear-gradient(135deg, #4caf50, #388e3c); }}
        table {{
            width: 100%;
            background: white;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        }}
        th, td {{
            padding: 16px;
            text-align: left;
        }}
        th {{
            background: #f5f5f5;
            font-weight: 600;
            font-size: 13px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
            color: #666;
        }}
        tr:hover {{
            background: #f9f9f9;
        }}
        .tier-badge {{
            display: inline-block;
            padding: 4px 10px;
            border-radius: 4px;
            font-size: 11px;
            font-weight: 600;
            color: white;
        }}
        .badge-premium {{ background: #9c27b0; }}
        .badge-capable {{ background: #2196f3; }}
        .badge-cheap {{ background: #4caf50; }}
        .cache-hit {{ color: #4caf50; font-weight: 600; }}
        .cache-miss {{ color: #999; }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 Empathy Telemetry Dashboard</h1>
            <p>Last {len(entries)} LLM API calls • Real-time cost tracking</p>
        </div>

        <div class="stats-grid">
            <div class="stat-card savings-card">
                <div class="stat-label">Cost Savings (Tier Routing)</div>
                <div class="stat-value">${saved:.2f}</div>
                <div class="stat-sublabel">
                    {savings_pct:.1f}% saved • Baseline: ${baseline_cost:.2f} • Actual: ${
        total_cost:.2f}
                </div>
            </div>

            <div class="stat-card">
                <div class="stat-label">Total Cost</div>
                <div class="stat-value">${total_cost:.2f}</div>
                <div class="stat-sublabel">{total_calls} API calls</div>
            </div>

            <div class="stat-card">
                <div class="stat-label">Avg Duration</div>
                <div class="stat-value">{avg_duration / 1000:.1f}s</div>
                <div class="stat-sublabel">Per API call</div>
            </div>
        </div>

        <div class="stat-card">
            <div class="stat-label">Tier Distribution</div>
            <div class="tier-distribution">
                {
        "".join(
            f'<div class="tier-bar tier-{tier.lower()}">{tier}: {pct:.1f}%</div>'
            for tier, pct in tier_distribution.items()
        )
    }
            </div>
        </div>

        <h2 style="color: white; margin: 40px 0 20px 0; font-size: 28px;">Recent LLM Calls</h2>
        <table>
            <thead>
                <tr>
                    <th>Time</th>
                    <th>Workflow</th>
                    <th>Stage</th>
                    <th>Tier</th>
                    <th>Cost</th>
                    <th>Tokens</th>
                    <th>Cache</th>
                    <th>Duration</th>
                </tr>
            </thead>
            <tbody>
                {
        "".join(
            f'''<tr>
                    <td>{datetime.fromisoformat(e.get("ts", "").replace("Z", "+00:00")).strftime("%H:%M:%S")}</td>
                    <td>{e.get("workflow", "")}</td>
                    <td>{e.get("stage", "")}</td>
                    <td><span class="tier-badge badge-{e.get("tier", "").lower()}">{e.get("tier", "")}</span></td>
                    <td>${e.get("cost", 0):.4f}</td>
                    <td>{e.get("tokens", {}).get("input", 0)}/{e.get("tokens", {}).get("output", 0)}</td>
                    <td class="cache-{"hit" if e.get("cache", {}).get("hit") else "miss"}">
                        {"HIT" if e.get("cache", {}).get("hit") else "MISS"}
                    </td>
                    <td>{e.get("duration_ms", 0) / 1000:.1f}s</td>
                </tr>'''
            for e in list(reversed(entries))[:20]
        )
    }
            </tbody>
        </table>
    </div>
</body>
</html>"""

    # Write to temp file
    with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f:
        f.write(html_content)
        temp_path = f.name

    print(f"📊 Opening dashboard in browser: {temp_path}")
    webbrowser.open(f"file://{temp_path}")

    return 0


def cmd_file_test_dashboard(args: Any) -> int:
    """Open interactive file test status dashboard in browser.

    Args:
        args: Parsed command-line arguments
            - port: Port to serve on (default: 8765)

    Returns:
        Exit code (0 for success)
    """
    from attune.models.telemetry import get_telemetry_store

    port = getattr(args, "port", 8765)

    def generate_dashboard_html() -> str:
        """Generate the dashboard HTML with current data."""
        store = get_telemetry_store()
        all_records = store.get_file_tests(limit=100000)

        if not all_records:
            return _generate_empty_dashboard()

        # Get latest record per file
        latest_by_file: dict[str, Any] = {}
        for record in all_records:
            existing = latest_by_file.get(record.file_path)
            if existing is None or record.timestamp > existing.timestamp:
                latest_by_file[record.file_path] = record

        records = list(latest_by_file.values())

        # Calculate stats
        total = len(records)
        passed = sum(1 for r in records if r.last_test_result == "passed")
        failed = sum(1 for r in records if r.last_test_result in ("failed", "error"))
        no_tests = sum(1 for r in records if r.last_test_result == "no_tests")
        stale = sum(1 for r in records if r.is_stale)

        # Sort by status priority: failed > stale > no_tests > passed
        def sort_key(r):
            if r.last_test_result in ("failed", "error"):
                return (0, r.file_path)
            if r.is_stale:
                return (1, r.file_path)
            if r.last_test_result == "no_tests":
                return (2, r.file_path)
            return (3, r.file_path)

        records.sort(key=sort_key)

        # Generate table rows
        rows_html = ""
        for record in records:
            result = record.last_test_result
            if result == "passed":
                status_class = "passed"
                status_icon = "✅"
            elif result in ("failed", "error"):
                status_class = "failed"
                status_icon = "❌"
            elif result == "no_tests":
                status_class = "no-tests"
                status_icon = "⚠️"
            else:
                status_class = "skipped"
                status_icon = "⏭️"

            stale_badge = '<span class="badge stale">STALE</span>' if record.is_stale else ""

            try:
                dt = datetime.fromisoformat(record.timestamp.rstrip("Z"))
                ts_display = dt.strftime("%Y-%m-%d %H:%M")
            except (ValueError, AttributeError):
                ts_display = record.timestamp[:16] if record.timestamp else "-"

            rows_html += f"""
            <tr class="{status_class}">
                <td class="file-path">{record.file_path}</td>
                <td class="status">{status_icon} {result.upper()} {stale_badge}</td>
                <td class="numeric">{record.test_count}</td>
                <td class="numeric passed-count">{record.passed}</td>
                <td class="numeric failed-count">{record.failed + record.errors}</td>
                <td class="numeric">{record.duration_seconds:.1f}s</td>
                <td class="timestamp">{ts_display}</td>
            </tr>
            """

        return (
            """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Test Status Dashboard</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #ffffff;
            color: #333;
            padding: 20px;
            min-height: 100vh;
        }
        .container { max-width: 1600px; margin: 0 auto; }
        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 1px solid #e0e0e0;
        }
        .header h1 { font-size: 28px; color: #333; }
        .refresh-btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: transform 0.2s, box-shadow 0.2s;
        }
        .refresh-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
        }
        .refresh-btn:active { transform: translateY(0); }
        .refresh-btn.spinning .icon { animation: spin 1s linear infinite; }
        @keyframes spin { 100% { transform: rotate(360deg); } }
        .stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }
        .stat-card {
            background: #f8f9fa;
            border-radius: 12px;
            padding: 20px;
            text-align: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }
        .stat-card.passed { border-left: 4px solid #22c55e; }
        .stat-card.failed { border-left: 4px solid #ef4444; }
        .stat-card.no-tests { border-left: 4px solid #f59e0b; }
        .stat-card.stale { border-left: 4px solid #8b5cf6; }
        .stat-card.total { border-left: 4px solid #3b82f6; }
        .stat-value { font-size: 36px; font-weight: bold; }
        .stat-label { font-size: 14px; color: #666; margin-top: 5px; }
        .stat-card.passed .stat-value { color: #22c55e; }
        .stat-card.failed .stat-value { color: #ef4444; }
        .stat-card.no-tests .stat-value { color: #f59e0b; }
        .stat-card.stale .stat-value { color: #8b5cf6; }
        .stat-card.total .stat-value { color: #3b82f6; }
        .filter-bar {
            display: flex;
            gap: 10px;
            margin-bottom: 20px;
            flex-wrap: wrap;
        }
        .filter-btn {
            background: #f8f9fa;
            color: #666;
            border: 1px solid #e0e0e0;
            padding: 8px 16px;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s;
        }
        .filter-btn:hover, .filter-btn.active {
            background: #667eea;
            color: #fff;
            border-color: #667eea;
        }
        .search-input {
            flex: 1;
            min-width: 200px;
            background: #fff;
            border: 1px solid #e0e0e0;
            color: #333;
            padding: 8px 16px;
            border-radius: 6px;
            font-size: 14px;
        }
        .search-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }
        table {
            width: 100%;
            border-collapse: collapse;
            background: #fff;
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
        }
        th, td { padding: 12px 16px; text-align: left; }
        th {
            background: #f8f9fa;
            font-weight: 600;
            color: #333;
            position: sticky;
            top: 0;
            border-bottom: 2px solid #e0e0e0;
        }
        tr { border-bottom: 1px solid #f0f0f0; }
        tr:hover { background: #f8f9fa; }
        tr.failed { background: rgba(239, 68, 68, 0.08); }
        tr.no-tests { background: rgba(245, 158, 11, 0.05); }
        .file-path { font-family: 'Monaco', 'Menlo', monospace; font-size: 13px; color: #333; }
        .numeric { text-align: right; font-family: monospace; }
        .passed-count { color: #22c55e; }
        .failed-count { color: #ef4444; }
        .timestamp { color: #888; font-size: 12px; }
        .badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 10px;
            font-weight: bold;
            margin-left: 8px;
        }
        .badge.stale { background: #8b5cf6; color: #fff; }
        .hidden { display: none; }
        .last-updated { color: #888; font-size: 12px; margin-top: 20px; text-align: center; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 File Test Status Dashboard</h1>
            <button class="refresh-btn" onclick="refreshData()">
                <span class="icon">🔄</span>
                <span>Refresh</span>
            </button>
        </div>

        <div class="stats">
            <div class="stat-card total">
                <div class="stat-value">"""
            + str(total)
            + """</div>
                <div class="stat-label">Total Files</div>
            </div>
            <div class="stat-card passed">
                <div class="stat-value">"""
            + str(passed)
            + """</div>
                <div class="stat-label">Passed</div>
            </div>
            <div class="stat-card failed">
                <div class="stat-value">"""
            + str(failed)
            + """</div>
                <div class="stat-label">Failed</div>
            </div>
            <div class="stat-card no-tests">
                <div class="stat-value">"""
            + str(no_tests)
            + """</div>
                <div class="stat-label">No Tests</div>
            </div>
            <div class="stat-card stale">
                <div class="stat-value">"""
            + str(stale)
            + """</div>
                <div class="stat-label">Stale</div>
            </div>
        </div>

        <div class="filter-bar">
            <button class="filter-btn active" data-filter="all">All</button>
            <button class="filter-btn" data-filter="passed">✅ Passed</button>
            <button class="filter-btn" data-filter="failed">❌ Failed</button>
            <button class="filter-btn" data-filter="no-tests">⚠️ No Tests</button>
            <button class="filter-btn" data-filter="stale">🔄 Stale</button>
            <input type="text" class="search-input" placeholder="Search files..." id="searchInput">
        </div>

        <table id="fileTable">
            <thead>
                <tr>
                    <th>File Path</th>
                    <th>Status</th>
                    <th>Tests</th>
                    <th>Passed</th>
                    <th>Failed</th>
                    <th>Duration</th>
                    <th>Last Run</th>
                </tr>
            </thead>
            <tbody>
                """
            + rows_html
            + """
            </tbody>
        </table>

        <div class="last-updated">
            Last updated: """
            + datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            + """
        </div>
    </div>

    <script>
        // Filter functionality
        const filterBtns = document.querySelectorAll('.filter-btn');
        const rows = document.querySelectorAll('#fileTable tbody tr');
        const searchInput = document.getElementById('searchInput');

        let currentFilter = 'all';

        filterBtns.forEach(btn => {
            btn.addEventListener('click', () => {
                filterBtns.forEach(b => b.classList.remove('active'));
                btn.classList.add('active');
                currentFilter = btn.dataset.filter;
                applyFilters();
            });
        });

        searchInput.addEventListener('input', applyFilters);

        function applyFilters() {
            const searchTerm = searchInput.value.toLowerCase();
            rows.forEach(row => {
                const filePath = row.querySelector('.file-path').textContent.toLowerCase();
                const matchesSearch = filePath.includes(searchTerm);
                const matchesFilter = currentFilter === 'all' ||
                    (currentFilter === 'passed' && row.classList.contains('passed')) ||
                    (currentFilter === 'failed' && row.classList.contains('failed')) ||
                    (currentFilter === 'no-tests' && row.classList.contains('no-tests')) ||
                    (currentFilter === 'stale' && row.innerHTML.includes('STALE'));

                row.classList.toggle('hidden', !(matchesSearch && matchesFilter));
            });
        }

        // Refresh functionality
        function refreshData() {
            const btn = document.querySelector('.refresh-btn');
            btn.classList.add('spinning');
            btn.disabled = true;

            // Reload the page to get fresh data
            setTimeout(() => {
                window.location.reload();
            }, 500);
        }

        // Auto-refresh every 60 seconds (optional)
        // setInterval(refreshData, 60000);
    </script>
</body>
</html>"""
        )

    def _generate_empty_dashboard() -> str:
        """Generate dashboard HTML when no data available."""
        return """<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>File Test Status Dashboard</title>
    <style>
        body {
            font-family: -apple-system, sans-serif;
            background: #ffffff;
            color: #333;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            text-align: center;
        }
        .message { max-width: 500px; }
        h1 { margin-bottom: 20px; color: #333; }
        code {
            background: #f8f9fa;
            color: #333;
            padding: 10px 20px;
            border-radius: 6px;
            display: block;
            margin-top: 20px;
            border: 1px solid #e0e0e0;
        }
    </style>
</head>
<body>
    <div class="message">
        <h1>📊 No Test Data Available</h1>
        <p>Run the file test tracker to populate data:</p>
        <code>empathy file-tests --scan</code>
        <p style="margin-top: 20px; color: #888;">Or track individual files:</p>
        <code>python -c "from attune.workflows.test_runner import track_file_tests; track_file_tests('src/your_file.py')"</code>
    </div>
</body>
</html>"""

    class DashboardHandler(http.server.SimpleHTTPRequestHandler):
        """Custom handler for the dashboard."""

        def do_GET(self):
            """Handle GET requests."""
            if self.path == "/" or self.path == "/index.html":
                self.send_response(200)
                self.send_header("Content-type", "text/html")
                self.end_headers()
                html = generate_dashboard_html()
                self.wfile.write(html.encode())
            else:
                self.send_error(404)

        def log_message(self, format, *args):
            """Suppress logging."""
            pass

    print(f"Starting File Test Dashboard on http://localhost:{port}")
    print("Press Ctrl+C to stop the server")

    # Open browser
    webbrowser.open(f"http://localhost:{port}")

    # Start server
    with socketserver.TCPServer(("", port), DashboardHandler) as httpd:
        httpd.allow_reuse_address = True
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nDashboard server stopped.")

    return 0
