package models

import (
	"time"

	"gorm.io/gorm"
)

// CertificationPhoto table.
type CertificationPhoto struct {
	ID           uint64 `gorm:"primaryKey"`
	UserID       uint64 `gorm:"uniqueIndex"`
	Filename     string
	Filesize     int64
	Status       CertificationPhotoStatus
	AdminComment string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type CertificationPhotoStatus string

const (
	CertificationPhotoNeeded   CertificationPhotoStatus = "needed"
	CertificationPhotoPending                           = "pending"
	CertificationPhotoApproved                          = "approved"
	CertificationPhotoRejected                          = "rejected"
)

// GetCertificationPhoto retrieves the user's record from the DB or upserts their initial record.
func GetCertificationPhoto(userID uint64) (*CertificationPhoto, error) {
	p := &CertificationPhoto{}
	result := DB.Where("user_id = ?", userID).First(&p)
	if result.Error == gorm.ErrRecordNotFound {
		p = &CertificationPhoto{
			UserID: userID,
			Status: CertificationPhotoNeeded,
		}
		result = DB.Create(p)
		return p, result.Error
	}
	return p, result.Error
}

// CertificationPhotosNeedingApproval returns a pager of the pictures that require admin approval.
func CertificationPhotosNeedingApproval(status CertificationPhotoStatus, pager *Pagination) ([]*CertificationPhoto, error) {
	var p = []*CertificationPhoto{}

	query := DB.Where(
		"status = ?",
		status,
	).Order(
		pager.Sort,
	)

	// Get the total count.
	query.Model(&CertificationPhoto{}).Count(&pager.Total)

	result := query.Offset(
		pager.GetOffset(),
	).Limit(pager.PerPage).Find(&p)

	return p, result.Error
}

// CountCertificationPhotosNeedingApproval gets the count of pending photos for admin alert.
func CountCertificationPhotosNeedingApproval() int64 {
	var count int64
	DB.Where("status = ?", CertificationPhotoPending).Model(&CertificationPhoto{}).Count(&count)
	return count
}

// Save photo.
func (p *CertificationPhoto) Save() error {
	result := DB.Save(p)
	return result.Error
}

// Delete the DB entry.
func (p *CertificationPhoto) Delete() error {
	return DB.Delete(p).Error
}
