"""Helpdesk AI bounded context — models.

Design
------
AITicketSuggestion
    AI-generated recommendation for handling a ticket. Covers priority changes,
    category suggestions, tag recommendations, and draft replies.

    Status lifecycle: PENDING → APPROVED / REJECTED.

    ``suggestion_type`` identifies what the AI is recommending:
    - priority: suggest a priority level
    - category: suggest a category
    - tags: suggest tags to apply
    - reply_draft: suggest a reply body for the agent
    - routing: suggest a queue/agent assignment

AIActionLog
    Immutable audit trail entry recording that an AI action was executed
    on a ticket. Written every time an AI suggestion is approved and applied,
    or whenever an automated AI action fires.

    ``action_type`` classifies what was done (assign, change_priority,
    add_tag, send_reply, etc.). ``payload_before`` and ``payload_after``
    capture snapshots so the audit is replayable.

Soft-delete is supported so stale/rejected suggestions can be hidden
without destroying the audit trail.
"""

from __future__ import annotations

from typing import ClassVar

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from simorgh.core.db.scoped import ScopedSoftDeleteManager
from simorgh.core.models import SoftDeleteModel, TenantScopedModel, TimeStampedModel, UUIDModel


# ---------------------------------------------------------------------------
# Choices
# ---------------------------------------------------------------------------

class AISuggestionStatus(models.TextChoices):
    PENDING = "pending", _("Pending")
    APPROVED = "approved", _("Approved")
    REJECTED = "rejected", _("Rejected")


class AISuggestionType(models.TextChoices):
    PRIORITY = "priority", _("Priority")
    CATEGORY = "category", _("Category")
    TAGS = "tags", _("Tags")
    REPLY_DRAFT = "reply_draft", _("Reply Draft")
    ROUTING = "routing", _("Routing")


class AIActionType(models.TextChoices):
    ASSIGN = "assign", _("Assign")
    CHANGE_PRIORITY = "change_priority", _("Change Priority")
    CHANGE_CATEGORY = "change_category", _("Change Category")
    ADD_TAG = "add_tag", _("Add Tag")
    REMOVE_TAG = "remove_tag", _("Remove Tag")
    SEND_REPLY = "send_reply", _("Send Reply")
    CHANGE_STATUS = "change_status", _("Change Status")
    ROUTE_TO_QUEUE = "route_to_queue", _("Route to Queue")


# ---------------------------------------------------------------------------
# AITicketSuggestion
# ---------------------------------------------------------------------------

class AITicketSuggestion(UUIDModel, TenantScopedModel, TimeStampedModel, SoftDeleteModel):
    """An AI-generated recommendation for a specific ticket.

    Multiple suggestions of different types may exist for a single ticket.
    Suggestions are created by an AI agent/external provider and reviewed
    by a human agent before application.
    """

    ticket = models.ForeignKey(
        "helpdesk.Ticket",
        on_delete=models.CASCADE,
        related_name="ai_suggestions",
        verbose_name=_("ticket"),
    )
    provider = models.CharField(
        _("provider"),
        max_length=100,
        default="default",
        help_text=_("AI provider identifier (e.g. 'openai', 'azure_ai')."),
    )
    suggestion_type = models.CharField(
        _("suggestion type"),
        max_length=50,
        choices=AISuggestionType.choices,
        default=AISuggestionType.TAGS,
        db_index=True,
    )
    status = models.CharField(
        _("status"),
        max_length=20,
        choices=AISuggestionStatus.choices,
        default=AISuggestionStatus.PENDING,
        db_index=True,
    )
    # The AI's recommended value — shape depends on suggestion_type:
    #   priority:  {"priority": "critical"}
    #   category:  {"category_id": 42, "category_name": "Billing"}
    #   tags:      {"tags": [{"id": 1, "name": "bug"}]}
    #   reply_draft: {"body": "..."}
    #   routing:   {"queue_id": 5, "assigned_to_id": 7}
    payload = models.JSONField(
        _("payload"),
        default=dict,
        blank=True,
        help_text=_("AI recommendation payload whose shape depends on suggestion_type."),
    )
    confidence_score = models.DecimalField(
        _("confidence score"),
        max_digits=5,
        decimal_places=4,
        null=True,
        blank=True,
        help_text=_("Confidence score in [0.0000, 1.0000]."),
    )
    rationale = models.TextField(
        _("rationale"),
        blank=True,
        default="",
        help_text=_("Natural language explanation of why the AI made this suggestion."),
    )
    model_version = models.CharField(
        _("model version"),
        max_length=64,
        blank=True,
        default="",
        help_text=_("Version/hash of the AI model that produced this suggestion."),
    )
    reviewed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="helpdesk_ai_reviews",
        verbose_name=_("reviewed by"),
    )
    reviewed_at = models.DateTimeField(_("reviewed at"), null=True, blank=True)
    review_comment = models.TextField(_("review comment"), blank=True, default="")

    objects: ClassVar[ScopedSoftDeleteManager] = ScopedSoftDeleteManager()

    class Meta:
        verbose_name = _("AI ticket suggestion")
        verbose_name_plural = _("AI ticket suggestions")
        ordering = ("-created_at",)
        indexes = [
            models.Index(
                fields=["ticket_id", "suggestion_type", "status"],
                name="hd_ai_sugg_tkt_type_status_idx",
            ),
            models.Index(
                fields=["tenant_id", "provider"],
                name="hd_ai_sugg_tenant_prov_idx",
            ),
            models.Index(
                fields=["tenant_id", "status"],
                name="hd_ai_sugg_tenant_status_idx",
            ),
        ]

    def __str__(self) -> str:
        return (
            f"AISuggestion({self.suggestion_type}) ticket={self.ticket_id} "
            f"[{self.status}] confidence={self.confidence_score}"
        )


# ---------------------------------------------------------------------------
# AIActionLog
# ---------------------------------------------------------------------------

class AIActionLog(UUIDModel, TenantScopedModel, TimeStampedModel):
    """Immutable audit trail entry for every AI action executed on a ticket.

    Written whenever a suggestion is approved-and-applied, or an autonomous
    AI action fires. The log is append-only — rows are never updated or
    soft-deleted.
    """

    ticket = models.ForeignKey(
        "helpdesk.Ticket",
        on_delete=models.CASCADE,
        related_name="ai_action_logs",
        verbose_name=_("ticket"),
    )
    suggestion = models.ForeignKey(
        AITicketSuggestion,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="action_logs",
        verbose_name=_("suggestion"),
        help_text=_("The approved suggestion that triggered this action, if any."),
    )
    action_type = models.CharField(
        _("action type"),
        max_length=50,
        choices=AIActionType.choices,
        db_index=True,
    )
    provider = models.CharField(
        _("provider"),
        max_length=100,
        blank=True,
        default="",
        help_text=_("AI provider that recommended this action."),
    )
    executed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="helpdesk_ai_actions_executed",
        verbose_name=_("executed by"),
        help_text=_("User who approved and triggered execution, or system if autonomous."),
    )
    payload_before = models.JSONField(
        _("payload before"),
        default=dict,
        blank=True,
        help_text=_("Snapshot of affected fields before the action."),
    )
    payload_after = models.JSONField(
        _("payload after"),
        default=dict,
        blank=True,
        help_text=_("Snapshot of affected fields after the action."),
    )
    execution_metadata = models.JSONField(
        _("execution metadata"),
        default=dict,
        blank=True,
        help_text=_("Provider-specific metadata (latency, tokens, model version, etc.)."),
    )
    error_message = models.TextField(_("error message"), blank=True, default="")

    class Meta:
        verbose_name = _("AI action log")
        verbose_name_plural = _("AI action logs")
        ordering = ("-created_at",)
        indexes = [
            models.Index(
                fields=["ticket_id", "action_type"],
                name="hd_ai_act_ticket_type_idx",
            ),
            models.Index(
                fields=["tenant_id", "created_at"],
                name="hd_ai_act_tenant_time_idx",
            ),
            models.Index(
                fields=["suggestion_id"],
                name="hd_ai_act_suggestion_idx",
            ),
        ]

    def __str__(self) -> str:
        ts = self.created_at.isoformat() if self.created_at else "?"
        return f"AIAction({self.action_type}) ticket={self.ticket_id} @ {ts}"

