package storage

import (
	"time"

	"github.com/rs/zerolog/log"
	"gorm.io/gorm"

	"git.mstar.dev/mstar/linstrom/shared"
)

// Describes a custom attribute field for accounts
type UserInfoField struct {
	gorm.Model       // Can actually just embed this as is here as those are not something directly exposed :3
	Name             string
	Value            string
	LastUrlCheckDate *time.Time // Used if the value is an url to somewhere. Empty if value is not an url
	// If the value is an url, this attribute indicates whether Linstrom was able to verify ownership
	// of the provided url via the common method of
	// "Does the target url contain a rel='me' link to the owner's account"
	Confirmed bool
	BelongsTo string // Id of account this info field belongs to
}

// TODO: Add functions to store, load, update and delete these

func (s *Storage) FindUserFieldById(id uint) (*UserInfoField, error) {
	defer shared.Untrace(shared.Trace(&log.Logger))
	entry := UserInfoField{}
	err := s.db.First(&entry, id).Error
	switch err {
	case nil:
		return &entry, nil
	case gorm.ErrRecordNotFound:
		return nil, ErrEntryNotFound
	default:
		return nil, err
	}
}

func (s *Storage) FindMultipleUserFieldsById(ids []uint) ([]UserInfoField, error) {
	defer shared.Untrace(shared.Trace(&log.Logger))
	entries := []UserInfoField{}
	err := s.db.Where(ids).Find(&entries).Error
	switch err {
	case gorm.ErrRecordNotFound:
		return nil, ErrEntryNotFound
	case nil:
		return entries, nil
	default:
		return nil, err
	}
}

func (s *Storage) AddNewUserField(name, value, belongsToId string) (*UserInfoField, error) {
	// TODO: Implement me
	panic("Not implemented")
}

func (s *Storage) DeleteUserField(id uint) error {
	defer shared.Untrace(shared.Trace(&log.Logger))
	return s.db.Delete(UserInfoField{Model: gorm.Model{ID: id}}).Error
}

func (s *Storage) DeleteAllUserFieldsForAccountId(id string) error {
	defer shared.Untrace(shared.Trace(&log.Logger))
	return s.db.Model(&UserInfoField{}).
		Where(&UserInfoField{BelongsTo: id}).
		Delete(&UserInfoField{}).
		Error
}
