"""
Dashboard API Route
Provides system overview, service health checks, and configuration info.
"""

import logging
import os
import platform
import sys
import time
import json
import uuid
from datetime import datetime, timezone

from fastapi import APIRouter, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from common.pool_wrapper import get_pooled_connection_compat

from config import (
    AI_SUPABASE_URL,
    CONV_SUPABASE_URL,
    DEFAULT_MODEL,
    GOOGLE_API_KEY,
    GROQ_API_KEY,
    LANGFUSE_BASE_URL,
    LANGFUSE_PUBLIC_KEY,
    LANGFUSE_SECRET_KEY,
    MONGODB_DB_NAME,
    MONGODB_URI,
    OPENAI_API_KEY,
    PORT,
    RATE_LIMIT_GUEST,
    RATE_LIMIT_USER,
    REDIS_HOST,
    REDIS_PORT,
    STARROCKS_DB,
    STARROCKS_HOST,
    USE_MONGO_CONVERSATION,
)

logger = logging.getLogger(__name__)
router = APIRouter()

# Track server start time
_SERVER_START_TIME = time.time()

# App version info
APP_VERSION = "2.5.0"
APP_CODENAME = "Canifa AI Stylist"

def _ensure_links_table():
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("""
                CREATE TABLE IF NOT EXISTS dashboard_links (
                    id TEXT PRIMARY KEY,
                    title TEXT NOT NULL,
                    url TEXT NOT NULL,
                    description TEXT,
                    category TEXT,
                    icon TEXT,
                    pinned INTEGER DEFAULT 0
                )
            """)
    except Exception as e:
        logger.error(f"Error creating dashboard_links table: {e}")

_ensure_links_table()

DEFAULT_TOOL_LINKS = [
    {"id": "tool_stress_test", "title": "Stress Test Dashboard", "url": "/static/stress-test.html",
     "description": "Bắn N request đồng thời — đo RPS, latency p95, error rate", "category": "tool", "icon": "🔥"},
    {"id": "tool_regression_test", "title": "Regression Test", "url": "/static/regression-test.html",
     "description": "Chạy bộ test cases qua bất kỳ chatbot URL — con người đọc kết quả", "category": "tool", "icon": "🧪"},
    {"id": "tool_user_simulator", "title": "User Simulator", "url": "/static/user-simulator.html",
     "description": "AI đóng vai persona test chatbot — đánh giá từ góc user thật", "category": "tool", "icon": "🎭"},
    {"id": "tool_prompt_optimizer", "title": "Prompt Optimizer", "url": "/static/prompt-optimizer.html",
     "description": "AI Judge chấm điểm chatbot + tự động gợi ý cải thiện prompt", "category": "tool", "icon": "⚡"},
    {"id": "tool_competitor_research", "title": "Competitor Research", "url": "/static/competitor-research.html",
     "description": "Nghiên cứu đối thủ — phân tích Zalando, YaMe, H&M", "category": "doc", "icon": "🔍"},
]

def _seed_default_links():
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("SELECT id FROM dashboard_links")
            existing_ids = {r["id"] for r in cur.fetchall()}
            for link in DEFAULT_TOOL_LINKS:
                if link["id"] not in existing_ids:
                    cur.execute("""
                        INSERT INTO dashboard_links (id, title, url, description, category, icon, pinned)
                        VALUES (?, ?, ?, ?, ?, ?, ?)
                    """, (link["id"], link["title"], link["url"], link["description"], link["category"], link["icon"], 0))
    except Exception as e:
        logger.error(f"Error seeding dashboard_links: {e}")

def _load_links():
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("SELECT id, title, url, description, category, icon, pinned FROM dashboard_links")
            rows = cur.fetchall()
            return [
                {
                    "id": r["id"],
                    "title": r["title"],
                    "url": r["url"],
                    "description": r["description"] or "",
                    "category": r["category"] or "tool",
                    "icon": r["icon"] or "",
                    "pinned": bool(r["pinned"])
                } for r in rows
            ]
    except Exception as e:
        logger.error(f"Error loading dashboard_links: {e}")
        return []

class LinkItem(BaseModel):
    title: str
    url: str
    description: str = ""
    category: str = "tool"
    icon: str = ""
    pinned: bool = False




def _mask_key(key: str | None) -> str:
    """Mask API key for safe display."""
    if not key:
        return "❌ Not Set"
    if len(key) <= 8:
        return "****"
    return f"{key[:4]}...{key[-4:]}"


def _check_service_status(name: str) -> dict:
    """Check service availability based on config presence."""
    checks = {
        "Redis": bool(REDIS_HOST),
        "MongoDB": bool(MONGODB_URI),
        "Langfuse": bool(LANGFUSE_SECRET_KEY and LANGFUSE_PUBLIC_KEY),
        "Supabase (AI)": bool(AI_SUPABASE_URL),
        "Supabase (Conv)": bool(CONV_SUPABASE_URL),
        "StarRocks": bool(STARROCKS_HOST),
        "OpenAI": bool(OPENAI_API_KEY),
        "Google AI": bool(GOOGLE_API_KEY),
        "Groq": bool(GROQ_API_KEY),
    }
    configured = checks.get(name, False)
    return {
        "name": name,
        "configured": configured,
        "status": "✅ Configured" if configured else "❌ Not Configured",
    }


@router.get("/api/dashboard/info", summary="Get dashboard system info")
async def dashboard_info():
    """Return comprehensive system information for the dashboard."""

    # Uptime calculation
    uptime_seconds = int(time.time() - _SERVER_START_TIME)
    hours, remainder = divmod(uptime_seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    uptime_str = f"{hours}h {minutes}m {seconds}s"

    # Service health checks
    services = [
        _check_service_status("Redis"),
        _check_service_status("MongoDB"),
        _check_service_status("Langfuse"),
        _check_service_status("Supabase (AI)"),
        _check_service_status("Supabase (Conv)"),
        _check_service_status("StarRocks"),
        _check_service_status("OpenAI"),
        _check_service_status("Google AI"),
        _check_service_status("Groq"),
    ]

    # Count healthy services
    healthy_count = sum(1 for s in services if s["configured"])
    total_count = len(services)

    # Feedback stats (safe import)
    feedback_stats = {}
    try:
        from common.feedback_tracker import get_feedback_stats
        feedback_stats = get_feedback_stats()
    except Exception as e:
        logger.warning(f"Could not load feedback stats: {e}")
        feedback_stats = {"error": str(e)}

    # Git info
    git_info = {"branch": "unknown", "commit": "unknown"}
    try:
        import subprocess
        git_branch = subprocess.check_output(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"],
            cwd=os.path.dirname(os.path.abspath(__file__)),
            text=True,
            timeout=5,
        ).strip()
        git_commit = subprocess.check_output(
            ["git", "rev-parse", "--short", "HEAD"],
            cwd=os.path.dirname(os.path.abspath(__file__)),
            text=True,
            timeout=5,
        ).strip()
        git_info = {"branch": git_branch, "commit": git_commit}
    except Exception:
        pass

    # Registered API routes
    from server import app as fastapi_app
    routes = []
    for route in fastapi_app.routes:
        if hasattr(route, "methods") and hasattr(route, "path"):
            routes.append({
                "path": route.path,
                "methods": list(route.methods),
                "name": getattr(route, "name", ""),
            })

    return {
        "system": {
            "app_name": APP_CODENAME,
            "app_version": APP_VERSION,
            "python_version": platform.python_version(),
            "os": f"{platform.system()} {platform.release()}",
            "uptime": uptime_str,
            "uptime_seconds": uptime_seconds,
            "server_port": PORT,
            "started_at": datetime.fromtimestamp(_SERVER_START_TIME, tz=timezone.utc).isoformat(),
        },
        "llm": {
            "default_model": DEFAULT_MODEL,
            "openai_key": _mask_key(OPENAI_API_KEY),
            "google_key": _mask_key(GOOGLE_API_KEY),
            "groq_key": _mask_key(GROQ_API_KEY),
        },
        "services": services,
        "services_summary": {
            "healthy": healthy_count,
            "total": total_count,
            "health_pct": round(healthy_count / total_count * 100) if total_count else 0,
        },
        "config": {
            "rate_limit_guest": RATE_LIMIT_GUEST,
            "rate_limit_user": RATE_LIMIT_USER,
            "conversation_storage": "MongoDB" if USE_MONGO_CONVERSATION else "Supabase",
            "mongodb_db": MONGODB_DB_NAME,
            "redis_host": REDIS_HOST or "N/A",
            "redis_port": REDIS_PORT,
            "langfuse_url": LANGFUSE_BASE_URL or "N/A",
            "starrocks_db": STARROCKS_DB or "N/A",
        },
        "git": git_info,
        "feedback": feedback_stats,
        "routes": routes,
        "timestamp": datetime.now(tz=timezone.utc).isoformat(),
    }

# =====================================================================
# Dashboard Links API
# =====================================================================

@router.get("/api/dashboard/links", summary="Get all dashboard links")
async def get_dashboard_links():
    _seed_default_links()
    links = _load_links()
    return {"links": links}

@router.post("/api/dashboard/links", summary="Create a new link")
async def create_dashboard_link(item: LinkItem):
    link_id = str(uuid.uuid4())
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("""
                INSERT INTO dashboard_links (id, title, url, description, category, icon, pinned)
                VALUES (?, ?, ?, ?, ?, ?, ?)
            """, (link_id, item.title, item.url, item.description, item.category, item.icon, 1 if item.pinned else 0))
    except Exception as e:
        logger.error(f"Error creating dashboard_link: {e}")
        raise HTTPException(status_code=500, detail="Database error")
    
    new_link = item.dict()
    new_link["id"] = link_id
    return {"status": "success", "link": new_link}

@router.put("/api/dashboard/links/{link_id}", summary="Update a link")
async def update_dashboard_link(link_id: str, item: LinkItem):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("""
                UPDATE dashboard_links
                SET title = ?, url = ?, description = ?, category = ?, icon = ?, pinned = ?
                WHERE id = ?
            """, (item.title, item.url, item.description, item.category, item.icon, 1 if item.pinned else 0, link_id))
            if cur.rowcount == 0:
                raise HTTPException(status_code=404, detail="Link not found")
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error updating dashboard_link: {e}")
        raise HTTPException(status_code=500, detail="Database error")

    updated_link = item.dict()
    updated_link["id"] = link_id
    return {"status": "success", "link": updated_link}

@router.delete("/api/dashboard/links/{link_id}", summary="Delete a link")
async def delete_dashboard_link(link_id: str):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("DELETE FROM dashboard_links WHERE id = ?", (link_id,))
            if cur.rowcount == 0:
                raise HTTPException(status_code=404, detail="Link not found")
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting dashboard_link: {e}")
        raise HTTPException(status_code=500, detail="Database error")
    return {"status": "success"}

@router.patch("/api/dashboard/links/{link_id}/pin", summary="Toggle pin status")
async def toggle_pin_dashboard_link(link_id: str):
    try:
        conn = get_pooled_connection_compat()
        with conn.cursor() as cur:
            cur.execute("SELECT pinned FROM dashboard_links WHERE id = ?", (link_id,))
            row = cur.fetchone()
            if not row:
                raise HTTPException(status_code=404, detail="Link not found")
            
            new_pin = 0 if row["pinned"] else 1
            cur.execute("UPDATE dashboard_links SET pinned = ? WHERE id = ?", (new_pin, link_id))
            return {"status": "success", "pinned": bool(new_pin)}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error toggling pin on dashboard_link: {e}")
        raise HTTPException(status_code=500, detail="Database error")
