package user

import (
	"context"
	"errors"

	"github.com/rede5/gohorsejobs/backend/internal/core/domain/entity"
	"github.com/rede5/gohorsejobs/backend/internal/core/dto"
	"github.com/rede5/gohorsejobs/backend/internal/core/ports"
)

type UpdateUserUseCase struct {
	userRepo ports.UserRepository
}

func NewUpdateUserUseCase(uRepo ports.UserRepository) *UpdateUserUseCase {
	return &UpdateUserUseCase{
		userRepo: uRepo,
	}
}

func (uc *UpdateUserUseCase) Execute(ctx context.Context, id, tenantID string, input dto.UpdateUserRequest) (*dto.UserResponse, error) {
	// 1. Find User
	user, err := uc.userRepo.FindByID(ctx, id)
	if err != nil {
		return nil, err
	}
	if user == nil {
		return nil, errors.New("user not found")
	}

	// 2. Check Permission (Tenant Check)
	// If tenantID is empty, it means SuperAdmin or Admin (handler logic), so we skip check.
	if tenantID != "" && user.TenantID != tenantID {
		return nil, errors.New("forbidden: user belongs to another tenant")
	}

	// 3. Update Fields
	if input.Name != nil {
		user.Name = *input.Name
	}
	if input.Email != nil {
		user.Email = *input.Email
	}
	if input.Phone != nil {
		user.Phone = input.Phone
	}
	if input.Bio != nil {
		user.Bio = input.Bio
	}
	if input.Status != nil {
		user.Status = *input.Status
	} else if input.Active != nil {
		if *input.Active {
			user.Status = "active"
		} else {
			user.Status = "inactive"
		}
	}

	if input.Roles != nil {
		user.Roles = []entity.Role{}
		for _, r := range *input.Roles {
			user.Roles = append(user.Roles, entity.Role{Name: r})
		}
	}
	if input.AvatarUrl != nil {
		user.AvatarUrl = *input.AvatarUrl
	}

	// 4. Save
	updated, err := uc.userRepo.Update(ctx, user)
	if err != nil {
		return nil, err
	}

	// 5. Convert to Response
	roles := make([]string, len(updated.Roles))
	for i, r := range updated.Roles {
		roles[i] = r.Name
	}

	return &dto.UserResponse{
		ID:        updated.ID,
		Name:      updated.Name,
		Email:     updated.Email,
		Roles:     roles,
		Status:    updated.Status,
		AvatarUrl: updated.AvatarUrl,
		Phone:     updated.Phone,
		Bio:       updated.Bio,
		CreatedAt: updated.CreatedAt,
	}, nil
}
