package request

import (
	"netidhub-saas-be/app/database/entity/users"
	"netidhub-saas-be/utils/paginator"
	"strconv"
	"time"

	"github.com/google/uuid"
)

type UsersGeneric interface {
	ToEntity()
}

type UsersQueryRequest struct {
	Username            *string               `json:"username"`
	Email               *string               `json:"email"`
	Fullname            *string               `json:"fullname"`
	PhoneNumber         *string               `json:"phoneNumber"`
	WorkType            *string               `json:"workType"`
	GenderType          *string               `json:"genderType"`
	IdentityType        *string               `json:"identityType"`
	IdentityGroup       *string               `json:"identityGroup"`
	IdentityGroupNumber *string               `json:"identityGroupNumber"`
	IdentityNumber      *string               `json:"identityNumber"`
	UserRoleId          *int                  `json:"userRoleId"`
	StatusId            *int                  `json:"statusId"`
	Pagination          *paginator.Pagination `json:"pagination"`
}

type UsersCreateRequest struct {
	Username            string     `json:"username" validate:"required,lowercase"`
	Email               string     `json:"email" validate:"required,email"`
	Fullname            string     `json:"fullname" validate:"required"`
	UserLevelId         uint       `json:"userLevelId" validate:"required"`
	UserRoleId          uint       `json:"userRoleId" validate:"required"`
	Password            string     `json:"password" validate:"required"`
	PhoneNumber         *string    `json:"phoneNumber"`
	Address             *string    `json:"address"`
	WorkType            *string    `json:"workType"`
	GenderType          *string    `json:"genderType"`
	IdentityType        *string    `json:"identityType"`
	IdentityGroup       *string    `json:"identityGroup"`
	IdentityGroupNumber *string    `json:"identityGroupNumber"`
	IdentityNumber      *string    `json:"identityNumber"`
	DateOfBirth         *string    `json:"dateOfBirth"`
	LastEducation       *string    `json:"lastEducation"`
	ClientId            *uuid.UUID `json:"clientId"`
}

func (req UsersCreateRequest) ToEntity() *users.Users {
	return &users.Users{
		Username:            req.Username,
		Email:               req.Email,
		Fullname:            req.Fullname,
		Address:             req.Address,
		PhoneNumber:         req.PhoneNumber,
		WorkType:            req.WorkType,
		GenderType:          req.GenderType,
		IdentityType:        req.IdentityType,
		IdentityGroup:       req.IdentityGroup,
		IdentityGroupNumber: req.IdentityGroupNumber,
		IdentityNumber:      req.IdentityNumber,
		DateOfBirth:         req.DateOfBirth,
		LastEducation:       req.LastEducation,
		UserRoleId:          req.UserRoleId,
		UserLevelId:         req.UserLevelId,
	}
}

type UsersUpdateRequest struct {
	Username            string  `json:"username" validate:"required,lowercase"`
	Email               string  `json:"email" validate:"required,email"`
	Fullname            string  `json:"fullname" validate:"required"`
	UserLevelId         uint    `json:"userLevelId" validate:"required"`
	UserRoleId          uint    `json:"userRoleId" validate:"required"`
	PhoneNumber         *string `json:"phoneNumber"`
	Address             *string `json:"address"`
	WorkType            *string `json:"workType"`
	GenderType          *string `json:"genderType"`
	IdentityType        *string `json:"identityType"`
	IdentityGroup       *string `json:"identityGroup"`
	IdentityGroupNumber *string `json:"identityGroupNumber"`
	IdentityNumber      *string `json:"identityNumber"`
	DateOfBirth         *string `json:"dateOfBirth"`
	LastEducation       *string `json:"lastEducation"`
	StatusId            *int    `json:"statusId"`
}

func (req UsersUpdateRequest) ToEntity() *users.Users {
	return &users.Users{
		Username:            req.Username,
		Email:               req.Email,
		Fullname:            req.Fullname,
		Address:             req.Address,
		PhoneNumber:         req.PhoneNumber,
		WorkType:            req.WorkType,
		GenderType:          req.GenderType,
		IdentityType:        req.IdentityType,
		IdentityGroup:       req.IdentityGroup,
		IdentityGroupNumber: req.IdentityGroupNumber,
		IdentityNumber:      req.IdentityNumber,
		DateOfBirth:         req.DateOfBirth,
		LastEducation:       req.LastEducation,
		UserRoleId:          req.UserRoleId,
		StatusId:            req.StatusId,
		UserLevelId:         req.UserLevelId,
		UpdatedAt:           time.Now(),
	}
}

type UserLogin struct {
	Username     *string `json:"username"`
	Password     *string `json:"password"`
	RefreshToken *string `json:"refreshToken"`
}

type UserForgotPassword struct {
	Username string `json:"username"`
}

type UserSavePassword struct {
	Password        string `json:"password"`
	ConfirmPassword string `json:"confirmPassword"`
}

type UserResetPassword struct {
	CodeRequest     string `json:"codeRequest"`
	UserId          string `json:"userId"`
	Password        string `json:"password"`
	ConfirmPassword string `json:"confirmPassword"`
}

type UserEmailValidationRequest struct {
	Username *string `json:"username"`
	Password *string `json:"password"`
	OldEmail *string `json:"oldEmail"`
	NewEmail *string `json:"newEmail"`
}

type UserOtpRequest struct {
	Email string  `json:"email" validate:"required,email"`
	Name  *string `json:"name"`
}

type UserOtpValidation struct {
	Email    *string `json:"email"`
	Username *string `json:"username"`
	OtpCode  string  `json:"otpCode"`
}

type UsersQueryRequestContext struct {
	Username            string `json:"username"`
	Email               string `json:"email"`
	Fullname            string `json:"fullname"`
	PhoneNumber         string `json:"phoneNumber"`
	WorkType            string `json:"workType"`
	GenderType          string `json:"genderType"`
	IdentityType        string `json:"identityType"`
	IdentityGroup       string `json:"identityGroup"`
	IdentityGroupNumber string `json:"identityGroupNumber"`
	IdentityNumber      string `json:"identityNumber"`
	UserRoleId          string `json:"userRoleId"`
	StatusId            string `json:"statusId"`
}

func (req UsersQueryRequestContext) ToParamRequest() UsersQueryRequest {
	var request UsersQueryRequest

	if username := req.Username; username != "" {
		request.Username = &username
	}
	if email := req.Email; email != "" {
		request.Email = &email
	}
	if fullname := req.Fullname; fullname != "" {
		request.Fullname = &fullname
	}
	if phoneNumber := req.PhoneNumber; phoneNumber != "" {
		request.PhoneNumber = &phoneNumber
	}
	if workType := req.WorkType; workType != "" {
		request.WorkType = &workType
	}
	if genderType := req.GenderType; genderType != "" {
		request.GenderType = &genderType
	}
	if identityType := req.IdentityType; identityType != "" {
		request.IdentityType = &identityType
	}
	if identityGroup := req.IdentityGroup; identityGroup != "" {
		request.IdentityGroup = &identityGroup
	}
	if identityGroupNumber := req.IdentityGroupNumber; identityGroupNumber != "" {
		request.IdentityGroupNumber = &identityGroupNumber
	}
	if identityNumber := req.IdentityNumber; identityNumber != "" {
		request.IdentityNumber = &identityNumber
	}
	if userRoleIdStr := req.UserRoleId; userRoleIdStr != "" {
		userRoleId, err := strconv.Atoi(userRoleIdStr)
		if err == nil {
			request.UserRoleId = &userRoleId
		}
	}
	if statusIdStr := req.StatusId; statusIdStr != "" {
		statusId, err := strconv.Atoi(statusIdStr)
		if err == nil {
			request.StatusId = &statusId
		}
	}

	return request
}
