import json
import logging

from django.http import JsonResponse, HttpResponse
from django.conf import settings

from .services import FacebookService
from .models import FacebookPageAssistant, EventType, FacebookEvent

import requests
from pxy_openai.assistants import OpenAIAssistant as OpenAIService


# Configure logging
logger = logging.getLogger(__name__)

PAGE_ACCESS_TOKEN = settings.PAGE_ACCESS_TOKEN


def verify_webhook_token(mode, token, challenge, verify_token):
    """
    Verifies the webhook token and mode.
    """
    if mode == "subscribe" and token == verify_token:
        logger.info("Webhook verified successfully.")
        return HttpResponse(challenge, status=200)
    else:
        logger.warning(f"Webhook verification failed. Mode: {mode}, Token: {token}")
        return HttpResponse("Forbidden", status=403)


def parse_webhook_payload(payload):
    """
    Parses the webhook payload and extracts relevant data.
    """
    try:
        entry = payload.get("entry", [{}])[0]
        changes = entry.get("changes", [{}])[0]
        value = changes.get("value", {})
        return value
    except Exception as e:
        logger.error(f"Error parsing payload: {e}")
        raise


def handle_comment_event(page_id, sender_id, data):
    """
    Handles incoming comment events: 
    1) Persiste el evento en la BD.
    2) Responde al comentario vía FacebookService.
    """
    # Si el comentario viene de la propia página, lo saltamos
    if sender_id == page_id:
        logger.info(f"Skipping self-generated comment. Sender ID: {sender_id}, Page ID: {page_id}")
        return JsonResponse({"status": "skipped"}, status=200)

    comment_id = data.get("comment_id")
    original_message = data.get("message")

    # 1) Registrar en la base de datos
    try:
        page = FacebookPageAssistant.objects.get(page_id=page_id)
        et = EventType.objects.get(code="comment")
        FacebookEvent.objects.create(
            page=page,
            event_type=et,
            sender_id=sender_id,
            object_id=comment_id,
            message=original_message
        )
    except Exception as e:
        logger.error(f"Error logging FB comment event: {e}")

    # 2) Responder al comentario via API de Facebook
    if comment_id and original_message:
        try:
            fb_service = FacebookService(PAGE_ACCESS_TOKEN)
            fb_service.reply_to_comment(page_id, comment_id, original_message)
            logger.info(f"Successfully replied to comment ID: {comment_id} with bot response: {original_message}")
        except Exception as e:
            logger.error(f"Error replying to comment via FacebookService: {e}")

    return JsonResponse({"status": "comment_handled"}, status=200)


def handle_share_event(page_id, data):
    """
    Handles incoming share events:
    1) Persiste el evento en la BD.
    2) Publica un comentario en la share vía FacebookService.
    """
    share_id = data.get("share_id")
    post_id  = data.get("post_id")
    original_message = data.get("message")
    share_link = data.get("link")

    logger.info(f"Post {post_id} was shared. Share ID: {share_id}, Link: {share_link}")

    # 1) Registrar en la base de datos
    try:
        page = FacebookPageAssistant.objects.get(page_id=page_id)
        et = EventType.objects.get(code="share")
        FacebookEvent.objects.create(
            page=page,
            event_type=et,
            object_id=share_id,
            message=original_message
        )
    except Exception as e:
        logger.error(f"Error logging FB share event: {e}")

    # 2) Comentar en la publicación compartida via API de Facebook
    try:
        fb_service = FacebookService(PAGE_ACCESS_TOKEN)
        fb_service.post_comment_on_share(page_id, post_id, original_message)
    except Exception as e:
        logger.error(f"Error posting comment on share via FacebookService: {e}")

    return JsonResponse({"status": "share_logged"}, status=200)


def handle_message_event(page_id: str, sender_psid: str, message: dict):
    """
    Handles incoming Messenger messages:
    1) Log event to DB (like comments/shares)
    2) Generate AI reply with your configured OpenAI assistant for this page
    3) Send the sreply via the Send API (using the page's access token)
    """
    try:
        # 0) ignore echoes to prevent loops
        if not message or message.get("is_echo"):
            return JsonResponse({"status": "ignored"}, status=200)

        text = (message.get("text") or "").strip()
        mid  = message.get("mid") or ""

        # 1) Persist event to DB (EventType 'message'; create if missing)
        try:
            page = FacebookPageAssistant.objects.get(page_id=page_id)
            et, _ = EventType.objects.get_or_create(code="message", defaults={"label": "Message"})
            FacebookEvent.objects.create(
                page=page,
                event_type=et,
                sender_id=sender_psid,
                object_id=mid,
                message=text
            )
        except Exception as e:
            logger.error(f"Error logging Messenger event: {e}")

        # 2) Build prompt and get AI reply from the page's configured assistant
        try:
            page_assistant = FacebookPageAssistant.objects.get(page_id=page_id).assistant
            prompt = text if text else "Say hello and ask how you can help."
            openai_service = OpenAIService(name=page_assistant.name)
            bot_reply = openai_service.handle_message(prompt)
        except Exception as e:
            logger.exception(f"AI reply failed; falling back. Reason: {e}")
            bot_reply = "Gracias por tu mensaje 🙌. ¿En qué puedo ayudarte?"

        # 3) Send the reply via Send API
        try:
            fb_service = FacebookService(PAGE_ACCESS_TOKEN)  # reuse your token flow
            page_token = fb_service._get_page_access_token(page_id) or PAGE_ACCESS_TOKEN

            url = "https://graph.facebook.com/v22.0/me/messages"
            payload = {
                "recipient": {"id": sender_psid},
                "messaging_type": "RESPONSE",
                "message": {"text": bot_reply},
            }
            resp = requests.post(url, params={"access_token": page_token}, json=payload, timeout=5)
            resp.raise_for_status()
            logger.info(f"Sent Messenger reply to psid={sender_psid}")
            return JsonResponse({"status": "message_replied"}, status=200)
        except requests.RequestException as e:
            logger.exception(f"Send API failed: {e}")
            return JsonResponse({"status": "send_failed"}, status=200)

    except Exception as e:
        logger.exception(f"handle_message_event crashed: {e}")
        return JsonResponse({"status": "error", "detail": str(e)}, status=200)
    
def handle_postback_event(page_id: str, sender_psid: str, postback: dict):
    """
    Minimal stub so views.py import succeeds.
    Logs and immediately 200s. We'll upgrade it later to AI-reply if you want.
    """
    try:
        payload = (postback or {}).get("payload")
        title = (postback or {}).get("title")
        logger.info(f"[HANDLER] postback page={page_id} psid={sender_psid} payload={payload!r} title={title!r}")
        return JsonResponse({"status": "postback_handled", "payload": payload}, status=200)
    except Exception as e:
        logger.exception(f"postback handler failed: {e}")
        return JsonResponse({"status": "error", "detail": str(e)}, status=200)

