package service

import (
	"context"

	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/transformer"

	"github.com/google/uuid"
)

type UserServiceImpl struct {
	userProcessor UserProcessor
}

func NewUserService(userProcessor UserProcessor) *UserServiceImpl {
	return &UserServiceImpl{
		userProcessor: userProcessor,
	}
}

func (s *UserServiceImpl) CreateUser(ctx context.Context, req *contract.CreateUserRequest) (*contract.UserResponse, error) {
	modelReq := transformer.CreateUserRequestToModel(req)

	userResponse, err := s.userProcessor.CreateUser(ctx, modelReq)
	if err != nil {
		return nil, err
	}

	contractResponse := transformer.UserModelResponseToResponse(userResponse)
	return contractResponse, nil
}

func (s *UserServiceImpl) UpdateUser(ctx context.Context, id uuid.UUID, req *contract.UpdateUserRequest) (*contract.UserResponse, error) {
	modelReq := transformer.UpdateUserRequestToModel(req)

	userResponse, err := s.userProcessor.UpdateUser(ctx, id, modelReq)
	if err != nil {
		return nil, err
	}

	contractResponse := transformer.UserModelResponseToResponse(userResponse)

	return contractResponse, nil
}

func (s *UserServiceImpl) DeleteUser(ctx context.Context, id uuid.UUID) error {
	return s.userProcessor.DeleteUser(ctx, id)
}

func (s *UserServiceImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*contract.UserResponse, error) {
	userResponse, err := s.userProcessor.GetUserByID(ctx, id)
	if err != nil {
		return nil, err
	}

	contractResponse := transformer.UserModelResponseToResponse(userResponse)

	return contractResponse, nil
}

func (s *UserServiceImpl) GetUserByEmail(ctx context.Context, email string) (*contract.UserResponse, error) {
	userResponse, err := s.userProcessor.GetUserByEmail(ctx, email)
	if err != nil {
		return nil, err
	}

	contractResponse := transformer.UserModelResponseToResponse(userResponse)

	return contractResponse, nil
}

func (s *UserServiceImpl) ListUsers(ctx context.Context, req *contract.ListUsersRequest) (*contract.ListUsersResponse, error) {
	page, limit := transformer.PaginationToRequest(req.Page, req.Limit)

	userResponses, totalCount, err := s.userProcessor.ListUsers(ctx, *req.OrganizationID, page, limit)
	if err != nil {
		return nil, err
	}

	contractResponses := transformer.UserResponsesToResponses(userResponses)

	response := transformer.CreateListUsersResponse(contractResponses, totalCount, page, limit)

	return response, nil
}

func (s *UserServiceImpl) ChangePassword(ctx context.Context, userID uuid.UUID, req *contract.ChangePasswordRequest) error {
	modelReq := transformer.ChangePasswordRequestToModel(req)

	return s.userProcessor.ChangePassword(ctx, userID, modelReq)
}

func (s *UserServiceImpl) ActivateUser(ctx context.Context, userID uuid.UUID) error {
	return s.userProcessor.ActivateUser(ctx, userID)
}

func (s *UserServiceImpl) DeactivateUser(ctx context.Context, userID uuid.UUID) error {
	return s.userProcessor.DeactivateUser(ctx, userID)
}

func (s *UserServiceImpl) UpdateUserOutlet(ctx context.Context, userID uuid.UUID, req *contract.UpdateUserOutletRequest) (*contract.UserResponse, error) {
	modelReq := transformer.UpdateUserOutletRequestToModel(req)

	userResponse, err := s.userProcessor.UpdateUserOutlet(ctx, userID, modelReq)
	if err != nil {
		return nil, err
	}

	contractResponse := transformer.UserModelResponseToResponse(userResponse)
	return contractResponse, nil
}
