"""
Glitch Mega-Skill — Unified webhook handler combining:
  - GHL MCP (36 tools: contacts, conversations, opportunities, payments, blogs, social, email)
  - Skillboss (687 endpoints: image gen, video, search, scrape, social data, TTS, STT, etc.)
  - Arcee Trinity (400B reasoning model for deep thinking)

Exposes REST webhooks that GHL workflows, n8n, or any HTTP client can call.
Each endpoint accepts JSON and returns JSON — no auth required (internal use).

Base URL: https://agents.realtalkha.com/api/webhooks/glitch/
"""

import os
import sys
import json
import asyncio
import logging
from datetime import datetime, timezone
from typing import Optional
from pydantic import BaseModel

# Ensure GHL MCP helper is importable
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "ghl-mcp-server"))

logger = logging.getLogger("glitch-skill")

# ═══════════════════════════════════════════════════════════
# CONFIG
# ═══════════════════════════════════════════════════════════
SKILLBOSS_API_KEY = os.getenv("SKILLBOSS_API_KEY", "")
SKILLBOSS_BASE = "https://api.skillboss.co/v1"
GHL_PIT_TOKEN = os.getenv("GHL_MCP_PIT_TOKEN", os.environ.get("GHL_AGENCY_PIT", ""))
GHL_LOCATION_ID = os.getenv("GHL_MCP_LOCATION_ID", "ifitVy09cFwlEVgEAFDS")
ARCEE_API_KEY = os.getenv("ARCEE_API_KEY", "")
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY", "")

# ═══════════════════════════════════════════════════════════
# REQUEST MODELS
# ═══════════════════════════════════════════════════════════

class GHLRequest(BaseModel):
    """Execute any GHL MCP tool."""
    tool: str                          # e.g. "contacts_get-contacts"
    params: dict = {}                  # tool-specific params
    contact_id: Optional[str] = None   # shortcut for contact operations
    tags: Optional[list] = None        # shortcut for tag operations
    message: Optional[str] = None      # shortcut for send message
    query: Optional[str] = None        # shortcut for search operations

class SearchRequest(BaseModel):
    """Web search via Skillboss."""
    query: str
    provider: str = "perplexity"       # perplexity, linkup

class ScrapeRequest(BaseModel):
    """Web scrape via Skillboss."""
    url: str

class ImageRequest(BaseModel):
    """Generate an image via Skillboss."""
    prompt: str
    model: str = "flux-1.1-pro"        # flux-schnell, flux-1.1-pro, vertex/gemini-3-pro-image-preview, neta/ghibli-style

class VideoRequest(BaseModel):
    """Generate a video via Skillboss."""
    prompt: str
    model: str = "google/veo-3.1-fast"
    image_url: Optional[str] = None    # for image-to-video

class SocialRequest(BaseModel):
    """Fetch social media data."""
    platform: str                      # twitter, instagram, linkedin, tiktok
    profile_id: str

class TTSRequest(BaseModel):
    """Text to speech."""
    text: str
    voice_id: str = "21m00Tcm4TlvDq8ikWAM"  # default ElevenLabs voice

class STTRequest(BaseModel):
    """Speech to text."""
    file_url: str

class EmailRequest(BaseModel):
    """Send email via Skillboss."""
    to: str
    subject: str
    body: str

class ThinkRequest(BaseModel):
    """Deep reasoning via Arcee Trinity."""
    prompt: str
    context: Optional[str] = None

class SlideRequest(BaseModel):
    """Generate a pitch deck / presentation."""
    prompt: str

class LandingPageRequest(BaseModel):
    """Generate a landing page."""
    prompt: str

class BlogRequest(BaseModel):
    """Create a blog post in GHL."""
    title: str
    content: str
    blog_id: str
    author_id: Optional[str] = None
    category_id: Optional[str] = None

class SocialPostRequest(BaseModel):
    """Create/edit social media post in GHL."""
    action: str = "create"             # create, edit, get
    content: Optional[str] = None
    post_id: Optional[str] = None
    platforms: Optional[list] = None

class UnifiedRequest(BaseModel):
    """Unified endpoint — routes to the right handler based on action."""
    action: str                        # ghl, search, scrape, image, video, social, tts, stt, email, think, slides, landing, blog, social_post
    params: dict = {}


# ═══════════════════════════════════════════════════════════
# SKILLBOSS CALLER
# ═══════════════════════════════════════════════════════════
async def _skillboss_call(model: str, inputs: dict) -> dict:
    """Call Skillboss API."""
    import httpx
    if not SKILLBOSS_API_KEY:
        return {"success": False, "error": "SKILLBOSS_API_KEY not configured"}
    try:
        async with httpx.AsyncClient(timeout=180) as client:
            res = await client.post(
                f"{SKILLBOSS_BASE}/run",
                headers={"Authorization": f"Bearer {SKILLBOSS_API_KEY}", "Content-Type": "application/json"},
                json={"model": model, "inputs": inputs},
            )
        if res.status_code >= 400:
            return {"success": False, "error": f"Skillboss error ({res.status_code}): {res.text[:500]}"}
        return {"success": True, "data": res.json()}
    except Exception as e:
        return {"success": False, "error": str(e)}


async def _skillboss_chat(model: str, messages: list) -> dict:
    """Call Skillboss chat completions."""
    import httpx
    if not SKILLBOSS_API_KEY:
        return {"success": False, "error": "SKILLBOSS_API_KEY not configured"}
    try:
        async with httpx.AsyncClient(timeout=180) as client:
            res = await client.post(
                f"{SKILLBOSS_BASE}/chat/completions",
                headers={"Authorization": f"Bearer {SKILLBOSS_API_KEY}", "Content-Type": "application/json"},
                json={"model": model, "messages": messages},
            )
        if res.status_code >= 400:
            return {"success": False, "error": f"Skillboss chat error ({res.status_code}): {res.text[:500]}"}
        return {"success": True, "data": res.json()}
    except Exception as e:
        return {"success": False, "error": str(e)}


# ═══════════════════════════════════════════════════════════
# GHL MCP CALLER
# ═══════════════════════════════════════════════════════════
async def _ghl_call(tool_name: str, arguments: dict) -> dict:
    """Call a GHL MCP tool."""
    try:
        from ghl_mcp_client import GHLMCPClient
        client = GHLMCPClient(pit_token=GHL_PIT_TOKEN, location_id=GHL_LOCATION_ID)
        async with client.connect():
            result = await client.call_tool(tool_name, arguments)
        return {"success": True, "data": result}
    except Exception as e:
        return {"success": False, "error": str(e)}


# ═══════════════════════════════════════════════════════════
# ARCEE TRINITY CALLER
# ═══════════════════════════════════════════════════════════
async def _arcee_think(prompt: str, context: str = None) -> dict:
    """Deep reasoning via Arcee Trinity on OpenRouter."""
    import httpx
    api_key = OPENROUTER_API_KEY or SKILLBOSS_API_KEY
    if not api_key:
        return {"success": False, "error": "No API key for Arcee Trinity"}

    messages = []
    if context:
        messages.append({"role": "system", "content": context})
    messages.append({"role": "user", "content": prompt})

    # Try via Skillboss chat first (free)
    result = await _skillboss_chat("arcee-ai/arcee-blitz", messages)
    if result.get("success"):
        return result

    # Fallback: try direct OpenRouter
    try:
        async with httpx.AsyncClient(timeout=120) as client:
            res = await client.post(
                "https://openrouter.ai/api/v1/chat/completions",
                headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
                json={"model": "arcee-ai/arcee-blitz", "messages": messages},
            )
        if res.status_code >= 400:
            return {"success": False, "error": f"Arcee error: {res.text[:500]}"}
        return {"success": True, "data": res.json()}
    except Exception as e:
        return {"success": False, "error": str(e)}


# ═══════════════════════════════════════════════════════════
# HANDLER FUNCTIONS
# ═══════════════════════════════════════════════════════════

async def handle_ghl(req: GHLRequest) -> dict:
    """Execute a GHL MCP tool."""
    tool = req.tool
    params = dict(req.params)

    # Shortcuts
    if req.contact_id and "contactId" not in str(params):
        params["path_contactId"] = req.contact_id
    if req.tags:
        params["body_tags"] = req.tags
    if req.message:
        params["body_message"] = req.message
    if req.query:
        params["query_query"] = req.query

    # Auto-inject locationId where needed
    if "locationId" not in str(params):
        params["query_locationId"] = GHL_LOCATION_ID

    return await _ghl_call(tool, params)


async def handle_search(req: SearchRequest) -> dict:
    """Web search."""
    model_map = {
        "perplexity": "perplexity/search",
        "linkup": "linkup/search",
    }
    model = model_map.get(req.provider, "perplexity/search")
    return await _skillboss_call(model, {"query": req.query})


async def handle_scrape(req: ScrapeRequest) -> dict:
    """Web scrape."""
    url = req.url.strip()
    if not url.startswith("http"):
        url = "https://" + url
    return await _skillboss_call("firecrawl/scrape", {"url": url})


async def handle_image(req: ImageRequest) -> dict:
    """Generate image."""
    return await _skillboss_call(req.model, {"prompt": req.prompt})


async def handle_video(req: VideoRequest) -> dict:
    """Generate video."""
    inputs = {"prompt": req.prompt}
    if req.image_url:
        inputs["image_url"] = req.image_url
    return await _skillboss_call(req.model, inputs)


async def handle_social_data(req: SocialRequest) -> dict:
    """Fetch social profile data."""
    model_map = {
        "twitter": "twitter-profile",
        "x": "twitter-profile",
        "instagram": "instagram-profile",
        "linkedin": "linkedin-profile",
        "tiktok": "tiktok-profile",
    }
    model = model_map.get(req.platform.lower())
    if not model:
        return {"success": False, "error": f"Unknown platform: {req.platform}"}
    return await _skillboss_call(model, {"profileId": req.profile_id})


async def handle_tts(req: TTSRequest) -> dict:
    """Text to speech."""
    return await _skillboss_call("elevenlabs/eleven_multilingual_v2", {
        "text": req.text,
        "voice_id": req.voice_id,
    })


async def handle_stt(req: STTRequest) -> dict:
    """Speech to text."""
    return await _skillboss_call("openai/whisper-1", {"file_url": req.file_url})


async def handle_email(req: EmailRequest) -> dict:
    """Send email."""
    return await _skillboss_call("aws/send-emails", {
        "to": req.to,
        "subject": req.subject,
        "body": req.body,
    })


async def handle_think(req: ThinkRequest) -> dict:
    """Deep reasoning."""
    return await _arcee_think(req.prompt, req.context)


async def handle_slides(req: SlideRequest) -> dict:
    """Generate presentation."""
    return await _skillboss_call("gamma/generation", {"prompt": req.prompt})


async def handle_landing(req: LandingPageRequest) -> dict:
    """Generate landing page."""
    return await _skillboss_call("stitch/generate-desktop", {"prompt": req.prompt})


async def handle_blog(req: BlogRequest) -> dict:
    """Create a blog post in GHL."""
    params = {
        "body_title": req.title,
        "body_blogId": req.blog_id,
        "body_locationId": GHL_LOCATION_ID,
        "body_rawHTML": req.content,
    }
    if req.author_id:
        params["body_authorId"] = req.author_id
    if req.category_id:
        params["body_categoryId"] = req.category_id
    return await _ghl_call("blogs_create-blog-post", params)


async def handle_social_post(req: SocialPostRequest) -> dict:
    """Create/edit social media posts in GHL."""
    if req.action == "get" and req.post_id:
        return await _ghl_call("social-media-posting_get-post", {"path_postId": req.post_id})
    elif req.action == "create":
        params = {"body_locationId": GHL_LOCATION_ID}
        if req.content:
            params["body_summary"] = req.content
        return await _ghl_call("social-media-posting_create-post", params)
    elif req.action == "edit" and req.post_id:
        params = {"path_postId": req.post_id}
        if req.content:
            params["body_summary"] = req.content
        return await _ghl_call("social-media-posting_edit-post", params)
    return {"success": False, "error": "Invalid social post action"}


# ═══════════════════════════════════════════════════════════
# UNIFIED ROUTER
# ═══════════════════════════════════════════════════════════
ACTION_MAP = {
    "ghl": (GHLRequest, handle_ghl),
    "search": (SearchRequest, handle_search),
    "scrape": (ScrapeRequest, handle_scrape),
    "image": (ImageRequest, handle_image),
    "video": (VideoRequest, handle_video),
    "social": (SocialRequest, handle_social_data),
    "tts": (TTSRequest, handle_tts),
    "stt": (STTRequest, handle_stt),
    "email": (EmailRequest, handle_email),
    "think": (ThinkRequest, handle_think),
    "slides": (SlideRequest, handle_slides),
    "landing": (LandingPageRequest, handle_landing),
    "blog": (BlogRequest, handle_blog),
    "social_post": (SocialPostRequest, handle_social_post),
}

async def handle_unified(req: UnifiedRequest) -> dict:
    """Route to the right handler based on action type."""
    action = req.action.lower().strip()
    if action not in ACTION_MAP:
        return {
            "success": False,
            "error": f"Unknown action: {action}",
            "available_actions": list(ACTION_MAP.keys()),
        }
    model_cls, handler = ACTION_MAP[action]
    try:
        typed_req = model_cls(**req.params)
        return await handler(typed_req)
    except Exception as e:
        return {"success": False, "error": f"Invalid params for {action}: {str(e)}"}


# ═══════════════════════════════════════════════════════════
# FASTAPI ROUTER (import into main.py)
# ═══════════════════════════════════════════════════════════
from fastapi import APIRouter

router = APIRouter(prefix="/api/webhooks/glitch", tags=["Glitch Skill"])

@router.post("/")
async def glitch_unified(req: UnifiedRequest):
    """Unified endpoint — routes based on action field."""
    result = await handle_unified(req)
    result["timestamp"] = datetime.now(timezone.utc).isoformat()
    result["action"] = req.action
    return result

@router.post("/ghl")
async def glitch_ghl(req: GHLRequest):
    """Execute any GHL MCP tool."""
    return await handle_ghl(req)

@router.post("/search")
async def glitch_search(req: SearchRequest):
    """Web search."""
    return await handle_search(req)

@router.post("/scrape")
async def glitch_scrape(req: ScrapeRequest):
    """Web scrape."""
    return await handle_scrape(req)

@router.post("/image")
async def glitch_image(req: ImageRequest):
    """Generate image."""
    return await handle_image(req)

@router.post("/video")
async def glitch_video(req: VideoRequest):
    """Generate video."""
    return await handle_video(req)

@router.post("/social")
async def glitch_social(req: SocialRequest):
    """Fetch social media data."""
    return await handle_social_data(req)

@router.post("/tts")
async def glitch_tts(req: TTSRequest):
    """Text to speech."""
    return await handle_tts(req)

@router.post("/stt")
async def glitch_stt(req: STTRequest):
    """Speech to text."""
    return await handle_stt(req)

@router.post("/email")
async def glitch_email(req: EmailRequest):
    """Send email."""
    return await handle_email(req)

@router.post("/think")
async def glitch_think(req: ThinkRequest):
    """Deep reasoning via Arcee Trinity."""
    return await handle_think(req)

@router.post("/slides")
async def glitch_slides(req: SlideRequest):
    """Generate presentation."""
    return await handle_slides(req)

@router.post("/landing")
async def glitch_landing(req: LandingPageRequest):
    """Generate landing page."""
    return await handle_landing(req)

@router.post("/blog")
async def glitch_blog(req: BlogRequest):
    """Create GHL blog post."""
    return await handle_blog(req)

@router.post("/social-post")
async def glitch_social_post(req: SocialPostRequest):
    """Create/edit GHL social posts."""
    return await handle_social_post(req)

@router.get("/tools")
async def glitch_list_tools():
    """List all available Glitch skill capabilities."""
    return {
        "skill": "Glitch Mega-Skill v1.0",
        "base_url": "https://agents.realtalkha.com/api/webhooks/glitch",
        "unified_endpoint": "POST /api/webhooks/glitch/",
        "tools": {
            "ghl": {
                "description": "Execute any of 36 GHL MCP tools",
                "endpoint": "/ghl",
                "tools": [
                    "contacts_get-contacts", "contacts_get-contact", "contacts_create-contact",
                    "contacts_update-contact", "contacts_upsert-contact",
                    "contacts_add-tags", "contacts_remove-tags", "contacts_get-all-tasks",
                    "conversations_search-conversation", "conversations_get-messages",
                    "conversations_send-a-new-message",
                    "opportunities_search-opportunity", "opportunities_get-pipelines",
                    "opportunities_get-opportunity", "opportunities_update-opportunity",
                    "calendars_get-calendar-events", "calendars_get-appointment-notes",
                    "payments_get-order-by-id", "payments_list-transactions",
                    "locations_get-location", "locations_get-custom-fields",
                    "social-media-posting_create-post", "social-media-posting_edit-post",
                    "social-media-posting_get-post", "social-media-posting_get-posts",
                    "social-media-posting_get-account", "social-media-posting_get-social-media-statistics",
                    "blogs_get-blogs", "blogs_get-blog-post", "blogs_create-blog-post",
                    "blogs_update-blog-post", "blogs_check-url-slug-exists",
                    "blogs_get-all-categories-by-location", "blogs_get-all-blog-authors-by-location",
                    "emails_fetch-template", "emails_create-template",
                ],
            },
            "search": {"description": "Web search (Perplexity or Linkup)", "endpoint": "/search"},
            "scrape": {"description": "Web scrape any URL to markdown", "endpoint": "/scrape"},
            "image": {
                "description": "Generate images (Flux, Gemini, Ghibli)",
                "endpoint": "/image",
                "models": ["flux-schnell", "flux-1.1-pro", "vertex/gemini-3-pro-image-preview", "neta/ghibli-style"],
            },
            "video": {
                "description": "Generate videos (Google Veo)",
                "endpoint": "/video",
                "models": ["google/veo-3.1", "google/veo-3.1-fast", "mm/i2v"],
            },
            "social": {
                "description": "Fetch social media profiles",
                "endpoint": "/social",
                "platforms": ["twitter", "instagram", "linkedin", "tiktok"],
            },
            "tts": {"description": "Text to speech (ElevenLabs)", "endpoint": "/tts"},
            "stt": {"description": "Speech to text (Whisper)", "endpoint": "/stt"},
            "email": {"description": "Send emails", "endpoint": "/email"},
            "think": {"description": "Deep reasoning via Arcee Trinity 400B", "endpoint": "/think"},
            "slides": {"description": "Generate pitch decks (Gamma)", "endpoint": "/slides"},
            "landing": {"description": "Generate landing pages (Stitch)", "endpoint": "/landing"},
            "blog": {"description": "Create blog posts in GHL", "endpoint": "/blog"},
            "social_post": {"description": "Create/edit social posts in GHL", "endpoint": "/social-post"},
        },
    }
