#!/usr/bin/env python3
"""Brevo webhook receiver.

This Flask application receives Brevo event webhooks (delivered, opened, replied, bounced, etc.)
and updates the `leads.db` SQLite database accordingly.

Prerequisites:
  pip install flask

Brevo documentation: https://developers.brevo.com/docs/email-webhook

Configure Brevo to POST to https://your-domain.com/brevo/webhook.
The app can be run behind Nginx (or any WSGI server).  For a quick test:
  export FLASK_APP=brevo_webhook.py
  flask run --host 0.0.0.0
"""

import os
import json
import sqlite3
import logging

from datetime import datetime
from flask import Flask, request, Response

app = Flask(__name__)

# ---------------------------------------------------------------------------
# Configuration                                                      
# ---------------------------------------------------------------------------
DB_PATH = os.environ.get("LEADS_DB", "/home/ubuntu/leads.db")
# Brevo sends event data in JSON payload. Example structure:
# {"event":{"type":"delivered"},"email":"customer@example.com",...}
# ---------------------------------------------------------------------------

# Setup logging to STDERR for container / systemd until we integrate file.
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")

# Map Brevo event names to database fields/behaviour
EVENT_TO_ACTION = {
    "delivered": {"field": "delivered_at", "info": "Email delivered."},
    "opened": {"field": "opened_at", "info": "Email opened."},
    "replied": {"field": "replied_at", "info": "Replied by user."},
    "bounce": {"field": "bounced_at", "info": "Bounced."},
    "blocked": {"field": "blocked_at", "info": "Blocked."},
    "spam": {"field": "spam_reported_at", "info": "Spam reported."},
}


def db_update(event_type: str, email: str, timestamp: str = None):
    """Update leads table for the given event and email.
    If the lead exists, set the timestamp on the appropriate field.
    Also updates overall status if applicable.
    """
    con = sqlite3.connect(DB_PATH)
    cur = con.cursor()

    # Ensure timestamp
    if not timestamp:
        timestamp = datetime.utcnow().isoformat()

    action = EVENT_TO_ACTION.get(event_type)
    if not action:
        # Ignore unknown events
        logging.warning(f"Unknown Brevo event: {event_type}")
        return

    field = action["field"]
    # If field does not exist, ignore.
    try:
        cur.execute(
            f"UPDATE leads SET {field} = ?, status = COALESCE(status, 'open') WHERE email = ?",
            (timestamp, email),
        )
        if cur.rowcount == 0:
            logging.info(f"No lead found for email {email} on event {event_type}")
        con.commit()
        logging.info(f"Updated {email}: set {field} = {timestamp}")
    except sqlite3.Error as e:
        logging.error(f"DB error on {email} for event {event_type}: {e}")
    finally:
        con.close()


@app.route("/brevo/webhook", methods=["POST"])
def brevo_webhook():
    if not request.is_json:
        logging.warning("Webhook received non-JSON payload")
        return Response("Bad request", status=400)
    data = request.get_json(force=True)
    # Brevo sends a JSON object; extract event and email.
    try:
        event_type = data["event"]["type"]
        email = data.get("email")
    except (KeyError, TypeError) as exc:
        logging.error(f"Malformed webhook payload: {exc}")
        return Response("Bad request", status=400)
    if not email:
        logging.error("Webhook payload missing 'email'")
        return Response("Bad request", status=400)

    db_update(event_type, email)
    return Response("OK", status=200)


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
