package models

import (
	"math"

	"git.mstar.dev/mstar/goutils/other"
	"gorm.io/gorm"
)

// Default role every user has. Defines sane defaults for a normal user
// Will get overwritten by just about every other role due to every other role having higher priority
var DefaultUserRole = Role{
	Model:      gorm.Model{ID: 1},
	Name:       "Default",
	Priority:   0,
	IsUserRole: false,
	IsBuiltIn:  true,

	CanSendMedia:             other.IntoPointer(true),
	CanSendCustomEmotes:      other.IntoPointer(true),
	CanSendCustomReactions:   other.IntoPointer(true),
	CanSendPublicNotes:       other.IntoPointer(true),
	CanSendLocalNotes:        other.IntoPointer(true),
	CanSendFollowerOnlyNotes: other.IntoPointer(true),
	CanSendPrivateNotes:      other.IntoPointer(true),
	CanSendReplies:           other.IntoPointer(true),
	CanQuote:                 other.IntoPointer(true),
	CanBoost:                 other.IntoPointer(true),
	CanIncludeLinks:          other.IntoPointer(true),
	CanIncludeSurvey:         other.IntoPointer(true),
	CanFederateFedi:          other.IntoPointer(true),
	CanFederateBsky:          other.IntoPointer(true),

	CanChangeDisplayName: other.IntoPointer(true),

	CanSubmitReports: other.IntoPointer(true),
	CanLogin:         other.IntoPointer(true),

	CanMentionOthers:     other.IntoPointer(true),
	HasMentionCountLimit: other.IntoPointer(false),
	MentionLimit: other.IntoPointer(
		uint32(math.MaxUint32),
	), // Set this to max, even if not used due to *HasMentionCountLimit == false

	AutoNsfwMedia:                  other.IntoPointer(false),
	AutoCwPosts:                    other.IntoPointer(false),
	AutoCwPostsText:                nil,
	WithholdNotesForManualApproval: other.IntoPointer(false),
	ScanCreatedPublicNotes:         other.IntoPointer(false),
	ScanCreatedLocalNotes:          other.IntoPointer(false),
	ScanCreatedFollowerOnlyNotes:   other.IntoPointer(false),
	ScanCreatedPrivateNotes:        other.IntoPointer(false),
	DisallowInteractionsWith:       []string{},

	FullAdmin:                          other.IntoPointer(false),
	CanAffectOtherAdmins:               other.IntoPointer(false),
	CanDeleteNotes:                     other.IntoPointer(false),
	CanConfirmWithheldNotes:            other.IntoPointer(false),
	CanAssignRoles:                     other.IntoPointer(false),
	CanSupressInteractionsBetweenUsers: other.IntoPointer(false),
	CanOverwriteDisplayNames:           other.IntoPointer(false),
	CanManageCustomEmotes:              other.IntoPointer(false),
	CanViewDeletedNotes:                other.IntoPointer(false),
	CanRecoverDeletedNotes:             other.IntoPointer(false),
	CanManageAvatarDecorations:         other.IntoPointer(false),
	CanManageAds:                       other.IntoPointer(false),
	CanSendAnnouncements:               other.IntoPointer(false),
}

// Role providing maximum permissions
var FullAdminRole = Role{
	Model:      gorm.Model{ID: 2},
	Name:       "fullAdmin",
	Priority:   math.MaxUint32,
	IsUserRole: false,
	IsBuiltIn:  true,

	CanSendMedia:             other.IntoPointer(true),
	CanSendCustomEmotes:      other.IntoPointer(true),
	CanSendCustomReactions:   other.IntoPointer(true),
	CanSendPublicNotes:       other.IntoPointer(true),
	CanSendLocalNotes:        other.IntoPointer(true),
	CanSendFollowerOnlyNotes: other.IntoPointer(true),
	CanSendPrivateNotes:      other.IntoPointer(true),
	CanQuote:                 other.IntoPointer(true),
	CanBoost:                 other.IntoPointer(true),
	CanIncludeLinks:          other.IntoPointer(true),
	CanIncludeSurvey:         other.IntoPointer(true),

	CanChangeDisplayName: other.IntoPointer(true),

	CanSubmitReports: other.IntoPointer(true),
	CanLogin:         other.IntoPointer(true),

	CanMentionOthers:     other.IntoPointer(true),
	HasMentionCountLimit: other.IntoPointer(false),
	MentionLimit: other.IntoPointer(
		uint32(math.MaxUint32),
	), // Set this to max, even if not used due to *HasMentionCountLimit == false

	AutoNsfwMedia:                  other.IntoPointer(false),
	AutoCwPosts:                    other.IntoPointer(false),
	AutoCwPostsText:                nil,
	WithholdNotesForManualApproval: other.IntoPointer(false),
	ScanCreatedPublicNotes:         other.IntoPointer(false),
	ScanCreatedLocalNotes:          other.IntoPointer(false),
	ScanCreatedFollowerOnlyNotes:   other.IntoPointer(false),
	ScanCreatedPrivateNotes:        other.IntoPointer(false),
	DisallowInteractionsWith:       []string{},

	FullAdmin:                          other.IntoPointer(true),
	CanAffectOtherAdmins:               other.IntoPointer(true),
	CanDeleteNotes:                     other.IntoPointer(true),
	CanConfirmWithheldNotes:            other.IntoPointer(true),
	CanAssignRoles:                     other.IntoPointer(true),
	CanSupressInteractionsBetweenUsers: other.IntoPointer(true),
	CanOverwriteDisplayNames:           other.IntoPointer(true),
	CanManageCustomEmotes:              other.IntoPointer(true),
	CanViewDeletedNotes:                other.IntoPointer(true),
	CanRecoverDeletedNotes:             other.IntoPointer(true),
	CanManageAvatarDecorations:         other.IntoPointer(true),
	CanManageAds:                       other.IntoPointer(true),
	CanSendAnnouncements:               other.IntoPointer(true),
}

// Role for totally freezing an account, blocking all activity from it
var AccountFreezeRole = Role{
	Model:      gorm.Model{ID: 3},
	Name:       "accountFreeze",
	Priority:   math.MaxUint32 - 1,
	IsUserRole: false,
	IsBuiltIn:  true,

	CanSendMedia:             other.IntoPointer(false),
	CanSendCustomEmotes:      other.IntoPointer(false),
	CanSendCustomReactions:   other.IntoPointer(false),
	CanSendPublicNotes:       other.IntoPointer(false),
	CanSendLocalNotes:        other.IntoPointer(false),
	CanSendFollowerOnlyNotes: other.IntoPointer(false),
	CanSendPrivateNotes:      other.IntoPointer(false),
	CanSendReplies:           other.IntoPointer(false),
	CanQuote:                 other.IntoPointer(false),
	CanBoost:                 other.IntoPointer(false),
	CanIncludeLinks:          other.IntoPointer(false),
	CanIncludeSurvey:         other.IntoPointer(false),
	CanFederateBsky:          other.IntoPointer(false),
	CanFederateFedi:          other.IntoPointer(false),

	CanChangeDisplayName: other.IntoPointer(false),

	CanSubmitReports: other.IntoPointer(false),
	CanLogin:         other.IntoPointer(false),

	CanMentionOthers:     other.IntoPointer(false),
	HasMentionCountLimit: other.IntoPointer(false),
	MentionLimit: other.IntoPointer(
		uint32(math.MaxUint32),
	), // Set this to max, even if not used due to *HasMentionCountLimit == false

	AutoNsfwMedia:                  other.IntoPointer(true),
	AutoCwPosts:                    other.IntoPointer(false),
	AutoCwPostsText:                other.IntoPointer("Account frozen"),
	WithholdNotesForManualApproval: other.IntoPointer(true),
	ScanCreatedPublicNotes:         other.IntoPointer(false),
	ScanCreatedLocalNotes:          other.IntoPointer(false),
	ScanCreatedFollowerOnlyNotes:   other.IntoPointer(false),
	ScanCreatedPrivateNotes:        other.IntoPointer(false),
	DisallowInteractionsWith:       []string{},

	FullAdmin:                          other.IntoPointer(false),
	CanAffectOtherAdmins:               other.IntoPointer(false),
	CanDeleteNotes:                     other.IntoPointer(false),
	CanConfirmWithheldNotes:            other.IntoPointer(false),
	CanAssignRoles:                     other.IntoPointer(false),
	CanSupressInteractionsBetweenUsers: other.IntoPointer(false),
	CanOverwriteDisplayNames:           other.IntoPointer(false),
	CanManageCustomEmotes:              other.IntoPointer(false),
	CanViewDeletedNotes:                other.IntoPointer(false),
	CanRecoverDeletedNotes:             other.IntoPointer(false),
	CanManageAvatarDecorations:         other.IntoPointer(false),
	CanManageAds:                       other.IntoPointer(false),
	CanSendAnnouncements:               other.IntoPointer(false),
}

var ServerActorRole = Role{
	Model:      gorm.Model{ID: 4},
	Name:       "ServerActor",
	Priority:   math.MaxUint32,
	IsUserRole: true,
	IsBuiltIn:  true,

	CanSendMedia:             other.IntoPointer(true),
	CanSendCustomEmotes:      other.IntoPointer(true),
	CanSendCustomReactions:   other.IntoPointer(true),
	CanSendPublicNotes:       other.IntoPointer(true),
	CanSendLocalNotes:        other.IntoPointer(true),
	CanSendFollowerOnlyNotes: other.IntoPointer(true),
	CanSendPrivateNotes:      other.IntoPointer(true),
	CanQuote:                 other.IntoPointer(true),
	CanBoost:                 other.IntoPointer(true),
	CanIncludeLinks:          other.IntoPointer(true),
	CanIncludeSurvey:         other.IntoPointer(true),

	CanChangeDisplayName: other.IntoPointer(true),

	CanSubmitReports: other.IntoPointer(true),
	CanLogin:         other.IntoPointer(true),

	CanMentionOthers:     other.IntoPointer(true),
	HasMentionCountLimit: other.IntoPointer(false),
	MentionLimit: other.IntoPointer(
		uint32(math.MaxUint32),
	), // Set this to max, even if not used due to *HasMentionCountLimit == false

	AutoNsfwMedia:                  other.IntoPointer(false),
	AutoCwPosts:                    other.IntoPointer(false),
	AutoCwPostsText:                nil,
	WithholdNotesForManualApproval: other.IntoPointer(false),
	ScanCreatedPublicNotes:         other.IntoPointer(false),
	ScanCreatedLocalNotes:          other.IntoPointer(false),
	ScanCreatedFollowerOnlyNotes:   other.IntoPointer(false),
	ScanCreatedPrivateNotes:        other.IntoPointer(false),
	DisallowInteractionsWith:       []string{},

	FullAdmin:                          other.IntoPointer(true),
	CanAffectOtherAdmins:               other.IntoPointer(true),
	CanDeleteNotes:                     other.IntoPointer(true),
	CanConfirmWithheldNotes:            other.IntoPointer(true),
	CanAssignRoles:                     other.IntoPointer(true),
	CanSupressInteractionsBetweenUsers: other.IntoPointer(true),
	CanOverwriteDisplayNames:           other.IntoPointer(true),
	CanManageCustomEmotes:              other.IntoPointer(true),
	CanViewDeletedNotes:                other.IntoPointer(true),
	CanRecoverDeletedNotes:             other.IntoPointer(true),
	CanManageAvatarDecorations:         other.IntoPointer(true),
	CanManageAds:                       other.IntoPointer(true),
	CanSendAnnouncements:               other.IntoPointer(true),
}

var AllDefaultRoles = []*Role{
	&DefaultUserRole,
	&FullAdminRole,
	&AccountFreezeRole,
	&ServerActorRole,
}
