"""
PX3Lab Follow-up Notifier - webhook Flask + worker de envio.

Roda ambos no mesmo processo: Flask no thread principal e worker em background.
"""
import logging
import os
import threading
from datetime import datetime, timezone

from flask import Flask, request, jsonify

import config
import db
import worker

# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
os.makedirs(os.path.dirname(config.LOG_PATH), exist_ok=True)
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    handlers=[
        logging.FileHandler(config.LOG_PATH),
        logging.StreamHandler(),
    ],
)
log = logging.getLogger("px3_followup.app")

# ---------------------------------------------------------------------------
# App
# ---------------------------------------------------------------------------
app = Flask(__name__)


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _extract_tags(payload: dict) -> list:
    tags = payload.get("tags") or []
    if isinstance(tags, str):
        tags = [tags]
    # normaliza para lowercase e strip
    return [str(t).strip().lower() for t in tags if t]


def _matching_tag(payload_tags: list) -> str | None:
    for t in payload_tags:
        if t in config.TAGS_CONFIG:
            return t
    return None


def _pick_name(payload: dict) -> str | None:
    contact_name = payload.get("contactName") or payload.get("full_name")
    if contact_name:
        return contact_name
    first = payload.get("firstName") or ""
    last = payload.get("lastName") or ""
    full = f"{first} {last}".strip()
    return full or None


# ---------------------------------------------------------------------------
# Rotas
# ---------------------------------------------------------------------------
@app.get("/health")
def health():
    return jsonify({"ok": True, "service": "px3_followup", "port": config.PORT})


@app.post("/webhook/linkia-followup")
def webhook_linkia():
    payload = request.get_json(silent=True) or {}
    event_type = payload.get("type") or payload.get("event")

    log.info("Webhook recebido: type=%s contact=%s", event_type, payload.get("id"))

    if event_type != "ContactTagUpdate":
        return jsonify({"ok": True, "ignored": "event_type_not_supported", "type": event_type}), 200

    tags = _extract_tags(payload)
    matched = _matching_tag(tags)
    if not matched:
        return jsonify({"ok": True, "ignored": "no_matching_tag", "tags": tags}), 200

    contact_id = payload.get("id") or payload.get("contactId")
    if not contact_id:
        return jsonify({"ok": False, "error": "missing_contact_id"}), 400

    contact_name = _pick_name(payload)
    contact_phone = payload.get("phone")
    assigned_user_id = payload.get("assignedTo")

    new_id = db.insert_event(
        contact_id=contact_id,
        contact_name=contact_name,
        contact_phone=contact_phone,
        assigned_user_id=assigned_user_id,
        tag=matched,
        tag_added_at=datetime.now(timezone.utc),
    )

    if new_id is None:
        log.info("Evento duplicado ignorado: contact=%s tag=%s", contact_id, matched)
        return jsonify({"ok": True, "duplicate": True, "contact_id": contact_id, "tag": matched}), 200

    log.info(
        "Novo evento salvo id=%s contact=%s tag=%s assigned=%s",
        new_id, contact_id, matched, assigned_user_id,
    )
    return jsonify({"ok": True, "event_id": new_id, "tag": matched}), 201


@app.get("/status")
def status():
    events = db.list_all_events()
    return jsonify({"ok": True, "events_tracked": len(events)})


# ---------------------------------------------------------------------------
# Boot
# ---------------------------------------------------------------------------
def start_worker_thread():
    t = threading.Thread(target=worker.run_forever, name="followup-worker", daemon=True)
    t.start()
    log.info("Worker thread iniciada")


if __name__ == "__main__":
    db.init_db()
    start_worker_thread()
    log.info("Servindo Flask em %s:%s", config.HOST, config.PORT)
    app.run(host=config.HOST, port=config.PORT, debug=False, use_reloader=False)
