"""MemoTrail web dashboard — FastAPI + Jinja2 + HTMX."""

from pathlib import Path

from fastapi import FastAPI, Request, Query
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

from memotrail.storage import SQLiteStore, ChromaStore
from memotrail.core.searcher import Searcher
from memotrail.core.embedder import Embedder
from memotrail.core.context_packer import ContextPacker
from memotrail.core.graph import KnowledgeGraph
from memotrail.core.temporal import TemporalTracker
from memotrail.utils import get_logger

logger = get_logger("memotrail.web")

WEB_DIR = Path(__file__).parent
TEMPLATES_DIR = WEB_DIR / "templates"
STATIC_DIR = WEB_DIR / "static"

# ── Initialize components ─────────────────────────────────────

sqlite_store = SQLiteStore()
chroma_store = ChromaStore()
embedder = Embedder()
searcher = Searcher(sqlite_store, chroma_store, embedder=embedder)
context_packer = ContextPacker(sqlite_store, chroma_store, searcher=searcher, embedder=embedder)
knowledge_graph = KnowledgeGraph(sqlite_store)
temporal_tracker = TemporalTracker(sqlite_store)

# ── FastAPI app ───────────────────────────────────────────────

app = FastAPI(title="MemoTrail Dashboard", version="0.9.0")
app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
templates = Jinja2Templates(directory=str(TEMPLATES_DIR))

# Mount REST API
from memotrail.web.api_routes import router as api_router, mount_api
mount_api(sqlite_store, chroma_store, searcher, context_packer, knowledge_graph, temporal_tracker)
app.include_router(api_router)


# ── Routes ────────────────────────────────────────────────────

@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
    """Dashboard home with stats."""
    db_stats = sqlite_store.get_stats()
    chat_chunks = chroma_store.get_collection_count(ChromaStore.CHAT_COLLECTION)
    memory_chunks = chroma_store.get_collection_count(ChromaStore.MEMORY_COLLECTION)

    # Count entities
    try:
        entity_count = sqlite_store.conn.execute(
            "SELECT COUNT(*) as c FROM entities"
        ).fetchone()["c"]
    except Exception:
        entity_count = 0

    stats = {
        **db_stats,
        "chat_chunks": chat_chunks,
        "memory_notes": memory_chunks,
        "total_entities": entity_count,
    }
    return templates.TemplateResponse("index.html", {"request": request, "stats": stats})


@app.get("/sessions", response_class=HTMLResponse)
async def sessions(
    request: Request,
    page: int = Query(1, ge=1),
    project: str | None = None,
):
    """Sessions list with pagination."""
    per_page = 20
    sessions_list, total = sqlite_store.get_sessions_paginated(page, per_page, project)
    total_pages = max(1, (total + per_page - 1) // per_page)

    return templates.TemplateResponse("sessions.html", {
        "request": request,
        "sessions": sessions_list,
        "page": page,
        "total_pages": total_pages,
        "total": total,
        "project": project,
    })


@app.get("/sessions/{session_id}", response_class=HTMLResponse)
async def session_detail(request: Request, session_id: str):
    """Session detail with messages."""
    session = sqlite_store.get_session(session_id)
    if not session:
        return HTMLResponse("<h1>Session not found</h1>", status_code=404)

    messages = sqlite_store.get_session_messages(session_id)
    decisions = sqlite_store.get_decisions(limit=100)
    session_decisions = [d for d in decisions if d.session_id == session_id]

    return templates.TemplateResponse("session_detail.html", {
        "request": request,
        "session": session,
        "messages": messages,
        "decisions": session_decisions,
    })


@app.get("/search", response_class=HTMLResponse)
async def search_page(request: Request, q: str | None = None, limit: int = 10):
    """Search page with live HTMX results."""
    results = []
    if q:
        results = searcher.search_chats(q, limit=limit)

    # Check if this is an HTMX request
    if request.headers.get("HX-Request"):
        return templates.TemplateResponse("_search_results.html", {
            "request": request,
            "results": results,
            "query": q,
        })

    return templates.TemplateResponse("search.html", {
        "request": request,
        "results": results,
        "query": q or "",
    })


@app.get("/memories", response_class=HTMLResponse)
async def memories(request: Request):
    """Memory management page."""
    memory_list = sqlite_store.get_all_memories()
    return templates.TemplateResponse("memories.html", {
        "request": request,
        "memories": memory_list,
    })


@app.post("/memories/add")
async def add_memory(request: Request):
    """Add a new memory via form submission."""
    from memotrail.core.indexer import Indexer

    form = await request.form()
    content = form.get("content", "").strip()
    tags_raw = form.get("tags", "").strip()
    tags = [t.strip() for t in tags_raw.split(",") if t.strip()] if tags_raw else []

    if content:
        idx = Indexer(sqlite_store, chroma_store, embedder=embedder)
        idx.index_memory(content, tags)

    memory_list = sqlite_store.get_all_memories()
    return templates.TemplateResponse("memories.html", {
        "request": request,
        "memories": memory_list,
    })


@app.delete("/memories/{memory_id}")
async def delete_memory(request: Request, memory_id: str):
    """Delete a memory."""
    sqlite_store.delete_memory(memory_id)
    chroma_store.delete_by_ids([memory_id], collection=ChromaStore.MEMORY_COLLECTION)

    memory_list = sqlite_store.get_all_memories()
    return templates.TemplateResponse("memories.html", {
        "request": request,
        "memories": memory_list,
    })


@app.get("/graph", response_class=HTMLResponse)
async def graph_page(request: Request):
    """Knowledge graph visualization."""
    entities = knowledge_graph.get_all_entities(limit=200)

    # Build nodes and edges for D3.js
    nodes = []
    entity_ids = set()
    for e in entities:
        nodes.append({
            "id": e["id"],
            "name": e["name"],
            "type": e["entity_type"],
            "mentions": e["mention_count"],
        })
        entity_ids.add(e["id"])

    # Get all relations between known entities
    edges = []
    seen_edges: set[str] = set()
    for e in entities:
        relations = knowledge_graph.get_entity_relations(e["id"])
        for r in relations:
            edge_key = f"{r['source_entity_id']}:{r['target_entity_id']}"
            if edge_key in seen_edges:
                continue
            if r["source_entity_id"] in entity_ids and r["target_entity_id"] in entity_ids:
                seen_edges.add(edge_key)
                edges.append({
                    "source": r["source_entity_id"],
                    "target": r["target_entity_id"],
                    "type": r["relation_type"],
                })

    import json
    return templates.TemplateResponse("graph.html", {
        "request": request,
        "nodes_json": json.dumps(nodes),
        "edges_json": json.dumps(edges),
        "entity_count": len(nodes),
        "relation_count": len(edges),
    })
