from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional
import os
import httpx

app = FastAPI(
    title="Innovatieplatform AI Service",
    description="AI service for chat, summarization and semantic search.",
    version="0.2.0",
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Simplified for internal Docker network
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY", "")
ANTHROPIC_MODEL = os.getenv("ANTHROPIC_MODEL", "claude-haiku-4-5-20251001")
DB_URL = os.getenv("DATABASE_URL", "postgresql://innovatie:secret@postgresql:5432/innovatieplatform")

# --- Request/Response models ---

class ChatRequest(BaseModel):
    message: str
    project_id: Optional[int] = None
    conversation_history: Optional[list] = []

class ChatResponse(BaseModel):
    reply: str
    project_id: Optional[int] = None

class SummarizeRequest(BaseModel):
    content: str
    project_id: Optional[int] = None
    summary_type: Optional[str] = "general"

class SummarizeResponse(BaseModel):
    summary: str
    project_id: Optional[int] = None

class SearchRequest(BaseModel):
    query: str
    project_id: Optional[int] = None
    limit: Optional[int] = 10

class SearchResult(BaseModel):
    id: int
    content: str
    score: float
    metadata: Optional[dict] = {}

class SearchResponse(BaseModel):
    results: list[SearchResult]
    query: str

# --- Database context helper ---

async def get_project_context(project_id: int) -> str:
    """Fetch project details from PostgreSQL for AI context."""
    try:
        import asyncpg
        conn = await asyncpg.connect(DB_URL)

        # Get project info
        project = await conn.fetchrow(
            "SELECT naam, beschrijving, status, prioriteit FROM projects WHERE id = $1",
            project_id
        )
        if not project:
            await conn.close()
            return ""

        # Get documents
        docs = await conn.fetch(
            "SELECT titel, inhoud FROM documents WHERE project_id = $1 ORDER BY versie DESC LIMIT 5",
            project_id
        )

        # Get commitments
        commits = await conn.fetch(
            "SELECT beschrijving, status, deadline FROM commitments WHERE project_id = $1 ORDER BY deadline LIMIT 5",
            project_id
        )

        await conn.close()

        context = f"Project: {project['naam']}\nStatus: {project['status']}\nBeschrijving: {project['beschrijving']}\n"

        if docs:
            context += "\nDocumenten:\n"
            for d in docs:
                content_preview = (d['inhoud'] or '')[:300]
                context += f"- {d['titel']}: {content_preview}\n"

        if commits:
            context += "\nCommitments:\n"
            for c in commits:
                context += f"- {c['beschrijving']} [{c['status']}] (deadline: {c['deadline']})\n"

        return context
    except Exception as e:
        return f"[Context fetch error: {str(e)}]"


async def get_global_context() -> str:
    """Fetch overview of all projects and kennis artikelen."""
    try:
        import asyncpg
        conn = await asyncpg.connect(DB_URL)

        projects = await conn.fetch(
            "SELECT naam, status, beschrijving FROM projects ORDER BY naam LIMIT 20"
        )

        artikelen = await conn.fetch(
            "SELECT titel, inhoud FROM kennis_artikelen ORDER BY created_at DESC LIMIT 10"
        )

        await conn.close()

        context = "Projecten overzicht:\n"
        for p in projects:
            context += f"- {p['naam']} [{p['status']}]: {(p['beschrijving'] or '')[:100]}\n"

        if artikelen:
            context += "\nKennisbasis:\n"
            for a in artikelen:
                context += f"- {a['titel']}: {(a['inhoud'] or '')[:200]}\n"

        return context
    except Exception as e:
        return f"[Context fetch error: {str(e)}]"


# --- Endpoints ---

@app.get("/health")
async def health_check():
    has_key = bool(ANTHROPIC_API_KEY)
    return {"status": "ok", "service": "ai-service", "model": ANTHROPIC_MODEL, "has_api_key": has_key}

@app.post("/api/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
    """Chat with AI, optionally scoped to a project."""
    if not ANTHROPIC_API_KEY:
        return ChatResponse(
            reply="AI niet geconfigureerd. Stel ANTHROPIC_API_KEY in als environment variable.",
            project_id=request.project_id
        )

    # Build context
    if request.project_id:
        context = await get_project_context(request.project_id)
    else:
        context = await get_global_context()

    system_prompt = (
        "Je bent de AI-assistent van het Innovatieplatform van Waterschap Brabantse Delta R&D Lab. "
        "Je helpt met vragen over projecten, onderzoek, architectuur en innovatie. "
        "Antwoord bondig in het Nederlands tenzij de gebruiker Engels spreekt. "
        "Gebruik de projectcontext om relevante antwoorden te geven.\n\n"
        f"Context:\n{context}"
    )

    # Build messages
    messages = []
    for entry in (request.conversation_history or []):
        role = "user" if entry.get("type") == "input" else "assistant"
        messages.append({"role": role, "content": entry.get("text", "")})
    messages.append({"role": "user", "content": request.message})

    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.post(
                "https://api.anthropic.com/v1/messages",
                headers={
                    "x-api-key": ANTHROPIC_API_KEY,
                    "anthropic-version": "2023-06-01",
                    "content-type": "application/json",
                },
                json={
                    "model": ANTHROPIC_MODEL,
                    "max_tokens": 1024,
                    "system": system_prompt,
                    "messages": messages,
                },
            )

            if response.status_code != 200:
                error_detail = response.text[:200]
                return ChatResponse(
                    reply=f"AI fout ({response.status_code}): {error_detail}",
                    project_id=request.project_id
                )

            data = response.json()
            reply = data["content"][0]["text"]
            return ChatResponse(reply=reply, project_id=request.project_id)

    except Exception as e:
        return ChatResponse(
            reply=f"AI verbindingsfout: {str(e)}",
            project_id=request.project_id
        )

@app.post("/api/summarize", response_model=SummarizeResponse)
async def summarize(request: SummarizeRequest):
    """Summarize content using AI."""
    if not ANTHROPIC_API_KEY:
        return SummarizeResponse(
            summary="AI niet geconfigureerd.",
            project_id=request.project_id
        )

    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.post(
                "https://api.anthropic.com/v1/messages",
                headers={
                    "x-api-key": ANTHROPIC_API_KEY,
                    "anthropic-version": "2023-06-01",
                    "content-type": "application/json",
                },
                json={
                    "model": ANTHROPIC_MODEL,
                    "max_tokens": 512,
                    "system": "Maak een beknopte samenvatting in het Nederlands. Focus op de kernpunten.",
                    "messages": [{"role": "user", "content": request.content}],
                },
            )

            if response.status_code != 200:
                return SummarizeResponse(summary=f"Samenvatting fout: {response.text[:200]}", project_id=request.project_id)

            data = response.json()
            return SummarizeResponse(summary=data["content"][0]["text"], project_id=request.project_id)
    except Exception as e:
        return SummarizeResponse(summary=f"Fout: {str(e)}", project_id=request.project_id)

@app.post("/api/search", response_model=SearchResponse)
async def search(request: SearchRequest):
    """Search projects and documents by keyword (basic text search, no embeddings yet)."""
    try:
        import asyncpg
        conn = await asyncpg.connect(DB_URL)

        query_pattern = f"%{request.query}%"

        results = []

        # Search documents
        docs = await conn.fetch(
            "SELECT id, titel, inhoud FROM documents WHERE inhoud ILIKE $1 OR titel ILIKE $1 LIMIT $2",
            query_pattern, request.limit
        )
        for d in docs:
            results.append(SearchResult(
                id=d['id'],
                content=f"{d['titel']}: {(d['inhoud'] or '')[:200]}",
                score=1.0,
                metadata={"type": "document"}
            ))

        # Search kennis artikelen
        artikelen = await conn.fetch(
            "SELECT id, titel, inhoud FROM kennis_artikelen WHERE inhoud ILIKE $1 OR titel ILIKE $1 LIMIT $2",
            query_pattern, request.limit
        )
        for a in artikelen:
            results.append(SearchResult(
                id=a['id'],
                content=f"{a['titel']}: {(a['inhoud'] or '')[:200]}",
                score=0.9,
                metadata={"type": "kennis_artikel"}
            ))

        await conn.close()
        return SearchResponse(results=results, query=request.query)
    except Exception as e:
        return SearchResponse(results=[], query=request.query)
