package notification

import (
	"time"

	"hfb_sys/backend/internal/model"

	"gorm.io/gorm"
)

type Repository struct {
	db *gorm.DB
}

type Entry struct {
	UserID  uint64
	Type    string
	Title   string
	Content string
	BizType string
	BizID   *uint64
}

func NewRepository(db *gorm.DB) *Repository {
	return &Repository{db: db}
}

func (r *Repository) List(userID uint64, page, pageSize int) (*PaginatedResult, error) {
	var total int64
	if err := r.db.Model(&model.Notification{}).Where("user_id = ?", userID).Count(&total).Error; err != nil {
		return nil, err
	}
	offset := (page - 1) * pageSize
	var rows []model.Notification
	if err := r.db.Where("user_id = ?", userID).Order("id DESC").Offset(offset).Limit(pageSize).Find(&rows).Error; err != nil {
		return nil, err
	}
	items := make([]NotificationDTO, 0, len(rows))
	for _, row := range rows {
		items = append(items, toDTO(row))
	}
	return &PaginatedResult{Items: items, Total: total, Page: page, PageSize: pageSize}, nil
}

func (r *Repository) MarkRead(userID uint64, id uint64) error {
	now := time.Now()
	return r.db.Model(&model.Notification{}).
		Where("id = ? AND user_id = ?", id, userID).
		Update("read_at", now).Error
}

func Append(tx *gorm.DB, entries ...Entry) error {
	for _, entry := range entries {
		if entry.UserID == 0 || entry.Title == "" {
			continue
		}
		row := model.Notification{
			UserID:  entry.UserID,
			Type:    entry.Type,
			Title:   entry.Title,
			Content: entry.Content,
			BizType: entry.BizType,
			BizID:   entry.BizID,
		}
		if row.Type == "" {
			row.Type = "system"
		}
		if err := tx.Create(&row).Error; err != nil {
			return err
		}
	}
	return nil
}

func toDTO(row model.Notification) NotificationDTO {
	return NotificationDTO{
		ID:        row.ID,
		UserID:    row.UserID,
		Type:      row.Type,
		Title:     row.Title,
		Content:   row.Content,
		BizType:   row.BizType,
		BizID:     row.BizID,
		ReadAt:    row.ReadAt,
		CreatedAt: row.CreatedAt,
	}
}
