package applicationservice

import (
	"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
	"bitbucket.org/nemt/nemt-portal-api/application/third/npd/npdmodel"
	"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
	"bitbucket.org/nemt/nemt-portal-api/domain/service"
)

// providerService holds methods to provider application service
type providerService struct {
	svc       *service.Service
	mapEntity *entitymapping.Mapper
}

// newProviderService returns a providerService instance
func newProviderService(svc *service.Service, mapper *entitymapping.Mapper) *providerService {
	return &providerService{
		svc:       svc,
		mapEntity: mapper,
	}
}

func (s *providerService) Save(providers []npdmodel.ProviderResponse, user viewmodel.User) ([]viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	entities := s.mapEntity.Provider.ToProviderEntitySlice(providers)
	result, err := s.svc.Provider.Save(entities, eUser)
	if err != nil {
		return nil, err
	}
	return s.mapEntity.Provider.ToProviderRespModelSlice(result), nil
}

func (s *providerService) GetAll(user viewmodel.User) ([]viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	providers, err := s.svc.Provider.GetAll(eUser)
	if err != nil {
		return nil, err
	}
	return s.mapEntity.Provider.ToProviderRespModelSlice(providers), nil
}

func (s *providerService) Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user viewmodel.User) ([]viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	providers, err := s.svc.Provider.Get(query, lat, long, distance, planCode, productID, mukID, internalID, sort, eUser)
	if err != nil {
		return nil, err
	}
	return s.mapEntity.Provider.ToProviderRespModelSlice(providers), nil
}

func (s *providerService) GetByUUID(providerUUID string, user viewmodel.User) (viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	provider, err := s.svc.Provider.GetByUUID(providerUUID, eUser)
	if err != nil {
		return viewmodel.ProviderResp{}, err
	}

	return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}

func (s *providerService) GetByNPI(NPI string, user viewmodel.User) (viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	provider, err := s.svc.Provider.GetByNPI(NPI, eUser)
	if err != nil {
		return viewmodel.ProviderResp{}, err
	}

	return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}

func (s *providerService) GetByOrganization(organizationUUID string, user viewmodel.User) (viewmodel.ProviderResp, error) {
	eUser := s.mapEntity.User.ToUserEntity(user)
	provider, err := s.svc.Provider.GetByOrganization(organizationUUID, eUser)
	if err != nil {
		return viewmodel.ProviderResp{}, err
	}

	return s.mapEntity.Provider.ToProviderRespModel(provider), nil
}
