package auth

import (
	"time"

	"gorm.io/gorm"

	filemanager "wucher/internal/domain/file_manager"
	"wucher/internal/shared/pkg/uuidv7"
)

// Note: UUIDv7 should be generated at application layer and stored as BINARY(16).
type User struct {
	ID                  []byte   `gorm:"type:binary(16);primaryKey;column:id"`
	RoleID              []byte   `gorm:"type:binary(16);index;column:role_id"`
	RoleIDs             [][]byte `gorm:"-"`
	Roles               []Role   `gorm:"-"`
	ImageAttachmentID   []byte   `gorm:"type:binary(16);index;column:image_attachment_id"`
	ProfileAttachmentID []byte   `gorm:"type:binary(16);index;column:profile_attachment_id"`

	Email        string  `gorm:"type:varchar(191);uniqueIndex;not null;column:email"`
	SSOEmail     *string `gorm:"type:varchar(191);uniqueIndex;column:sso_email"`
	Username     *string `gorm:"type:varchar(100);index;column:username"`
	FirstName    string  `gorm:"type:varchar(100);not null;column:first_name"`
	LastName     string  `gorm:"type:varchar(100);not null;column:last_name"`
	MobilePhone  string  `gorm:"type:varchar(32);index;column:mobile_phone"`
	Timezone     string  `gorm:"type:varchar(64);not null;default:UTC;column:timezone"`
	SortKey      *int    `gorm:"index;column:sortkey"`
	PasswordHash []byte  `gorm:"type:varbinary(255);column:password_hash"`
	SaltValue    []byte  `gorm:"type:varbinary(255);column:salt_value"`
	// Stores PIN hash records ("<salt_b64>$<hash_b64>"); legacy rows may still contain encrypted values.
	SecurityPINHash  []byte     `gorm:"type:varbinary(512);column:security_pin_hash"`
	SecurityPINSetAt *time.Time `gorm:"column:security_pin_set_at"`
	EmailVerifiedAt  *time.Time `gorm:"column:email_verified_at"`
	IsActive         bool       `gorm:"index;not null;default:true;column:is_active"`
	CreatedAt        time.Time
	CreatedBy        []byte `gorm:"type:binary(16);column:created_by"`
	UpdatedAt        time.Time
	UpdatedBy        []byte `gorm:"type:binary(16);column:updated_by"`

	PilotProfile           *PilotProfile           `gorm:"foreignKey:UserID;references:ID"`
	DoctorProfile          *DoctorProfile          `gorm:"foreignKey:UserID;references:ID"`
	AirRescuerProfile      *AirRescuerProfile      `gorm:"foreignKey:UserID;references:ID"`
	TechnicianProfile      *TechnicianProfile      `gorm:"foreignKey:UserID;references:ID"`
	FlightAssistantProfile *FlightAssistantProfile `gorm:"foreignKey:UserID;references:ID"`
	StaffProfile           *StaffProfile           `gorm:"foreignKey:UserID;references:ID"`
	ImageAttachment        *filemanager.Attachment `gorm:"foreignKey:ImageAttachmentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	ProfileAttachment      *filemanager.Attachment `gorm:"foreignKey:ProfileAttachmentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}

func (User) TableName() string { return "users" }

func (u *User) BeforeCreate(tx *gorm.DB) error {
	if len(u.ID) == 0 {
		u.ID = uuidv7.MustBytes()
	}
	return nil
}
