package domain

import (
	"encoding/json"
	"time"
)

type NotificationType string
type NotificationRecieverSide string
type NotificationDeliveryScheme string
type NotificationLevel string
type NotificationErrorSeverity string
type NotificationDeliveryStatus string
type DeliveryChannel string
type ReceiverType string

const (
	ReceiverTypeUser       ReceiverType = "user"
	ReceiverTypeTeamMember ReceiverType = "team_member"
)

const (
	NOTIFICATION_TYPE_KNOWLEDGE_LEVEL_UPDATE NotificationType = "knowledge_level_update"
	NOTIFICATION_TYPE_PAYMENT_VERIFIED       NotificationType = "payment_verified"
	NOTIFICATION_TYPE_SUBSCRIPTION_ACTIVATED NotificationType = "subscription_activated"
	NOTIFICATION_TYPE_COURSE_CREATED         NotificationType = "course_created"
	NOTIFICATION_TYPE_SUB_COURSE_CREATED     NotificationType = "sub_course_created"
	NOTIFICATION_TYPE_VIDEO_ADDED            NotificationType = "video_added"
	NOTIFICATION_TYPE_ISSUE_STATUS_UPDATED   NotificationType = "issue_status_updated"
	NOTIFICATION_TYPE_ISSUE_CREATED          NotificationType = "issue_created"
	NOTIFICATION_TYPE_ADMIN_CREATED          NotificationType = "admin_created"
	NOTIFICATION_TYPE_TEAM_MEMBER_CREATED    NotificationType = "team_member_created"
	NOTIFICATION_TYPE_USER_DELETED           NotificationType = "user_deleted"

	NotificationRecieverSideAdmin         NotificationRecieverSide = "admin"
	NotificationRecieverSideCustomer      NotificationRecieverSide = "customer"
	NotificationRecieverSideCashier       NotificationRecieverSide = "cashier"
	NotificationRecieverSideBranchManager NotificationRecieverSide = "branch_manager"
	NotificationRecieverSideTeamMember    NotificationRecieverSide = "team_member"

	NotificationDeliverySchemeBulk   NotificationDeliveryScheme = "bulk"
	NotificationDeliverySchemeSingle NotificationDeliveryScheme = "single"

	NotificationLevelInfo    NotificationLevel = "info"
	NotificationLevelError   NotificationLevel = "error"
	NotificationLevelWarning NotificationLevel = "warning"
	NotificationLevelSuccess NotificationLevel = "success"

	NotificationErrorSeverityLow      NotificationErrorSeverity = "low"
	NotificationErrorSeverityMedium   NotificationErrorSeverity = "medium"
	NotificationErrorSeverityHigh     NotificationErrorSeverity = "high"
	NotificationErrorSeverityCritical NotificationErrorSeverity = "critical"
	NotificationErrorSeverityFatal    NotificationErrorSeverity = "fatal"

	DeliveryStatusPending NotificationDeliveryStatus = "pending"
	DeliveryStatusSent    NotificationDeliveryStatus = "sent"
	DeliveryStatusFailed  NotificationDeliveryStatus = "failed"

	DeliveryChannelEmail DeliveryChannel = "email"
	DeliveryChannelSMS   DeliveryChannel = "sms"
	DeliveryChannelPush  DeliveryChannel = "push"
	DeliveryChannelInApp DeliveryChannel = "in_app"
)

type NotificationPayload struct {
	Headline string   `json:"headline"`
	Message  string   `json:"message"`
	Tags     []string `json:"tags"`
}

type Notification struct {
	ID              string                     `json:"id"`
	RecipientID     int64                      `json:"recipient_id"`
	ReceiverType    ReceiverType               `json:"receiver_type"`
	Type            NotificationType           `json:"type"`
	Level           NotificationLevel          `json:"level"`
	ErrorSeverity   NotificationErrorSeverity  `json:"error_severity"`
	Reciever        NotificationRecieverSide   `json:"reciever"`
	IsRead          bool                       `json:"is_read"`
	DeliveryStatus  NotificationDeliveryStatus `json:"delivery_status,omitempty"`
	DeliveryChannel DeliveryChannel            `json:"delivery_channel,omitempty"`
	Payload         NotificationPayload        `json:"payload"`
	Priority        int                        `json:"priority,omitempty"`
	Version         int                        `json:"-"`
	Timestamp       time.Time                  `json:"timestamp"`
	Expires         time.Time                  `json:"expires"`
	Image           string                     `json:"image"`
	Metadata        json.RawMessage            `json:"metadata,omitempty"`
}
type CreateNotification struct {
	RecipientID     int64                      `json:"recipient_id"`
	ReceiverType    ReceiverType               `json:"receiver_type"`
	Type            NotificationType           `json:"type"`
	Level           NotificationLevel          `json:"level"`
	ErrorSeverity   *NotificationErrorSeverity `json:"error_severity"`
	Reciever        NotificationRecieverSide   `json:"reciever"`
	IsRead          bool                       `json:"is_read"`
	DeliveryStatus  NotificationDeliveryStatus `json:"delivery_status,omitempty"`
	DeliveryChannel DeliveryChannel            `json:"delivery_channel,omitempty"`
	Payload         NotificationPayload        `json:"payload"`
	Priority        int                        `json:"priority,omitempty"`
	Expires         time.Time                  `json:"expires"`
	Image           string                     `json:"image,omitempty"`
	Metadata        json.RawMessage            `json:"metadata,omitempty"`
}

func (n *Notification) ToJSON() ([]byte, error) {
	return json.Marshal(n)
}

func FromJSON(data []byte) (*Notification, error) {
	var n Notification
	err := json.Unmarshal(data, &n)
	if err != nil {
		return nil, err
	}
	return &n, nil
}

func ReceiverFromRole(role Role) NotificationRecieverSide {
	switch role {
	case RoleAdmin:
		return NotificationRecieverSideAdmin
	case RoleSuperAdmin:
		return NotificationRecieverSideAdmin
	case RoleStudent:
		return NotificationRecieverSideCustomer
	case RoleInstructor:
		return NotificationRecieverSideCustomer
	default:
		return ""
	}
}

func ReceiverTypeFromReciever(reciever NotificationRecieverSide) ReceiverType {
	switch reciever {
	case NotificationRecieverSideTeamMember:
		return ReceiverTypeTeamMember
	default:
		return ReceiverTypeUser
	}
}
