// internal/models/notification.go
package models

import (
	"time"

	"gorm.io/gorm"
)

// Notification represents a notification for a user
type Notification struct {
	ID         uint           `gorm:"primaryKey" json:"id"`
	UserID     uint           `gorm:"not null" json:"user_id"`
	User       User           `gorm:"foreignKey:UserID" json:"user,omitempty"`
	Type       string         `gorm:"type:varchar(50);not null" json:"type"` // match_found, claim_approved, claim_rejected, item_expired, etc.
	Title      string         `gorm:"type:varchar(200);not null" json:"title"`
	Message    string         `gorm:"type:text;not null" json:"message"`
	EntityType string         `gorm:"type:varchar(50)" json:"entity_type"` // item, claim, match, etc.
	EntityID   *uint          `json:"entity_id"`
	IsRead     bool           `gorm:"default:false" json:"is_read"`
	ReadAt     *time.Time     `json:"read_at"`
	CreatedAt  time.Time      `json:"created_at"`
	UpdatedAt  time.Time      `json:"updated_at"`
	DeletedAt  gorm.DeletedAt `gorm:"index" json:"-"`
}

// TableName specifies the table name for Notification model
func (Notification) TableName() string {
	return "notifications"
}

// Notification type constants
const (
	NotificationMatchFound     = "match_found"
	NotificationClaimApproved  = "claim_approved"
	NotificationClaimRejected  = "claim_rejected"
	NotificationItemExpired    = "item_expired"
	NotificationNewClaim       = "new_claim"
	NotificationItemReturned   = "item_returned"
)

// MarkAsRead marks the notification as read
func (n *Notification) MarkAsRead() {
	n.IsRead = true
	now := time.Now()
	n.ReadAt = &now
}

// NotificationResponse represents notification data for API responses
type NotificationResponse struct {
	ID         uint       `json:"id"`
	Type       string     `json:"type"`
	Title      string     `json:"title"`
	Message    string     `json:"message"`
	EntityType string     `json:"entity_type"`
	EntityID   *uint      `json:"entity_id"`
	IsRead     bool       `json:"is_read"`
	ReadAt     *time.Time `json:"read_at"`
	CreatedAt  time.Time  `json:"created_at"`
}

// ToResponse converts Notification to NotificationResponse
func (n *Notification) ToResponse() NotificationResponse {
	return NotificationResponse{
		ID:         n.ID,
		Type:       n.Type,
		Title:      n.Title,
		Message:    n.Message,
		EntityType: n.EntityType,
		EntityID:   n.EntityID,
		IsRead:     n.IsRead,
		ReadAt:     n.ReadAt,
		CreatedAt:  n.CreatedAt,
	}
}

// CreateNotification creates a new notification
func CreateNotification(db *gorm.DB, userID uint, notifType, title, message, entityType string, entityID *uint) error {
	notification := &Notification{
		UserID:     userID,
		Type:       notifType,
		Title:      title,
		Message:    message,
		EntityType: entityType,
		EntityID:   entityID,
	}

	return db.Create(notification).Error
}

// CreateMatchNotification creates a notification for match found
func CreateMatchNotification(db *gorm.DB, userID uint, itemName string, matchID uint) error {
	return CreateNotification(
		db,
		userID,
		NotificationMatchFound,
		"Barang yang Mirip Ditemukan!",
		"Kami menemukan barang yang mirip dengan laporan kehilangan Anda: "+itemName,
		"match",
		&matchID,
	)
}

// CreateClaimApprovedNotification creates a notification for approved claim
func CreateClaimApprovedNotification(db *gorm.DB, userID uint, itemName string, claimID uint) error {
	return CreateNotification(
		db,
		userID,
		NotificationClaimApproved,
		"Klaim Disetujui!",
		"Klaim Anda untuk barang '"+itemName+"' telah disetujui. Silakan ambil barang di tempat yang ditentukan.",
		"claim",
		&claimID,
	)
}

// CreateClaimRejectedNotification creates a notification for rejected claim
func CreateClaimRejectedNotification(db *gorm.DB, userID uint, itemName, reason string, claimID uint) error {
	return CreateNotification(
		db,
		userID,
		NotificationClaimRejected,
		"Klaim Ditolak",
		"Klaim Anda untuk barang '"+itemName+"' ditolak. Alasan: "+reason,
		"claim",
		&claimID,
	)
}