package models

import (
	"time"

	"github.com/google/uuid"
)

// ── Enum consts ───────────────────────────────────────────────────────────────

const (
	// NotificationKind
	KindRenderCompleted   = "RenderCompleted"
	KindRenderFailed      = "RenderFailed"
	KindRenderProgress    = "RenderProgress"
	KindPlanExpiring      = "PlanExpiring"
	KindPlanExpired       = "PlanExpired"
	KindPaymentSuccess    = "PaymentSuccess"
	KindPaymentFailed     = "PaymentFailed"
	KindStorageWarning    = "StorageWarning"
	KindStorageFull       = "StorageFull"
	KindExportExpiring    = "ExportExpiring"
	KindExportDeleted     = "ExportDeleted"
	KindGiftEarned        = "GiftEarned"
	KindQuestCompleted    = "QuestCompleted"
	KindLevelUp           = "LevelUp"
	KindAccountSecurity   = "AccountSecurity"
	KindSystemAnnouncement = "SystemAnnouncement"
	KindTenantInvite      = "TenantInvite"
	KindMarketing         = "Marketing"
	KindOther             = "Other"

	// Priority
	PriorityLow    = "Low"
	PriorityNormal = "Normal"
	PriorityHigh   = "High"
	PriorityUrgent = "Urgent"

	// DeliveryChannel
	ChannelInApp    = "InApp"
	ChannelPush     = "Push"
	ChannelEmail    = "Email"
	ChannelSMS      = "SMS"
	ChannelTelegram = "Telegram"
	ChannelWebhook  = "Webhook"

	// DeliveryStatus
	StatusPending    = "Pending"
	StatusSent       = "Sent"
	StatusDelivered  = "Delivered"
	StatusFailed     = "Failed"
	StatusBounced    = "Bounced"
	StatusSuppressed = "Suppressed"
)

// ── Domain entities ──────────────────────────────────────────────────────────

type Notification struct {
	ID               uuid.UUID  `json:"id"`
	TenantID         uuid.UUID  `json:"tenant_id"`
	UserID           uuid.UUID  `json:"user_id"`
	NotificationType string     `json:"notification_type"`
	Priority         string     `json:"priority"`
	Title            string     `json:"title"`
	Message          string     `json:"message"`
	Label            *string    `json:"label,omitempty"`
	Signature        *string    `json:"signature,omitempty"`
	Icon             *string    `json:"icon,omitempty"`
	Image            *string    `json:"image,omitempty"`
	AnimationDemo    *string    `json:"animation_demo,omitempty"`
	Design           *string    `json:"design,omitempty"`
	ActionURL        *string    `json:"action_url,omitempty"`
	ActionText       *string    `json:"action_text,omitempty"`
	RenderJobID      *uuid.UUID `json:"render_job_id,omitempty"`
	ExportID         *uuid.UUID `json:"export_id,omitempty"`
	PaymentID        *uuid.UUID `json:"payment_id,omitempty"`
	GiftID           *uuid.UUID `json:"gift_id,omitempty"`
	EarnedGiftID     *uuid.UUID `json:"earned_gift_id,omitempty"`
	IsEmergency      bool       `json:"is_emergency"`
	Seen             bool       `json:"seen"`
	SeenAt           *time.Time `json:"seen_at,omitempty"`
	Clicked          bool       `json:"clicked"`
	ClickedAt        *time.Time `json:"clicked_at,omitempty"`
	GiftUsed         bool       `json:"gift_used"`
	ExpireDate       *time.Time `json:"expire_date,omitempty"`
	CreatedAt        time.Time  `json:"created_at"`
	UpdatedAt        time.Time  `json:"updated_at"`
}

type NotificationPreference struct {
	ID               uuid.UUID `json:"id"`
	UserID           uuid.UUID `json:"user_id"`
	NotificationType string    `json:"notification_type"`
	Channel          string    `json:"channel"`
	Enabled          bool      `json:"enabled"`
	UpdatedAt        time.Time `json:"updated_at"`
}

type NotificationTemplate struct {
	ID              uuid.UUID  `json:"id"`
	TenantID        *uuid.UUID `json:"tenant_id,omitempty"`
	Code            string     `json:"code"`
	Channel         string     `json:"channel"`
	Locale          string     `json:"locale"`
	Subject         *string    `json:"subject,omitempty"`
	BodyText        *string    `json:"body_text,omitempty"`
	BodyHTML        *string    `json:"body_html,omitempty"`
	PushTitle       *string    `json:"push_title,omitempty"`
	PushBody        *string    `json:"push_body,omitempty"`
	PushIcon        *string    `json:"push_icon,omitempty"`
	VariablesSchema *string    `json:"variables_schema,omitempty"`
	IsActive        bool       `json:"is_active"`
	CreatedAt       time.Time  `json:"created_at"`
	UpdatedAt       time.Time  `json:"updated_at"`
}

type NotificationDelivery struct {
	ID                uuid.UUID  `json:"id"`
	TenantID          uuid.UUID  `json:"tenant_id"`
	UserID            uuid.UUID  `json:"user_id"`
	NotificationID    *uuid.UUID `json:"notification_id,omitempty"`
	Channel           string     `json:"channel"`
	Recipient         string     `json:"recipient"`
	Subject           *string    `json:"subject,omitempty"`
	Provider          *string    `json:"provider,omitempty"`
	ProviderMessageID *string    `json:"provider_message_id,omitempty"`
	Status            string     `json:"status"`
	ErrorMessage      *string    `json:"error_message,omitempty"`
	Attempt           int        `json:"attempt"`
	MaxAttempts       int        `json:"max_attempts"`
	SentAt            *time.Time `json:"sent_at,omitempty"`
	DeliveredAt       *time.Time `json:"delivered_at,omitempty"`
	FailedAt          *time.Time `json:"failed_at,omitempty"`
	CreatedAt         time.Time  `json:"created_at"`
}

// ── Request / Response types ─────────────────────────────────────────────────

type PagedResponse[T any] struct {
	Data []T            `json:"data"`
	Meta PaginationMeta `json:"meta"`
}

type PaginationMeta struct {
	Page     int   `json:"page"`
	PageSize int   `json:"page_size"`
	Total    int64 `json:"total"`
	HasMore  bool  `json:"has_more"`
}

type CreateNotificationRequest struct {
	UserID           uuid.UUID  `json:"user_id"            binding:"required"`
	TenantID         uuid.UUID  `json:"tenant_id"          binding:"required"`
	NotificationType string     `json:"notification_type"  binding:"required"`
	Priority         *string    `json:"priority"`
	Title            string     `json:"title"              binding:"required"`
	Message          string     `json:"message"            binding:"required"`
	Label            *string    `json:"label"`
	Icon             *string    `json:"icon"`
	Image            *string    `json:"image"`
	ActionURL        *string    `json:"action_url"`
	ActionText       *string    `json:"action_text"`
	RenderJobID      *uuid.UUID `json:"render_job_id"`
	ExportID         *uuid.UUID `json:"export_id"`
	PaymentID        *uuid.UUID `json:"payment_id"`
	GiftID           *uuid.UUID `json:"gift_id"`
	EarnedGiftID     *uuid.UUID `json:"earned_gift_id"`
	IsEmergency      bool       `json:"is_emergency"`
	ExpireDate       *time.Time `json:"expire_date"`
	Channels         []string   `json:"channels"` // which delivery channels to trigger
}

type UpdatePreferenceRequest struct {
	NotificationType string `json:"notification_type" binding:"required"`
	Channel          string `json:"channel"           binding:"required"`
	Enabled          bool   `json:"enabled"`
}

type TemplateUpsertRequest struct {
	Code    string     `json:"code"    binding:"required"`
	Channel string     `json:"channel" binding:"required"`
	Locale  string     `json:"locale"  binding:"required"`
	Subject *string    `json:"subject"`
	BodyText *string   `json:"body_text"`
	BodyHTML *string   `json:"body_html"`
	PushTitle *string  `json:"push_title"`
	PushBody *string   `json:"push_body"`
	PushIcon *string   `json:"push_icon"`
	IsActive *bool     `json:"is_active"`
}

type APIError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

// ── Channel provider config (SMS / Email) ────────────────────────────────────

type ChannelConfig struct {
	TenantID  uuid.UUID      `json:"tenant_id"`
	Channel   string         `json:"channel"` // 'sms' | 'email'
	Settings  map[string]any `json:"settings"`
	Enabled   bool           `json:"enabled"`
	UpdatedAt time.Time      `json:"updated_at"`
}

type UpsertChannelConfigRequest struct {
	Settings map[string]any `json:"settings"`
	Enabled  *bool          `json:"enabled"`
}

type SendSMSRequest struct {
	To      string `json:"to"      binding:"required"`
	Message string `json:"message" binding:"required"`
}

type SendEmailRequest struct {
	To           string            `json:"to" binding:"required"`
	Subject      string            `json:"subject"`
	BodyHTML     string            `json:"body_html"`
	BodyText     string            `json:"body_text"`
	TemplateCode string            `json:"template_code"`
	Locale       string            `json:"locale"`
	Variables    map[string]string `json:"variables"`
}

// ── Marketing campaigns ──────────────────────────────────────────────────────

type Campaign struct {
	ID           uuid.UUID  `json:"id"`
	TenantID     uuid.UUID  `json:"tenant_id"`
	Name         string     `json:"name"`
	Channel      string     `json:"channel"`  // sms | email
	Audience     string     `json:"audience"` // all | verified | with_plan
	Subject      *string    `json:"subject,omitempty"`
	BodyHTML     *string    `json:"body_html,omitempty"`
	TemplateCode *string    `json:"template_code,omitempty"`
	Status       string     `json:"status"`
	TotalCount   int        `json:"total_count"`
	SentCount    int        `json:"sent_count"`
	FailedCount  int        `json:"failed_count"`
	CreatedAt    time.Time  `json:"created_at"`
	SentAt       *time.Time `json:"sent_at,omitempty"`
}

type CreateCampaignRequest struct {
	Name         string  `json:"name"    binding:"required"`
	Channel      string  `json:"channel" binding:"required"` // sms | email
	Audience     string  `json:"audience"`
	Subject      *string `json:"subject"`
	BodyHTML     *string `json:"body_html"`
	TemplateCode *string `json:"template_code"`
}
