package models

import (
	"time"

	"gorm.io/gorm"
)

// Comment table - in forum threads, on profiles or photos, etc.
type Comment struct {
	ID        uint64 `gorm:"primaryKey"`
	TableName string `gorm:"index"`
	TableID   uint64 `gorm:"index"`
	UserID    uint64 `gorm:"index"`
	User      User
	Message   string
	CreatedAt time.Time
	UpdatedAt time.Time
}

// Preload related tables for the forum (classmethod).
func (c *Comment) Preload() *gorm.DB {
	return DB.Preload("User.ProfilePhoto")
}

// GetComment by ID.
func GetComment(id uint64) (*Comment, error) {
	c := &Comment{}
	result := c.Preload().First(&c, id)
	return c, result.Error
}

// AddComment about anything.
func AddComment(user *User, tableName string, tableID uint64, message string) (*Comment, error) {
	c := &Comment{
		TableName: tableName,
		TableID:   tableID,
		User:      *user,
		Message:   message,
	}
	result := DB.Create(c)
	return c, result.Error
}

// PaginateComments provides a page of comments on something.
func PaginateComments(user *User, tableName string, tableID uint64, pager *Pagination) ([]*Comment, error) {
	var (
		cs    = []*Comment{}
		query = (&Comment{}).Preload()
	)

	query = query.Where(
		"table_name = ? AND table_id = ?",
		tableName, tableID,
	).Order(pager.Sort)

	query.Model(&Comment{}).Count(&pager.Total)
	result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&cs)
	return cs, result.Error
}

// Save a comment.
func (c *Comment) Save() error {
	return DB.Save(c).Error
}

// Delete a comment.
func (c *Comment) Delete() error {
	return DB.Delete(c).Error
}
