package model

import (
	"time"

	"gorm.io/gorm"
)

// User represents a user in the system
type Customer struct {
	ID                       uint           `gorm:"primaryKey" json:"id"`
	Email                    string         `gorm:"uniqueIndex;not null;size:255" json:"email"`
	Password                 string         `gorm:"size:255" json:"-"` // Hashed password, not exposed in JSON
	FirstName                string         `gorm:"size:100" json:"first_name"`
	LastName                 string         `gorm:"size:100" json:"last_name"`
	Role                     CustomerRole   `gorm:"type:varchar(20);default:'user'" json:"role"`
	Provider                 AuthProvider   `gorm:"type:varchar(20);default:'local'" json:"provider"`
	ProviderID               string         `gorm:"size:255" json:"provider_id,omitempty"` // ID from OAuth provider
	AvatarURL                string         `gorm:"size:500" json:"avatar_url,omitempty"`
	IsActive                 bool           `gorm:"default:true" json:"is_active"`
	EmailVerified            bool           `gorm:"default:false" json:"email_verified"`
	EmailVerificationToken   string         `gorm:"size:255" json:"-"`
	EmailVerificationExpires *time.Time     `json:"-"`
	PasswordResetToken       string         `gorm:"size:255" json:"-"`
	PasswordResetExpires     *time.Time     `json:"-"`
	LastPasswordResetRequest *time.Time     `json:"-"`
	LastLoginAt              *time.Time     `json:"last_login_at,omitempty"`
	LangID                   uint           `gorm:"default:2" json:"lang_id"`    // User's preferred language
	CountryID                uint           `gorm:"default:2" json:"country_id"` // User's selected country
	CreatedAt                time.Time      `json:"created_at"`
	UpdatedAt                time.Time      `json:"updated_at"`
	DeletedAt                gorm.DeletedAt `gorm:"index" json:"-"`
}

// CustomerRole represents the role of a user
type CustomerRole string

const (
	RoleUser  CustomerRole = "user"
	RoleAdmin CustomerRole = "admin"
)

// AuthProvider represents the authentication provider
type AuthProvider string

const (
	ProviderLocal  AuthProvider = "local"
	ProviderGoogle AuthProvider = "google"
)

// TableName specifies the table name for User model
func (Customer) TableName() string {
	return "b2b_customers"
}

// IsAdmin checks if the user has admin role
func (u *Customer) IsAdmin() bool {
	return u.Role == RoleAdmin
}

// CanManageUsers checks if the user can manage other users
func (u *Customer) CanManageUsers() bool {
	return u.Role == RoleAdmin
}

// FullName returns the user's full name
func (u *Customer) FullName() string {
	if u.FirstName == "" && u.LastName == "" {
		return u.Email
	}
	return u.FirstName + " " + u.LastName
}

// UserSession represents a user session for JWT claims
type UserSession struct {
	UserID    uint         `json:"user_id"`
	Email     string       `json:"email"`
	Username  string       `json:"username"`
	Role      CustomerRole `json:"role"`
	LangID    uint         `json:"lang_id"`
	CountryID uint         `json:"country_id"`
	IsActive  bool         `json:"is_active"`
}

// ToSession converts User to UserSession
func (u *Customer) ToSession() *UserSession {
	return &UserSession{
		UserID:    u.ID,
		Email:     u.Email,
		Role:      u.Role,
		LangID:    u.LangID,
		CountryID: u.CountryID,
		IsActive:  u.IsActive,
	}
}

// LoginRequest represents the login form data
type LoginRequest struct {
	Email    string `json:"email" form:"email"`
	Password string `json:"password" form:"password"`
}

// RegisterRequest represents the initial registration form data
type RegisterRequest struct {
	ErrorMsg        string `form:"error_msg" json:"error_msg"`
	Email           string `json:"email" form:"email"`
	Password        string `json:"password" form:"password"`
	ConfirmPassword string `json:"confirm_password" form:"confirm_password"`
	FirstName       string `json:"first_name" form:"first_name"`
	LastName        string `json:"last_name" form:"last_name"`
	LangID          uint   `form:"lang_id" json:"lang_id"`
	CountryID       uint   `form:"country_id" json:"country_id"`
}

// CompleteRegistrationRequest represents the completion of registration with email verification
type CompleteRegistrationRequest struct {
	Token string `json:"token" form:"token"`
}

// ResetPasswordRequest represents the reset password form data
type ResetPasswordRequest struct {
	Token    string `json:"token" form:"token"`
	Password string `json:"password" form:"password"`
}

// AuthResponse represents the authentication response
type AuthResponse struct {
	AccessToken string       `json:"access_token"`
	TokenType   string       `json:"token_type"`
	ExpiresIn   int          `json:"expires_in"`
	User        *UserSession `json:"user"`
}

// RefreshToken represents an opaque refresh token stored in the database
type RefreshToken struct {
	ID         uint      `gorm:"primaryKey" json:"-"`
	CustomerID uint      `gorm:"not null;index" json:"-"`
	TokenHash  string    `gorm:"size:64;uniqueIndex;not null" json:"-"` // SHA-256 hex of the raw token
	ExpiresAt  time.Time `gorm:"not null" json:"-"`
	CreatedAt  time.Time `json:"-"`
}

// TableName specifies the table name for RefreshToken model
func (RefreshToken) TableName() string {
	return "b2b_refresh_tokens"
}

type UserInList struct {
	UserID    uint   `gorm:"primaryKey;column:id" json:"user_id"`
	Email     string `gorm:"column:email" json:"email"`
	FirstName string `gorm:"column:first_name" json:"first_name"`
	LastName  string `gorm:"column:last_name" json:"last_name"`
	Role      string `gorm:"column:role" json:"role"`
}
