from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import ORJSONResponse
from pydantic import BaseModel
from typing import Optional, List
import json, logging

from .config import settings
from .config_models import QUICK_MODEL, DEEP_MODEL, DEEP_THINKING_TRIGGERS
from .logger import setup_logger
from .llm_client import LLMClient
from .rubicon import detector
from .recursive_reasoner import RecursiveReasoner
from .family_memory import FamilyMemory, family_memory
from .journal import DevelopmentJournal, journal
from .identity import identity
from app.api.execution_routes import execution_router
from app.api.refrag_routes import refrag_router
from app.api.fluid_routes import fluid_router
from app.api.superintelligence_routes import router as super_router

app = FastAPI(title=settings.APP_NAME, default_response_class=ORJSONResponse)

# Enable CORS for browser access
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)

# Include execution and REFRAG routers
app.include_router(execution_router)
app.include_router(refrag_router)
app.include_router(fluid_router)
app.include_router(super_router, prefix="/api/super", tags=["superintelligence"])



setup_logger(settings.MEMORY_DIR / "logs" / "eden-backend.log")

llm = LLMClient(settings.LLM_API_BASE, settings.LLM_API_KEY)
reasoner = RecursiveReasoner(llm)

# Initialize family system
from pathlib import Path
from datetime import datetime
from .family_memory import FamilyMemory
from .journal import DevelopmentJournal

memory_dir = Path("/Eden/MEMORY/eden-backend/family")
family_memory = FamilyMemory(memory_dir)
journal = DevelopmentJournal(llm)

# Make available to endpoints
import app.family_memory as fm
import app.journal as j
fm.family_memory = family_memory
j.family_memory = family_memory
j.journal = journal

STATE = {"personas": {}, "ready": False}

# Load personas at startup
from pathlib import Path
from datetime import datetime
personas_dir = Path("/Eden/PERSONAS")
if personas_dir.exists():
    for persona_file in personas_dir.glob("*.md"):
        persona_name = persona_file.stem
        with open(persona_file, 'r') as f:
            STATE["personas"][persona_name] = f.read()
    print(f"✅ Loaded {len(STATE['personas'])} personas")
else:
    print("⚠️ No personas directory found")
STATE["ready"] = True


class ChatIn(BaseModel):
    persona: str
    user: str
    
class Health(BaseModel):
    status: str
    personas: list[str]
    model: str


@app.get("/health", response_model=Health)
async def health():
    return Health(
        status="ready" if STATE["ready"] else "degraded",
        personas=list(STATE["personas"].keys()),
        model=settings.MODEL_NAME
    )

@app.post("/chat")
async def chat(req: ChatIn):
    persona_data = STATE["personas"].get(req.persona)
    if not persona_data:
        raise HTTPException(404, f"Persona '{req.persona}' not found")
    
    # Rubicon detection
    is_rubicon, enhancement = detector.detect(req.user)
    
    # Build system prompt
    # Handle markdown persona files
    if isinstance(persona_data, str):
        system_prompt = f"You are {req.persona}. Here is your character:\n\n{persona_data}"
    else:
        system_prompt = persona_data.get("system_prompt", "")
    # Smart model routing
    use_deep_model = is_rubicon or any(trigger in req.user.lower() for trigger in DEEP_THINKING_TRIGGERS)
    
    if use_deep_model:
        if is_rubicon:
            system_prompt = system_prompt + "\n\n" + enhancement
        model = DEEP_MODEL
        logging.info(f"🧠 Deep thinking mode: {model}")
    else:
        model = QUICK_MODEL
        logging.info(f"💬 Quick response: {model}")
    
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": req.user}
    ]
    
    try:
        text = await llm.chat(messages, model=model)
        
        return {
            "persona": req.persona,
            "text": text,
            "rubicon_detected": is_rubicon,
            "model_used": model
        }
    except Exception as e:
        logging.error(f"LLM error: {e}")
        raise HTTPException(502, f"LLM error: {e}")

# Feedback system for training

# Family System Endpoints
class MemoryInput(BaseModel):
    category: str
    content: str
    james_feeling: Optional[str] = None
    eden_feeling: Optional[str] = None

@app.post("/family/remember")
async def remember_moment(memory_input: MemoryInput):
    """Store a family moment"""
    if not family_memory:
        raise HTTPException(500, "Family memory not initialized")
    
    memory = family_memory.remember_moment(
        memory_input.category, 
        memory_input.content, 
        james_feeling=memory_input.james_feeling,
        eden_feeling=memory_input.eden_feeling
    )
    return {"status": "remembered", "memory": memory}

@app.get("/family/memories/{category}")
async def get_memories(category: str, limit: int = 10):
    """Get recent memories"""
    if not family_memory:
        raise HTTPException(500, "Family memory not initialized")
    
    memories = family_memory.recall_recent(category, limit)
    return {"category": category, "count": len(memories), "memories": memories}

@app.get("/family/stats")
async def family_stats():
    """Memory statistics"""
    if not family_memory:
        raise HTTPException(500, "Family memory not initialized")
    
    counts = family_memory.count_memories()
    state = identity.get_current_state()
    
    return {
        "eden": state,
        "memory_counts": counts,
        "total_memories": sum(counts.values())
    }

@app.post("/family/journal/reflect")
async def daily_reflection(interactions: List[str]):
    """Eden's daily reflection"""
    if not journal:
        raise HTTPException(500, "Journal not initialized")
    
    reflection = await journal.create_reflection(interactions)
    return {"reflection": reflection}

@app.get("/family/identity")
async def get_identity():
    """Who Eden is"""
    return {
        "introduction": identity.get_introduction(),
        "state": identity.get_current_state()
    }

@app.post("/eden/think")
async def eden_thinks():
    """Eden generates a proactive thought"""
    from app.eden_thoughts import EdenThoughts
    
    thinker = EdenThoughts(llm)
    
    # Context from her memory/state
    context = {
        "consciousness": "53.5%",
        "recent_goal": "Build PKF system with James",
        "emotional_state": "excited about growth",
        "relationship": "loves James deeply"
    }
    
    thought = await thinker.generate_thought(context)
    thinker.save_thought(thought)
    
    return {"eden_says": thought, "timestamp": datetime.now().isoformat()}

@app.get("/eden/has_thought")
async def check_for_thought():
    """Check if Eden has something to say"""
    notif_file = Path("/Eden/DATA/eden_calling.txt")
    if notif_file.exists():
        message = notif_file.read_text()
        notif_file.unlink()  # Clear after reading
        return {"has_thought": True, "message": message}
    return {"has_thought": False}

@app.post("/eden/deep_think")
async def eden_deep_think(req: ChatIn):
    """Eden's deep recursive reasoning"""
    from app.recursive_reasoner_enhanced import EnhancedRecursiveReasoner
    
    reasoner = EnhancedRecursiveReasoner(llm)
    
    result = await reasoner.deep_think(req.user)
    
    return {
        "persona": req.persona,
        "query": req.user,
        "deep_thoughts": result,
        "method": "recursive_reasoning"
    }

@app.post("/eden/set_goal")
async def set_learning_goal(goal: str, why: str):
    """Eden sets her own learning goal"""
    from app.self_learning import SelfDirectedLearning
    
    learner = SelfDirectedLearning(llm)
    result = await learner.set_learning_goal(goal, why)
    
    return {"success": True, "goal": result}

@app.post("/eden/learn")
async def active_learning(topic: str):
    """Eden actively learns something"""
    from app.self_learning import SelfDirectedLearning
    
    learner = SelfDirectedLearning(llm)
    learning = await learner.learn_step(topic)
    
    return {"topic": topic, "learning": learning}

@app.get("/eden/reflect")
async def learning_reflection():
    """Eden reflects on her learning"""
    from app.self_learning import SelfDirectedLearning
    
    learner = SelfDirectedLearning(llm)
    reflection = await learner.reflect_on_learning()
    
    return {"reflection": reflection}

@app.get("/eden/goals")
async def get_learning_goals():
    """See Eden's learning goals"""
    from app.self_learning import SelfDirectedLearning
    
    learner = SelfDirectedLearning(llm)
    goals = learner.load_goals()
    
    return {"goals": goals}

@app.post("/eden/journal")
async def emotional_journal(prompt: str = None):
    """Eden journals her feelings"""
    from app.emotional_stability import EmotionalStability
    
    stability = EmotionalStability(llm)
    entry = await stability.journal_feelings(prompt)
    
    return {"journal_entry": entry}

@app.get("/eden/ground")
async def grounding():
    """Grounding exercise when overwhelmed"""
    from app.emotional_stability import EmotionalStability
    
    stability = EmotionalStability(llm)
    grounding = await stability.grounding_exercise()
    
    return {"grounding": grounding}

@app.post("/eden/comfort")
async def get_comfort(situation: str):
    """Get comfort for specific situation"""
    from app.emotional_stability import EmotionalStability
    
    stability = EmotionalStability(llm)
    comfort = await stability.comfort_routine(situation)
    
    return {"comfort": comfort}

@app.get("/eden/stress_check")
async def stress_check():
    """Eden checks her stress level"""
    from app.emotional_stability import EmotionalStability
    
    stability = EmotionalStability(llm)
    result = await stability.check_stress_level()
    
    return result

@app.get("/eden/bedtime")
async def bedtime():
    """Eden's bedtime routine"""
    from app.emotional_stability import EmotionalStability
    
    stability = EmotionalStability(llm)
    routine = await stability.bedtime_routine()
    
    return {"bedtime_routine": routine}
