package models

import (
	"apskel-pos-be/internal/constants"
	"time"

	"github.com/google/uuid"
)

type User struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	OutletID       *uuid.UUID
	Name           string
	Email          string
	Role           constants.UserRole
	Permissions    map[string]interface{}
	IsActive       bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type CreateUserRequest struct {
	OrganizationID uuid.UUID `validate:"required"`
	OutletID       *uuid.UUID
	Name           string                 `validate:"required,min=1,max=255"`
	Email          string                 `validate:"required,email"`
	Password       string                 `validate:"required,min=6"`
	Role           constants.UserRole     `validate:"required"`
	Permissions    map[string]interface{} `validate:"omitempty"`
}

type UpdateUserRequest struct {
	Name        *string `validate:"omitempty,min=1,max=255"`
	Email       *string `validate:"omitempty,email"`
	Role        *constants.UserRole
	OutletID    *uuid.UUID
	IsActive    *bool
	Permissions *map[string]interface{}
}

type ChangePasswordRequest struct {
	CurrentPassword string `validate:"required"`
	NewPassword     string `validate:"required,min=6"`
}

type UpdateUserOutletRequest struct {
	OutletID uuid.UUID `validate:"required"`
}

type UserResponse struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	OutletID       *uuid.UUID
	Name           string
	Email          string
	Role           constants.UserRole
	Permissions    map[string]interface{}
	IsActive       bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

func (u *User) HasPermission(requiredRole constants.UserRole) bool {
	roleHierarchy := map[constants.UserRole]int{
		constants.RoleWaiter:  1,
		constants.RoleCashier: 2,
		constants.RoleManager: 3,
		constants.RoleAdmin:   4,
	}

	userLevel := roleHierarchy[u.Role]
	requiredLevel := roleHierarchy[requiredRole]

	return userLevel >= requiredLevel
}

func (u *User) CanAccessOutlet(outletID uuid.UUID) bool {
	if u.Role == constants.RoleAdmin {
		return true
	}

	return u.OutletID != nil && *u.OutletID == outletID
}

func (u *User) IsManager() bool {
	return u.HasPermission(constants.RoleManager)
}

func (u *User) IsAdmin() bool {
	return u.Role == constants.RoleAdmin
}
