// internal/models/user.go - FIXED VERSION
package models

import (
	"lost-and-found/internal/utils"
	"time"

	"gorm.io/gorm"
)

// User represents a user in the system
type User struct {
	ID        uint           `gorm:"primaryKey" json:"id"`
	Name      string         `gorm:"type:varchar(100);not null" json:"name"`
	Email     string         `gorm:"type:varchar(100);uniqueIndex;not null" json:"email"`
	Password  string         `gorm:"type:varchar(255);not null" json:"-"`
	NRP        string         `gorm:"type:varchar(20)" json:"nrp"`      // ✅ Plain text
	Phone      string         `gorm:"type:varchar(20)" json:"phone"`    // ✅ Plain text
	RoleID     uint           `gorm:"not null;default:3" json:"role_id"`
	Role       Role           `gorm:"foreignKey:RoleID" json:"role,omitempty"`
	Status     string         `gorm:"type:varchar(20);default:'active'" json:"status"`
	LastLogin  *time.Time     `json:"last_login"`
	CreatedAt  time.Time      `json:"created_at"`
	UpdatedAt  time.Time      `json:"updated_at"`
	DeletedAt  gorm.DeletedAt `gorm:"index" json:"-"`
}

// TableName specifies the table name
func (User) TableName() string {
	return "users"
}

// User status constants
const (
	UserStatusActive  = "active"
	UserStatusBlocked = "blocked"
)

// IsActive checks if user is active
func (u *User) IsActive() bool {
	return u.Status == UserStatusActive
}

// IsBlocked checks if user is blocked
func (u *User) IsBlocked() bool {
	return u.Status == UserStatusBlocked
}

// IsAdmin checks if user is admin
func (u *User) IsAdmin() bool {
	return u.Role.Name == "admin"
}

// IsManager checks if user is manager
func (u *User) IsManager() bool {
	return u.Role.Name == "manager"
}

func (u *User) HasPermission(permissionSlug string) bool {
    // Jika Role atau Permissions belum di-load, return false (fail safe)
    if u.Role.ID == 0 {
        return false
    }
    
    // Admin (Role ID 1) biasanya bypass semua check, tapi sebaiknya tetap cek list
    // untuk konsistensi database.
    
    for _, perm := range u.Role.Permissions {
        if perm.Slug == permissionSlug {
            return true
        }
    }
    return false
}

// IsUser checks if user is regular user
func (u *User) IsUser() bool {
	return u.Role.Name == "user"
}

// UserResponse represents user data for API responses
type UserResponse struct {
	ID        uint       `json:"id"`
	Name      string     `json:"name"`
	Email     string     `json:"email"`
	NRP       string     `json:"nrp,omitempty"`   // ✅ Langsung dari database
	Phone     string     `json:"phone,omitempty"` // ✅ Langsung dari database
	Role      string     `json:"role"`
	Status    string     `json:"status"`
	LastLogin *time.Time `json:"last_login,omitempty"`
	CreatedAt time.Time  `json:"created_at"`
}

// ✅ ToResponse converts User to UserResponse dengan DEKRIPSI
func (u *User) ToResponse() UserResponse {
	response := UserResponse{
		ID:        u.ID,
		Name:      u.Name,
		Email:     u.Email,
		NRP:       u.NRP,    // ✅ Langsung assign
		Phone:     u.Phone,  // ✅ Langsung assign
		Status:    u.Status,
		LastLogin: u.LastLogin,
		CreatedAt: u.CreatedAt,
	}

	// Set role name
	if u.Role.ID != 0 {
		response.Role = u.Role.Name
	}

	// ✅ DEKRIPSI NRP
	if u.NRP != "" {
		decryptedNRP, err := utils.DecryptString(u.NRP)
		if err == nil {
			response.NRP = decryptedNRP
		} else {
			// Jika dekripsi gagal, kembalikan nilai asli (untuk backward compatibility)
			response.NRP = u.NRP
		}
	}

	// ✅ DEKRIPSI Phone
	if u.Phone != "" {
		decryptedPhone, err := utils.DecryptString(u.Phone)
		if err == nil {
			response.Phone = decryptedPhone
		} else {
			// Jika dekripsi gagal, kembalikan nilai asli (untuk backward compatibility)
			response.Phone = u.Phone
		}
	}

	return response
}

// ✅ ToPublicResponse - untuk public access (hide sensitive data)
func (u *User) ToPublicResponse() UserResponse {
	return UserResponse{
		ID:        u.ID,
		Name:      u.Name,
		Role:      u.Role.Name,
		Status:    u.Status,
		CreatedAt: u.CreatedAt,
		// NRP & Phone tidak disertakan untuk security
	}
}