from fastapi import FastAPI, Request, BackgroundTasks, HTTPException
import uvicorn
import json
import logging
from datetime import datetime
from typing import Dict, Any

from core.memory.redis_connector import redis_client

# Configure Logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("GenesisSynapse")

app = FastAPI(title="Genesis Synapse Bridge")

# Channels
CH_COMMANDS = "genesis:commands"
CH_OBSERVATIONS = "genesis:observations"
CH_EPISODIC = "genesis:memory:episodic"

@app.on_event("startup")
async def startup_event():
    logger.info("Genesis Synapse Bridge starting up...")
    # Verify Redis connection
    try:
        redis_client.client.ping()
        logger.info("Connected to Genesis Redis Cortex")
        
        # Start background listener for ClawdBot Observations
        redis_client.subscribe(CH_OBSERVATIONS, process_observation)
        
    except Exception as e:
        logger.error(f"Failed to connect to Redis: {e}")

def process_observation(message: Dict[str, Any]):
    """
    Bridge function: Receives Real-time Observations (ClawdBot/Telegram) 
    and commits them to Episodic Memory Stream.
    """
    try:
        # Avoid circular logging if the source is already Synapse/Vapi
        if message.get("source") == "vapi":
            return
            
        logger.info(f"Synapse received observation from {message.get('source')}: {message.get('type')}")
        
        # Add to Episodic Memory Stream
        redis_client.stream_add(CH_EPISODIC, message)
        
    except Exception as e:
        logger.error(f"Error bridging observation to stream: {e}")

@app.post("/vapi/webhook")
async def vapi_webhook(request: Request, background_tasks: BackgroundTasks):
    """
    Endpoint for Vapi.ai webhooks (Incoming Voice Events).
    """
    try:
        payload = await request.json()
        
        # We process this asynchronously to return 200 OK fast to Vapi
        background_tasks.add_task(process_vapi_event, payload)
        
        return {"status": "received"}
    except Exception as e:
        logger.error(f"Error processing Vapi webhook: {e}")
        raise HTTPException(status_code=500, detail="Internal Server Error")

def process_vapi_event(payload: Dict[str, Any]):
    """
    Process the Vapi event and push to Redis Stream.
    """
    message_type = payload.get("message", {}).get("type")
    
    event_data = {
        "source": "vapi",
        "type": message_type,
        "payload": json.dumps(payload),
        "timestamp": datetime.utcnow().isoformat()
    }
    
    # 1. Log to Stream for Episodic Memory
    redis_client.stream_add(CH_EPISODIC, event_data)
    
    # 2. If it's a transcript or function call, publish to live observers (Clawdbot/Genesis)
    if message_type in ["transcript", "function-call", "end-of-call"]:
        redis_client.publish(CH_OBSERVATIONS, event_data)
        logger.info(f"Published Vapi event {message_type} to {CH_OBSERVATIONS}")

@app.post("/genesis/command")
async def genesis_command_endpoint(command: Dict[str, Any]):
    """
    Internal endpoint for Genesis agents to send commands to Clawdbot via HTTP
    (Alternative to direct Redis publishing).
    """
    # Push to command channel
    redis_client.publish(CH_COMMANDS, command)
    return {"status": "published", "channel": CH_COMMANDS}

@app.get("/health")
def health_check():
    return {"status": "active", "redis": redis_client.client.ping()}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
