using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace LittleShop.Models;

public enum MessageDirection
{
    AdminToCustomer = 0,
    CustomerToAdmin = 1
}

public enum MessageStatus
{
    Pending = 0,     // Message created, waiting to be sent
    Sent = 1,        // Message delivered to customer
    Delivered = 2,   // Message acknowledged by bot/platform
    Read = 3,        // Customer has read the message
    Failed = 4       // Delivery failed
}

public enum MessageType
{
    OrderUpdate = 0,     // Status update about an order
    PaymentReminder = 1, // Payment reminder
    ShippingInfo = 2,    // Tracking/shipping information
    CustomerService = 3, // General customer service
    Marketing = 4,       // Marketing/promotional (requires consent)
    SystemAlert = 5      // System-generated alerts
}

public class CustomerMessage
{
    [Key]
    public Guid Id { get; set; }
    
    // Relationships
    [Required]
    public Guid CustomerId { get; set; }
    
    public Guid? OrderId { get; set; } // Optional - message may not be about specific order
    
    public Guid? AdminUserId { get; set; } // Which admin sent the message (null for system messages or unidentified admins)
    
    // Message Details
    [Required]
    public MessageDirection Direction { get; set; }
    
    [Required]
    public MessageType Type { get; set; }
    
    [Required]
    [StringLength(100)]
    public string Subject { get; set; } = string.Empty;
    
    [Required]
    [StringLength(4000)] // Telegram message limit is ~4096 characters
    public string Content { get; set; } = string.Empty;
    
    public MessageStatus Status { get; set; } = MessageStatus.Pending;
    
    // Delivery Information
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
    
    public DateTime? SentAt { get; set; }
    
    public DateTime? DeliveredAt { get; set; }
    
    public DateTime? ReadAt { get; set; }
    
    public DateTime? FailedAt { get; set; }
    
    [StringLength(500)]
    public string? FailureReason { get; set; }
    
    public int RetryCount { get; set; } = 0;
    
    public DateTime? NextRetryAt { get; set; }
    
    // Message Threading (for conversations)
    public Guid? ParentMessageId { get; set; } // Reply to another message
    
    public Guid? ThreadId { get; set; } // Conversation thread identifier
    
    // Platform-specific Information
    [StringLength(100)]
    public string Platform { get; set; } = "Telegram"; // Telegram, Email, SMS, etc.
    
    [StringLength(200)]
    public string? PlatformMessageId { get; set; } // Telegram message ID, email message ID, etc.
    
    // Priority and Scheduling
    public int Priority { get; set; } = 5; // 1-10, 1 = highest priority
    
    public DateTime? ScheduledFor { get; set; } // For scheduled messages
    
    public DateTime? ExpiresAt { get; set; } // Message expires if not delivered
    
    // Customer Preferences
    public bool RequiresResponse { get; set; } = false;
    
    public bool IsUrgent { get; set; } = false;
    
    public bool IsMarketing { get; set; } = false;
    
    // Auto-generated flags
    public bool IsAutoGenerated { get; set; } = false;
    
    [StringLength(100)]
    public string? AutoGenerationTrigger { get; set; } // e.g., "OrderStatusChanged", "PaymentOverdue"
    
    // Data retention
    public bool IsArchived { get; set; } = false;
    
    public DateTime? ArchivedAt { get; set; }
    
    // Navigation properties
    public virtual Customer Customer { get; set; } = null!;
    public virtual Order? Order { get; set; }
    public virtual User? AdminUser { get; set; }
    public virtual CustomerMessage? ParentMessage { get; set; }
    public virtual ICollection<CustomerMessage> Replies { get; set; } = new List<CustomerMessage>();
    
    // Helper methods
    public bool CanRetry()
    {
        return Status == MessageStatus.Failed && 
               RetryCount < 3 && 
               (NextRetryAt == null || DateTime.UtcNow >= NextRetryAt) &&
               (ExpiresAt == null || DateTime.UtcNow < ExpiresAt);
    }
    
    public void MarkAsSent()
    {
        Status = MessageStatus.Sent;
        SentAt = DateTime.UtcNow;
    }
    
    public void MarkAsDelivered(string? platformMessageId = null)
    {
        Status = MessageStatus.Delivered;
        DeliveredAt = DateTime.UtcNow;
        if (!string.IsNullOrEmpty(platformMessageId))
        {
            PlatformMessageId = platformMessageId;
        }
    }
    
    public void MarkAsRead()
    {
        Status = MessageStatus.Read;
        ReadAt = DateTime.UtcNow;
    }
    
    public void MarkAsFailed(string reason)
    {
        Status = MessageStatus.Failed;
        FailedAt = DateTime.UtcNow;
        FailureReason = reason;
        RetryCount++;
        
        // Exponential backoff for retries
        if (RetryCount <= 3)
        {
            var delayMinutes = Math.Pow(2, RetryCount) * 5; // 10, 20, 40 minutes
            NextRetryAt = DateTime.UtcNow.AddMinutes(delayMinutes);
        }
    }
    
    public string GetDisplayTitle()
    {
        var prefix = Direction == MessageDirection.AdminToCustomer ? "→" : "←";
        var typeStr = Type switch
        {
            MessageType.OrderUpdate => "Order Update",
            MessageType.PaymentReminder => "Payment",
            MessageType.ShippingInfo => "Shipping",
            MessageType.CustomerService => "Support",
            MessageType.Marketing => "Marketing",
            MessageType.SystemAlert => "System",
            _ => "Message"
        };
        
        return $"{prefix} {typeStr}: {Subject}";
    }
}