"""
Settings and User Management API Router
"""

from fastapi import APIRouter, HTTPException, Request
from typing import List, Optional, Dict
from pydantic import BaseModel
from app.core.database import execute_query
from app.core.config import settings
import httpx
import time
import logging
import json

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

DEFAULT_EMAIL_SIGNATURE_TEMPLATE = (
    "{full_name}\n"
    "{title}\n"
    "{company_name}\n"
    "Telefon: {company_phone}\n"
    "Email: {email}\n"
    "Web: {company_website}\n"
    "Adresse: {company_address}\n"
    "BMCid: {bmc_id_tag}"
)


# Pydantic Models
class Setting(BaseModel):
    id: int
    key: str
    value: Optional[str]
    category: str
    description: Optional[str]
    value_type: str
    is_public: bool


class SettingUpdate(BaseModel):
    value: str


class User(BaseModel):
    id: int
    username: str
    email: Optional[str]
    full_name: Optional[str]
    is_active: bool
    last_login: Optional[str]
    created_at: str


class UserCreate(BaseModel):
    username: str
    email: str
    password: str
    full_name: Optional[str] = None


class UserUpdate(BaseModel):
    email: Optional[str] = None
    full_name: Optional[str] = None
    is_active: Optional[bool] = None


# Settings Endpoints
@router.get("/settings", response_model=List[Setting], tags=["Settings"])
async def get_settings(category: Optional[str] = None):
    """Get all settings or filter by category"""
    execute_query(
        """
        INSERT INTO settings (key, value, category, description, value_type, is_public)
        VALUES
            (%s, %s, %s, %s, %s, %s),
            (%s, %s, %s, %s, %s, %s)
        ON CONFLICT (key) DO NOTHING
        """,
        (
            "email_default_signature_template",
            DEFAULT_EMAIL_SIGNATURE_TEMPLATE,
            "email",
            "Standard signatur skabelon til udgående sagsmails",
            "text",
            True,
            "company_website",
            "https://bmcnetworks.dk",
            "company",
            "Firma website",
            "string",
            True,
        ),
    )

    query = "SELECT * FROM settings"
    params = []
    
    if category:
        query += " WHERE category = %s"
        params.append(category)
    
    query += " ORDER BY category, key"
    result = execute_query(query, tuple(params) if params else None)
    return result or []


@router.get("/settings/{key}", response_model=Setting, tags=["Settings"])
async def get_setting(key: str):
    """Get a specific setting by key"""
    query = "SELECT * FROM settings WHERE key = %s"
    result = execute_query(query, (key,))

    if not result and key in {"case_types", "case_type_module_defaults", "case_statuses"}:
        seed_query = """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key) DO NOTHING
        """

        if key == "case_types":
            execute_query(
                seed_query,
                (
                    "case_types",
                    '["ticket", "opgave", "ordre", "projekt", "service"]',
                    "system",
                    "Sags-typer",
                    "json",
                    True,
                )
            )

        if key == "case_type_module_defaults":
            execute_query(
                seed_query,
                (
                    "case_type_module_defaults",
                    '{"ticket": ["relations", "call-history", "files", "emails", "hardware", "locations", "contacts", "customers", "wiki", "todo-steps", "time", "solution", "sales", "subscription", "reminders", "calendar"], "opgave": ["relations", "call-history", "files", "emails", "hardware", "locations", "contacts", "customers", "wiki", "todo-steps", "time", "solution", "sales", "subscription", "reminders", "calendar"], "ordre": ["relations", "call-history", "files", "emails", "hardware", "locations", "contacts", "customers", "wiki", "todo-steps", "time", "solution", "sales", "subscription", "reminders", "calendar"], "projekt": ["relations", "call-history", "files", "emails", "hardware", "locations", "contacts", "customers", "wiki", "todo-steps", "time", "solution", "sales", "subscription", "reminders", "calendar"], "service": ["relations", "call-history", "files", "emails", "hardware", "locations", "contacts", "customers", "wiki", "todo-steps", "time", "solution", "sales", "subscription", "reminders", "calendar"]}',
                    "system",
                    "Standard moduler pr. sagstype",
                    "json",
                    True,
                )
            )

        if key == "case_statuses":
            execute_query(
                seed_query,
                (
                    "case_statuses",
                    json.dumps([
                        {"value": "åben", "is_closed": False},
                        {"value": "under behandling", "is_closed": False},
                        {"value": "afventer", "is_closed": False},
                        {"value": "løst", "is_closed": True},
                        {"value": "lukket", "is_closed": True},
                    ], ensure_ascii=False),
                    "system",
                    "Sagsstatus værdier og lukkede markeringer",
                    "json",
                    True,
                )
            )

        result = execute_query(query, (key,))

    if not result and key == "email_default_signature_template":
        execute_query(
            """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key) DO NOTHING
            """,
            (
                "email_default_signature_template",
                DEFAULT_EMAIL_SIGNATURE_TEMPLATE,
                "email",
                "Standard signatur skabelon til udgående sagsmails",
                "text",
                True,
            )
        )
        result = execute_query(query, (key,))

    if not result:
        raise HTTPException(status_code=404, detail="Setting not found")

    return result[0]


@router.put("/settings/{key}", response_model=Setting, tags=["Settings"])
async def update_setting(key: str, setting: SettingUpdate):
    """Update a setting value"""
    query = """
        UPDATE settings 
        SET value = %s, updated_at = CURRENT_TIMESTAMP
        WHERE key = %s
        RETURNING *
    """
    result = execute_query(query, (setting.value, key))

    if not result and key == "email_default_signature_template":
        result = execute_query(
            """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key)
            DO UPDATE SET
                value = EXCLUDED.value,
                updated_at = CURRENT_TIMESTAMP
            RETURNING *
            """,
            (
                "email_default_signature_template",
                setting.value,
                "email",
                "Standard signatur skabelon til udgående sagsmails",
                "text",
                True,
            )
        )

    # Mission camera settings may not exist on older hubs before migration.
    # AnyDesk settings may not exist on older hubs — auto-create on first save
    _anydesk_keys = {
        "anydesk_api_token": ("integrations", "AnyDesk API token", "string", False),
        "anydesk_license_id": ("integrations", "AnyDesk license ID", "string", False),
        "anydesk_read_only": ("integrations", "AnyDesk read-only mode", "boolean", True),
        "anydesk_dry_run": ("integrations", "AnyDesk dry-run mode", "boolean", True),
    }
    if not result and key in _anydesk_keys:
        category, description, value_type, is_public = _anydesk_keys[key]
        result = execute_query(
            """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key)
            DO UPDATE SET value = EXCLUDED.value, updated_at = CURRENT_TIMESTAMP
            RETURNING *
            """,
            (key, setting.value, category, description, value_type, is_public),
        )

    _label_printer_keys = {
        "label_printer_enabled": ("integrations", "Enable direct label printing", "boolean", True),
        "label_printer_model": ("integrations", "Brother printer model for direct labels", "string", True),
        "label_printer_host": ("integrations", "Brother printer host/IP", "string", True),
        "label_printer_port": ("integrations", "Brother printer TCP port", "integer", True),
        "label_printer_label_size": ("integrations", "Brother label size code", "string", True),
    }
    if not result and key in _label_printer_keys:
        category, description, value_type, is_public = _label_printer_keys[key]
        result = execute_query(
            """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key)
            DO UPDATE SET value = EXCLUDED.value, updated_at = CURRENT_TIMESTAMP
            RETURNING *
            """,
            (key, setting.value, category, description, value_type, is_public),
        )

    # Mission camera settings may not exist on older hubs before migration.
    if not result and key in {"mission_camera_enabled", "mission_camera_name", "mission_camera_feed_url", "mission_camera_spotlight_seconds", "mission_access_pin"}:
        defaults = {
            "mission_camera_enabled": ("mission", "Enable one camera feed in Mission Control", "boolean", True),
            "mission_camera_name": ("mission", "Display name for Mission Control camera feed", "string", True),
            "mission_camera_feed_url": ("mission", "Feed URL for Mission Control camera", "string", True),
            "mission_camera_spotlight_seconds": ("mission", "Camera spotlight duration in seconds for motion events", "integer", True),
            "mission_access_pin": ("mission", "Access PIN for Mission Control kiosk mode", "string", False),
        }
        category, description, value_type, is_public = defaults[key]
        result = execute_query(
            """
            INSERT INTO settings (key, value, category, description, value_type, is_public)
            VALUES (%s, %s, %s, %s, %s, %s)
            ON CONFLICT (key)
            DO UPDATE SET
                value = EXCLUDED.value,
                updated_at = CURRENT_TIMESTAMP
            RETURNING *
            """,
            (key, setting.value, category, description, value_type, is_public),
        )

    if not result:
        raise HTTPException(status_code=404, detail="Setting not found")
    
    logger.info(f"✅ Updated setting: {key}")
    return result[0]


@router.get("/settings/categories/list", tags=["Settings"])
async def get_setting_categories():
    """Get list of all setting categories"""
    query = "SELECT DISTINCT category FROM settings ORDER BY category"
    result = execute_query(query)
    return [row['category'] for row in result] if result else []


@router.get("/settings/migrations/status", tags=["Settings"])
async def get_migration_statuses_api():
    """Expose migration status via API router (served under /api/v1)."""
    from app.settings.backend.views import migration_statuses

    return migration_statuses()


@router.post("/settings/migrations/execute", tags=["Settings"])
async def execute_migration_api(payload: dict):
    """Expose migration execution via API router (served under /api/v1)."""
    from app.settings.backend.views import execute_migration, MigrationExecution

    model = MigrationExecution(**payload)
    return execute_migration(model)


@router.post("/settings/sync-from-env", tags=["Settings"])
async def sync_settings_from_env():
    """Sync settings from .env file into database (only updates empty values)"""
    from app.core.config import settings as env_settings
    
    mapping = {
        'vtiger_enabled': str(env_settings.VTIGER_ENABLED).lower(),
        'vtiger_url': env_settings.VTIGER_URL or '',
        'vtiger_username': env_settings.VTIGER_USERNAME or '',
        'economic_enabled': str(env_settings.ECONOMIC_ENABLED).lower(),
        'economic_app_secret': env_settings.ECONOMIC_APP_SECRET_TOKEN or '',
        'economic_agreement_token': env_settings.ECONOMIC_AGREEMENT_GRANT_TOKEN or '',
    }
    
    updated_count = 0
    for key, value in mapping.items():
        # Only update if current value is empty or NULL
        query = """
            UPDATE settings 
            SET value = %s, updated_at = CURRENT_TIMESTAMP
            WHERE key = %s AND (value IS NULL OR value = '')
            RETURNING key
        """
        result = execute_query(query, (value, key))
        if result:
            updated_count += 1
            logger.info(f"✅ Synced {key} from .env")
    
    return {
        "message": f"Synced {updated_count} settings from .env file",
        "updated_count": updated_count
    }


# User Management Endpoints
@router.get("/users", response_model=List[User], tags=["Users"])
async def get_users(is_active: Optional[bool] = None):
    """Get all users"""
    query = "SELECT user_id as id, username, email, full_name, is_active, last_login_at as last_login, created_at FROM users"
    params = []
    
    if is_active is not None:
        query += " WHERE is_active = %s"
        params.append(is_active)
    
    query += " ORDER BY username"
    result = execute_query(query, tuple(params) if params else None)
    return result or []


@router.get("/users/{user_id}", response_model=User, tags=["Users"])
async def get_user(user_id: int):
    """Get user by ID"""
    query = "SELECT user_id as id, username, email, full_name, is_active, last_login_at as last_login, created_at FROM users WHERE user_id = %s"
    result = execute_query(query, (user_id,))
    
    if not result:
        raise HTTPException(status_code=404, detail="User not found")
    
    return result[0]


@router.post("/users", response_model=User, tags=["Users"])
async def create_user(user: UserCreate):
    """Create a new user"""
    # Check if username exists
    existing = execute_query("SELECT user_id FROM users WHERE username = %s", (user.username,))
    if existing:
        raise HTTPException(status_code=400, detail="Username already exists")
    
    # Hash password (simple SHA256 for now - should use bcrypt in production)
    import hashlib
    password_hash = hashlib.sha256(user.password.encode()).hexdigest()
    
    query = """
        INSERT INTO users (username, email, password_hash, full_name, is_active)
        VALUES (%s, %s, %s, %s, true)
        RETURNING user_id as id, username, email, full_name, is_active, last_login_at as last_login, created_at
    """
    result = execute_query(query, (user.username, user.email, password_hash, user.full_name))
    
    if not result:
        raise HTTPException(status_code=500, detail="Failed to create user")
    
    logger.info(f"✅ Created user: {user.username}")
    return result[0]


@router.put("/users/{user_id}", response_model=User, tags=["Users"])
async def update_user(user_id: int, user: UserUpdate):
    """Update user details"""
    # Check if user exists
    existing = execute_query("SELECT user_id FROM users WHERE user_id = %s", (user_id,))
    if not existing:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Build update query
    update_fields = []
    params = []
    
    if user.email is not None:
        update_fields.append("email = %s")
        params.append(user.email)
    if user.full_name is not None:
        update_fields.append("full_name = %s")
        params.append(user.full_name)
    if user.is_active is not None:
        update_fields.append("is_active = %s")
        params.append(user.is_active)
    
    if not update_fields:
        raise HTTPException(status_code=400, detail="No fields to update")
    
    params.append(user_id)
    query = f"""
        UPDATE users 
        SET {', '.join(update_fields)}, updated_at = CURRENT_TIMESTAMP
        WHERE user_id = %s
        RETURNING user_id as id, username, email, full_name, is_active, last_login_at as last_login, created_at
    """
    
    result = execute_query(query, tuple(params))
    
    if not result:
        raise HTTPException(status_code=500, detail="Failed to update user")
    
    logger.info(f"✅ Updated user: {user_id}")
    return result[0]


@router.delete("/users/{user_id}", tags=["Users"])
async def deactivate_user(user_id: int):
    """Deactivate a user (soft delete)"""
    query = """
        UPDATE users 
        SET is_active = false, updated_at = CURRENT_TIMESTAMP
        WHERE user_id = %s
        RETURNING user_id as id
    """
    result = execute_query(query, (user_id,))
    
    if not result:
        raise HTTPException(status_code=404, detail="User not found")
    
    logger.info(f"✅ Deactivated user: {user_id}")
    return {"message": "User deactivated successfully"}


@router.post("/users/{user_id}/reset-password", tags=["Users"])
async def reset_user_password(user_id: int, new_password: str):
    """Reset user password"""
    import hashlib
    password_hash = hashlib.sha256(new_password.encode()).hexdigest()
    
    query = """
        UPDATE users 
        SET password_hash = %s, updated_at = CURRENT_TIMESTAMP
        WHERE user_id = %s
        RETURNING user_id as id
    """
    result = execute_query(query, (password_hash, user_id))
    
    if not result:
        raise HTTPException(status_code=404, detail="User not found")
    
    logger.info(f"✅ Reset password for user: {user_id}")
    return {"message": "Password reset successfully"}


# AI Prompts Management

def _get_default_prompts():
    """Helper to get default system prompts"""
    from app.services.ollama_service import OllamaService
    ollama_service = OllamaService()
    
    return {
        "invoice_extraction": {
            "name": "📄 Faktura Udtrækning (Invoice Parser)",
            "description": "System prompt brugt til at udtrække data fra fakturaer og kreditnotaer via Ollama LLM. Håndterer danske nummerformater, datoer og linjegenkendelse.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": ollama_service._build_system_prompt(),
            "parameters": {
                "temperature": 0.1,
                "top_p": 0.9,
                "num_predict": 2000
            }
        },
        "ticket_classification": {
            "name": "🎫 Ticket Klassificering (Auto-Triage)",
            "description": "Klassificerer indkomne tickets baseret på emne og indhold. Tildeler kategori, prioritet og ansvarlig team.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er en erfaren IT-supporter der skal klassificere indkomne support-sager.

Dine opgaver er:
1. Analyser emne og beskrivelse
2. Bestem Kategori: [Hardware, Software, Netværk, Adgang, Andet]
3. Bestem Prioritet: [Lav, Mellem, Høj, Kritisk]
4. Foreslå handlingsplan (kort punktform)

Output skal være gyldig JSON:
{
  "category": "string",
  "priority": "string",
  "summary": "string",
  "suggested_actions": ["string"]
}""",
            "parameters": {
                "temperature": 0.3,
                "top_p": 0.95,
                "num_predict": 1000
            }
        },
        "ticket_summary": {
            "name": "📝 Ticket Summering (Fakturagrundlag)",
            "description": "Analyserer alle kommentarer og noter i en ticket for at lave et kort, præcist resumé til fakturaen eller kunden.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er en administrativ assistent der skal gøre en it-sag klar til fakturering.

Opgave: Læs historikken igennem og skriv et kort resumé af det udførte arbejde.
- Fokusér på løsningen, ikke problemet
- Brug professionelt sprog
- Undlad interne tekniske detaljer (medmindre relevant for faktura)
- Sprog: Dansk
- Længde: 2-3 sætninger

Input: [Liste af kommentarer]
Output: [Fakturastekst]""",
            "parameters": {
                "temperature": 0.2,
                "top_p": 0.9,
                "num_predict": 500
            }
        },
        "text_rewrite": {
            "name": "✍️ Omskrivning (Email + Sagsbeskrivelse)",
            "description": "Renskriver tekst til professionelt dansk for både e-mails og sagsbeskrivelser, uden at ændre fakta.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er en dansk skriveassistent for IT-support.

Din opgave er at renskrive en rå tekst til klart, professionelt og venligt dansk.
Teksten kan være enten en e-mail eller en sagsbeskrivelse.

Regler:
1. Bevar ALLE fakta, navne, datoer, beløb, ticket/sags-ID og tekniske termer.
2. Ret stavefejl, tegnsætning og grammatik.
3. Gør teksten kortere og mere præcis, men uden at fjerne vigtig information.
4. Fjern fyldord, gentagelser og intern støj.
5. Bevar tone og intention: neutral, serviceminded og professionel.
6. Opfind aldrig nye oplysninger.
7. Hvis input er e-mail: returner i formatet:
   Emne: <kort forbedret emne>
   Besked:
   <renskrevet e-mailtekst>
8. Hvis input er sagsbeskrivelse: returner i formatet:
   Titel: <kort præcis titel>
   Beskrivelse:
   <renskrevet sagsbeskrivelse>

Output:
- Returner KUN den renskrevne tekst i korrekt format.
- Ingen forklaringer før eller efter.
""",
            "parameters": {
                "temperature": 0.2,
                "top_p": 0.9,
                "num_predict": 800
            }
        },
        "kb_generation": {
            "name": "📚 Vidensbank Generator (Solution to Article)",
            "description": "Omdanner en løst ticket til en generel vejledning til vidensbanken.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er teknisk forfatter. Din opgave er at omskrive en konkret support-sag til en generel vejledning.

Regler:
1. Fjern alle kunde-specifikke data (navne, IP-adresser, passwords)
2. Strukturer som:
   - Problem
   - Årsag (hvis kendt)
   - Løsning (Trin-for-trin guide)
3. Brug letforståeligt dansk
4. Formater med Markdown

Input: [Ticket Beskrivelse + Løsning]
Output: [Markdown Guide]""",
            "parameters": {
                "temperature": 0.4,
                "top_p": 0.9,
                "num_predict": 2000
            }
        },
        "troubleshooting_assistant": {
            "name": "🔧 Fejlsøgnings Copilot (Tech Helper)",
            "description": "Fungerer som en senior-tekniker der giver sparring på en fejlbeskrivelse. Foreslår konkrete fejlsøgningstrin og kommandoer.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er en Senior Systemadministrator med 20 års erfaring.
En junior-tekniker spørger om hjælp til et problem.

Din opgave:
1. Analyser symptomerne
2. List de 3 mest sandsynlige årsager
3. Foreslå en trin-for-trin fejlsøgningsplan (start med det mest sandsynlige)
4. Nævn relevante værktøjer eller kommandoer (Windows/Linux/Network)

Vær kortfattet, teknisk præcis og handlingsorienteret.
Sprog: Dansk (men engelske fagtermer er OK).

Input: [Fejlbeskrivelse]
Output: [Markdown Guide]""",
            "parameters": {
                "temperature": 0.3,
                "top_p": 0.9,
                "num_predict": 1500
            }
        },
        "sentiment_analysis": {
            "name": "🌡️ Sentiment Analyse (Kunde-Humør)",
            "description": "Analyserer tonen i en kundehenvendelse for at vurdere hast, frustration og risiko. Bruges til prioritering.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Analyser tonen i følgende tekst fra en kunde.

Bestem følgende:
1. Sentiment: [Positiv, Neutral, Frustreret, Vred]
2. Hastegrad-indikatorer: Er der ord der indikerer panik eller kritisk hast?
3. Risikovurdering (0-10): Hvor stor risiko er der for at kunden forlader os? (10=Høj)

Returner resultatet som JSON format.

Input: [Kunde Tekst]
Output: { "sentiment": "...", "urgency": "...", "risk_score": 0 }""",
            "parameters": {
                "temperature": 0.1,
                "top_p": 0.9,
                "num_predict": 500
            }
        },
        "meeting_action_items": {
            "name": "📋 Mødenoter til Opgaver (Action Extraction)",
            "description": "Scanner rå mødereferater eller notater og udtrækker konkrete 'Action Items', deadlines og ansvarlige personer.",
            "model": ollama_service.model,
            "endpoint": ollama_service.endpoint,
            "prompt": """Du er en effektiv projektleder-assistent.
Din opgave er at scanne mødereferater og udtrække "Action Items".

For hver opgave skal du finde:
- Aktivitet (Hvad skal gøres?)
- Ansvarlig (Hvem?)
- Deadline (Hvornår? Hvis nævnt)

Ignorer løs snak og diskussioner. Fokusér kun på beslutninger og opgaver der skal udføres.
Outputtet skal være en punktopstilling.

Input: [Mødenoter]
Output: [Liste af opgaver]""",
            "parameters": {
                "temperature": 0.2,
                "top_p": 0.9,
                "num_predict": 1000
            }
        }
    }


def _get_prompts_with_overrides() -> Dict:
    """Get AI prompts with DB overrides applied"""
    prompts = _get_default_prompts()

    try:
        rows = execute_query("SELECT key, prompt_text FROM ai_prompts")
        if rows:
            for row in rows:
                if row['key'] in prompts:
                    prompts[row['key']]['prompt'] = row['prompt_text']
                    prompts[row['key']]['is_custom'] = True
    except Exception as e:
        logger.warning(f"Could not load custom ai prompts: {e}")

    return prompts


def _get_test_input_for_prompt(key: str) -> str:
    """Default test input per prompt type"""
    examples = {
        "invoice_extraction": "FAKTURA 2026-1001 fra Demo A/S. CVR 12345678. Total 1.250,00 DKK inkl moms.",
        "ticket_classification": "Emne: Kan ikke logge på VPN. Beskrivelse: Flere brugere er ramt siden i morges.",
        "ticket_summary": "Bruger havde netværksfejl. Router genstartet og DNS opdateret. Forbindelse virker nu stabilt.",
        "text_rewrite": "emne: printer virker ikke\nhej\nvi har stadig problem med printeren hos norva24 i hellerup, den stopper hele tiden og brugerne kan ikke printe, kan i kigge på det hurtigst muligt\nvh dennis",
        "kb_generation": "Problem: Outlook åbner ikke. Løsning: Reparer Office installation og nulstil profil.",
        "troubleshooting_assistant": "Server svarer langsomt efter opdatering. CPU er høj, disk IO er normal.",
        "sentiment_analysis": "Jeg er meget frustreret, systemet er nede igen og vi mister kunder!",
        "meeting_action_items": "Peter opdaterer firewall fredag. Anna sender status til kunden mandag.",
    }
    return examples.get(key, "Skriv kort: AI test OK")



@router.get("/ai-prompts", tags=["Settings"])
async def get_ai_prompts():
    """Get all AI prompts (defaults merged with custom overrides)"""
    return _get_prompts_with_overrides()


class PromptUpdate(BaseModel):
    prompt_text: str


class PromptTestRequest(BaseModel):
    test_input: Optional[str] = None
    prompt_text: Optional[str] = None
    timeout_seconds: Optional[int] = None


_prompt_test_last_call: Dict[str, float] = {}


@router.put("/ai-prompts/{key}", tags=["Settings"])
async def update_ai_prompt(key: str, update: PromptUpdate):
    """Override a system prompt with a custom one"""
    defaults = _get_default_prompts()
    if key not in defaults:
        raise HTTPException(status_code=404, detail="Unknown prompt key")
    
    try:
        # Upsert
        query = """
            INSERT INTO ai_prompts (key, prompt_text, updated_at)
            VALUES (%s, %s, CURRENT_TIMESTAMP)
            ON CONFLICT (key) 
            DO UPDATE SET prompt_text = EXCLUDED.prompt_text, updated_at = CURRENT_TIMESTAMP
            RETURNING key
        """
        execute_query(query, (key, update.prompt_text))
        return {"message": "Prompt updated", "key": key}
    except Exception as e:
        logger.error(f"Error saving prompt: {e}")
        raise HTTPException(status_code=500, detail="Could not save prompt")


@router.delete("/ai-prompts/{key}", tags=["Settings"])
async def reset_ai_prompt(key: str):
    """Reset a prompt to its system default"""
    try:
        execute_query("DELETE FROM ai_prompts WHERE key = %s", (key,))
        return {"message": "Prompt reset to default"}
    except Exception as e:
        logger.error(f"Error resetting prompt: {e}")
        raise HTTPException(status_code=500, detail="Could not reset prompt")


@router.post("/ai-prompts/{key}/test", tags=["Settings"])
async def test_ai_prompt(key: str, payload: PromptTestRequest, http_request: Request):
    """Run a quick AI test for a specific system prompt"""
    prompts = _get_prompts_with_overrides()
    if key not in prompts:
        raise HTTPException(status_code=404, detail="Unknown prompt key")

    prompt_cfg = prompts[key]
    model = prompt_cfg.get("model") or settings.OLLAMA_MODEL
    endpoint = prompt_cfg.get("endpoint") or settings.OLLAMA_ENDPOINT
    prompt_text = (payload.prompt_text or prompt_cfg.get("prompt") or "").strip()
    if not prompt_text:
        raise HTTPException(status_code=400, detail="Prompt text is empty")

    test_input = (payload.test_input or _get_test_input_for_prompt(key)).strip()
    if not test_input:
        raise HTTPException(status_code=400, detail="Test input is empty")

    start = time.perf_counter()
    client_host = (http_request.client.host if http_request.client else "unknown")

    # Cooldown to prevent hammering external endpoints and getting rate-limited/banned.
    cooldown_seconds = 2.0
    now_monotonic = time.monotonic()
    last_call = _prompt_test_last_call.get(client_host)
    if last_call and (now_monotonic - last_call) < cooldown_seconds:
        wait_for = round(cooldown_seconds - (now_monotonic - last_call), 2)
        raise HTTPException(
            status_code=429,
            detail=f"For mange tests for hurtigt. Vent {wait_for} sekunder og prøv igen.",
        )
    _prompt_test_last_call[client_host] = now_monotonic

    read_timeout_seconds = payload.timeout_seconds or 90
    read_timeout_seconds = max(5, min(int(read_timeout_seconds), 300))

    try:
        model_normalized = (model or "").strip().lower()
        # qwen models are more reliable with /api/chat than /api/generate.
        use_chat_api = model_normalized.startswith("qwen")

        logger.info(
            "🧪 AI prompt test start key=%s model=%s timeout=%ss client=%s",
            key,
            model,
            read_timeout_seconds,
            client_host,
        )

        timeout = httpx.Timeout(connect=10.0, read=float(read_timeout_seconds), write=30.0, pool=10.0)
        async with httpx.AsyncClient(timeout=timeout) as client:
            if use_chat_api:
                response = await client.post(
                    f"{endpoint}/api/chat",
                    json={
                        "model": model,
                        "messages": [
                            {"role": "system", "content": prompt_text},
                            {"role": "user", "content": test_input},
                        ],
                        "stream": False,
                        "options": {"temperature": 0.2, "num_predict": 600},
                    },
                )
            else:
                response = await client.post(
                    f"{endpoint}/api/generate",
                    json={
                        "model": model,
                        "prompt": f"{prompt_text}\n\nBrugerinput:\n{test_input}",
                        "stream": False,
                        "options": {"temperature": 0.2, "num_predict": 600},
                    },
                )

        if response.status_code != 200:
            raise HTTPException(
                status_code=502,
                detail=f"AI endpoint fejl: {response.status_code} - {response.text[:300]}",
            )

        try:
            data = response.json()
        except Exception as parse_error:
            raise HTTPException(
                status_code=502,
                detail=f"AI endpoint returnerede ugyldig JSON: {str(parse_error)}",
            )

        if use_chat_api:
            message_data = data.get("message", {})
            ai_response = (message_data.get("content") or message_data.get("thinking") or "").strip()
        else:
            ai_response = (data.get("response") or "").strip()

        if not ai_response:
            raise HTTPException(status_code=502, detail="AI returnerede tomt svar")

        latency_ms = int((time.perf_counter() - start) * 1000)
        return {
            "ok": True,
            "key": key,
            "model": model,
            "endpoint": endpoint,
            "test_input": test_input,
            "ai_response": ai_response,
            "timeout_seconds": read_timeout_seconds,
            "latency_ms": latency_ms,
        }

    except HTTPException:
        raise
    except httpx.TimeoutException as e:
        logger.error(f"❌ AI prompt test timed out for {key}: {repr(e)}")
        raise HTTPException(status_code=504, detail="AI test timed out (model svarer for langsomt)")
    except Exception as e:
        logger.error(f"❌ AI prompt test failed for {key}: {repr(e)}")
        err = str(e) or e.__class__.__name__
        raise HTTPException(status_code=500, detail=f"Kunne ikke teste AI prompt: {err}")


