"""Helpdesk webhook endpoints — incoming and outgoing.

Incoming webhook
----------------
``POST /helpdesk/webhooks/incoming/<uuid:endpoint_id>/``
Accepts an authenticated or HMAC-signed payload and creates a ticket in
the target queue.

Outgoing webhooks
-----------------
Outgoing webhooks are dispatched via the platform ``automation`` app's
``WebhookEndpoint`` + ``deliver_webhook`` infrastructure.  Helpdesk
subscribers in ``events.py`` fan out to relevant endpoints on ticket
events (created, updated, status_changed, reply_added, assigned, escalated,
solved, sla_breached).

Endpoints
---------
``GET/POST /helpdesk/webhooks/endpoints/``
    List or create outgoing webhook endpoints.
``GET/PUT/PATCH/DELETE /helpdesk/webhooks/endpoints/<id>/``
    Detail, update, or delete an outgoing webhook endpoint.
"""

from __future__ import annotations

import hashlib
import hmac
import json
import structlog

_log = structlog.get_logger("simorgh.helpdesk.webhooks")


def verify_hmac_signature(secret: str, body: bytes, signature: str) -> bool:
    """Verify HMAC-SHA256 signature on an incoming webhook payload."""
    if not signature.startswith("sha256="):
        return False
    expected_hex = signature[7:]
    computed = hmac.new(
        secret.encode("utf-8"), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(computed, expected_hex)


def dispatch_outgoing_webhooks(
    *,
    tenant_id: int,
    event_name: str,
    payload: dict,
) -> int:
    """Deliver an event payload to all active outgoing webhook endpoints for the tenant.

    Returns the number of endpoints dispatched to.
    """
    from simorgh.apps.automation.models import WebhookEndpoint
    from simorgh.apps.automation.webhook_service import deliver_webhook

    endpoints = WebhookEndpoint.objects.filter(
        tenant_id=tenant_id,
        is_active=True,
    )
    count = 0
    for endpoint in endpoints:
        try:
            deliver_webhook(endpoint, event_name, payload)
            count += 1
        except Exception:
            _log.warning(
                "helpdesk.webhooks.dispatch_failed",
                endpoint_id=endpoint.pk,
                event=event_name,
                exc_info=True,
            )
    return count


def process_incoming_ticket(
    *,
    tenant_id: int,
    org_node_id: int,
    queue_id: int | None,
    subject: str,
    description: str = "",
    priority: str = "normal",
    channel: str = "api",
    requester_email: str = "",
    requester_name: str = "",
    custom_fields: dict | None = None,
    tag_ids: list[int] | None = None,
    actor_id: int | None = None,
) -> dict:
    """Create a ticket from an incoming webhook payload.

    Returns a dict with ``ticket_id``, ``reference_number``, and ``public_id``.
    """
    from simorgh.apps.helpdesk.models import Queue
    from simorgh.apps.helpdesk.services import TicketService

    if not queue_id:
        default_q = (
            Queue.objects.filter(tenant_id=tenant_id, is_default=True, is_active=True).first()
            or Queue.objects.filter(tenant_id=tenant_id, is_active=True).order_by("sort_order", "id").first()
        )
        if default_q is None:
            raise ValueError("No active queue found for this tenant.")
        queue_id = default_q.pk

    ticket = TicketService.create(
        tenant_id=tenant_id,
        organization_node_id=org_node_id,
        queue_id=queue_id,
        subject=subject,
        description=description,
        priority=priority,
        channel=channel,
        requester_email=requester_email,
        requester_name=requester_name,
        custom_fields=custom_fields or {},
        tag_ids=tag_ids or [],
        created_by_id=actor_id,
    )

    return {
        "ticket_id": ticket.pk,
        "reference_number": ticket.reference_number,
        "public_id": str(ticket.public_id),
    }
