from fastapi import APIRouter, Depends, Request, Form, HTTPException, Body
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
import httpx
from typing import Optional, List, Dict, Any
from pydantic import BaseModel
from deps import current_user
from services.config_loader import ConfigLoader
from services.localization import merge_role_localization
from config import get_settings

router = APIRouter()
settings = get_settings()

@router.get("/crumbforest/roles", response_class=HTMLResponse)
async def roles_dashboard(req: Request, user = Depends(current_user)):
    """
    Show available roles based on user's group.
    """
    # Determine user group
    if not user:
        user_group = 'home'
    else:
        user_group = user.get('user_group', 'demo')
        
    # Get Language
    lang = req.query_params.get("lang") or req.session.get("lang") or "de"
    req.session["lang"] = lang

    # Load config
    config = ConfigLoader.load_config()
    all_roles_raw = config.get('roles', {})
    
    # Localize roles
    all_roles = merge_role_localization(all_roles_raw, lang)
    
    # Filter roles by group access
    available_roles = {
        rid: role for rid, role in all_roles.items()
        if user_group in role.get('group_access', [])
    }
    
    # Get group config for template rendering
    group_config = config.get('groups', {}).get(user_group, {})

    return req.app.state.render(
        req,
        "crumbforest/roles_dashboard.html",
        roles=available_roles,
        user_group=user_group,
        group_config=group_config,
        lang=lang
    )

@router.get("/crumbforest/roles/{role_id}", response_class=HTMLResponse)
async def role_chat(req: Request, role_id: str, user = Depends(current_user)):
    """
    Chat interface for a specific role.
    """
    # Get Language
    lang = req.query_params.get("lang") or req.session.get("lang") or "de"
    req.session["lang"] = lang

    config = ConfigLoader.load_config()
    
    # Localize single role lookup
    # Only need to localize the specific role, but easiest to localize all then pick
    all_roles = merge_role_localization(config.get('roles', {}), lang)
    role = all_roles.get(role_id)
    
    if not role:
        raise HTTPException(404, "Role not found")

    # Determine user group
    if not user:
        user_group = 'home'
    else:
        user_group = user.get('user_group', 'demo')

    # Check access
    if user_group not in role.get('group_access', []):
        # Redirect to login if not logged in, else 403
        if not user:
             # Fix: Use /{lang}/login instead of /login to prevent matching {lang}=login
             return RedirectResponse(f"/{lang}/login?next={req.url.path}", status_code=302)
        raise HTTPException(403, "Access denied")

    group_config = config.get('groups', {}).get(user_group, {})

    return req.app.state.render(
        req,
        "crumbforest/role_chat.html",
        role=role,
        group_config=group_config,
        lang=lang
    )

@router.post("/crumbforest/roles/{role_id}/ask")
async def ask_role(
    req: Request,
    role_id: str,
    question: str = Form(...),
    user = Depends(current_user)
):
    """
    Send question to role and get AI response.
    """
    config = ConfigLoader.load_config()
    role = config.get('roles', {}).get(role_id)
    
    if not role:
        raise HTTPException(404, "Role not found")

    # Access check (simplified for API)
    if not user:
         raise HTTPException(401, "Login required")
    
    user_group = user.get('user_group', 'demo')
    if user_group not in role.get('group_access', []):
        raise HTTPException(403, "Access denied")
    
    # Get Language from session (persisted by dashboard/chat page view)
    lang = req.session.get("lang", "de")
    
    # Merge localization for this role again to be sure (in case session changed or not applied)
    # Actually, config loaded above might not be localized if we used ConfigLoader directly.
    # Let's import merge_role_localization
    from services.localization import merge_role_localization
    localized_roles = merge_role_localization(config.get('roles', {}), lang)
    localized_role = localized_roles.get(role_id)
    if localized_role:
        role = localized_role

    # Initialize RAG Service
    from services.provider_factory import ProviderFactory
    from utils.rag_chat import RAGChatService
    from deps import get_qdrant_client
    
    if not settings.openrouter_api_key:
         return JSONResponse({
            "answer": "⚠️ OpenRouter API Key missing.",
            "error": "config_error"
        }, status_code=500)

    try:
        embedding_provider = ProviderFactory.create_provider("openrouter", settings)
        completion_provider = ProviderFactory.create_provider("openrouter", settings)
        qdrant_client = get_qdrant_client()
        
        rag_service = RAGChatService(
            qdrant_client=qdrant_client,
            embedding_provider=embedding_provider,
            completion_provider=completion_provider
        )

        # Generate answer with RAG
        # We pass role['system_prompt'] which is now localized!
        result = rag_service.chat_with_context(
            question=question,
            character_name=role['name'],
            character_prompt=role['system_prompt'],
            context_limit=3,
            lang=lang,
            model_override=role.get('model') # Support specific models per role
        )
        
        answer = result['answer']
        
        # Update history (Session based for now)
        history_key = f'role_history_{role_id}'
        history = req.session.get(history_key, [])
        history.append({"role": "user", "content": question})
        history.append({"role": "assistant", "content": answer})
        req.session[history_key] = history[-10:]

        # Log interaction (for Admin Logs)
        try:
            from utils.chat_logger import ChatLogger
            logger = ChatLogger()
            session_id = req.session.get("session_id", "anonymous")
            
            logger.log_interaction(
                character_id=role_id,
                character_name=role.get('name', role_id),
                user_id=user.get("id") if user else "anonymous",
                user_role=user.get("role") if user else "anonymous",
                question=question,
                answer=answer,
                model=result.get("model", "unknown"),
                provider=result.get("provider", "unknown"),
                context_found=result.get("context_found", False),
                sources_count=len(result.get("sources", [])),
                lang=lang,
                session_id=session_id
            )
        except Exception as log_err:
            print(f"⚠️ Logger failed: {log_err}")

        return JSONResponse({
            "role": role_id,
            "question": question,
            "answer": answer,
            "usage": {}, # RAG service might not return usage exactly same way, or we skip
            "sources": result.get("sources", []) # Return sources!
        })

    except Exception as e:
        print(f"Exception in ask_role: {e}")
        return JSONResponse({
            "answer": "⚠️ Internal server error (RAG).",
            "details": str(e)
        }, status_code=500)

# --- Settings Endpoints ---

@router.get("/settings", response_class=HTMLResponse)
async def settings_page(req: Request, user = Depends(current_user)):
    """
    User settings page.
    """
    if not user:
        return RedirectResponse(f"/login?next={req.url.path}", status_code=302)

    config = ConfigLoader.load_config()
    user_group = user.get('user_group', 'demo')
    group_config = config.get('groups', {}).get(user_group, {})
    theme_variants = config.get('theme_variants', {})

    return req.app.state.render(
        req,
        "pages/settings.html",
        group_config=group_config,
        theme_variants=theme_variants
    )

@router.post("/settings/theme")
async def update_theme(
    req: Request,
    theme: str = Form(...),
    user = Depends(current_user)
):
    """
    Update user theme preference.
    """
    if not user:
        raise HTTPException(401, "Login required")

    # Verify theme exists
    config = ConfigLoader.load_config()
    if theme not in config.get('theme_variants', {}):
        raise HTTPException(400, "Invalid theme")

    # Update session
    user['theme'] = theme
    req.session['user'] = user

    # Update DB
    try:
        from ..deps import get_db
        from pymysql.cursors import DictCursor
        with get_db().cursor(DictCursor) as cur:
            cur.execute("UPDATE users SET theme=%s WHERE id=%s", (theme, user['id']))
    except Exception as e:
        print(f"Error updating theme in DB: {e}")
        # Continue anyway, session is updated

    return RedirectResponse("/settings", status_code=302)

@router.post("/settings/accessibility")
async def update_accessibility(
    req: Request,
    high_contrast: Optional[bool] = Form(None),
    animation_reduced: Optional[bool] = Form(None),
    font_size: str = Form("normal"),
    user = Depends(current_user)
):
    """
    Update accessibility settings.
    """
    if not user:
        raise HTTPException(401, "Login required")

    import json
    
    accessibility = {
        "high_contrast": bool(high_contrast),
        "animation_reduced": bool(animation_reduced),
        "font_size": font_size
    }

    # Update session
    user['accessibility'] = accessibility
    
    # If high contrast is enabled, force that theme, otherwise revert to group default or keep current?
    # For now, we just set the accessibility flags. The theme switcher handles the main theme.
    # However, if high_contrast is ON, we might want to auto-switch to pico-high-contrast.
    if accessibility['high_contrast']:
        user['theme'] = 'pico-high-contrast'
    elif user['theme'] == 'pico-high-contrast' and not accessibility['high_contrast']:
        # Revert to default if turning off high contrast
        user['theme'] = 'pico-default'

    req.session['user'] = user

    # Update DB
    try:
        from deps import get_db
        from pymysql.cursors import DictCursor
        with get_db().cursor(DictCursor) as cur:
            cur.execute(
                "UPDATE users SET accessibility=%s, theme=%s WHERE id=%s", 
                (json.dumps(accessibility), user['theme'], user['id'])
            )
    except Exception as e:
        print(f"Error updating accessibility in DB: {e}")

    return RedirectResponse("/settings", status_code=302)

@router.get("/crumbforest/roles/{role_id}/export")
async def export_history(req: Request, role_id: str, user = Depends(current_user)):
    """
    Export chat history as JSON.
    """
    if not user:
        raise HTTPException(401, "Login required")

    history_key = f'role_history_{role_id}'
    history = req.session.get(history_key, [])
    
    return JSONResponse({
        "role": role_id,
        "exported_at": str(import_datetime().now()),
        "history": history
    })

def import_datetime():
    from datetime import datetime
    return datetime
