package service

import (
	"bitbucket.org/nemt/nemt-portal-api/domain/entity"
)

// userService is the domain service for user operations
type organizationService struct {
	svc *Service
}

// newUserService returns an instance of userService
func newOrganizationService(svc *Service) *organizationService {
	return &organizationService{
		svc: svc,
	}
}

func (s *organizationService) GetAllTypes() ([]entity.OrganizationType, error) {
	return s.svc.db.Organization().GetAllTypes()
}

func (s *organizationService) GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error) {
	return s.svc.db.Organization().GetByType(organizationTypeKey, user)
}

func (s *organizationService) GetByName(name string, searchType string, user entity.User) ([]entity.Organization, error) {
	return s.svc.db.Organization().GetByName(name, searchType, user)
}

func (s *organizationService) GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error) {
	return s.svc.db.Organization().GetByTypeAndReferenceID(typeKey, referenceID, user)
}

func (s *organizationService) GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error) {
	organization, err := s.svc.db.Organization().GetByUUID(organizationUUID, user)
	if err != nil {
		return organization, err
	}

	organization.Contacts, err = s.GetContactsByOrganizationID(organization.ID)
	if err != nil {
		return organization, err
	}

	organization.Addresses, err = s.GetAddressByOrganizationID(organization.ID)
	if err != nil {
		return organization, err
	}

	organization.ChildOrgs, err = s.svc.db.Organization().GetChildsByID(organization.ID, user)
	if err != nil {
		return organization, err
	}

	if organization.ParentID > 0 {
		parent, err := s.svc.db.Organization().GetByID(organization.ParentID, user)
		if err != nil {
			return organization, err
		}
		organization.Parent = &parent
	}

	return organization, nil
}

func (s *organizationService) SetParentOrganization(organizationID int64, parentOrganizationID int64) error {
	return s.svc.db.Organization().SetParentOrganization(organizationID, parentOrganizationID)
}

func (s *organizationService) GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error) {
	return s.svc.db.Organization().GetContactsByOrganizationUUID(organizationUUID)
}

func (s *organizationService) GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error) {
	return s.svc.db.Organization().GetContactsByOrganizationID(organizationID)
}

func (s *organizationService) GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error) {
	return s.svc.db.Organization().GetContactsByUUID(contactUUID)
}

func (s *organizationService) GetAddressByOrganizationUUID(organizationUUID string) ([]entity.OrganizationAddress, error) {
	return s.svc.db.Organization().GetAddressByOrganizationUUID(organizationUUID)
}

func (s *organizationService) GetAddressByOrganizationID(organizationID int64) ([]entity.OrganizationAddress, error) {
	return s.svc.db.Organization().GetAddressByOrganizationID(organizationID)
}

func (s *organizationService) GetAddressByUUID(contactUUID string) (entity.OrganizationAddress, error) {
	return s.svc.db.Organization().GetAddressByUUID(contactUUID)
}

func (s *organizationService) InactivateOrganizationAddress(address entity.OrganizationAddress, user entity.User) error {
	return s.svc.db.Organization().InactivateOrganizationAddress(address, user)
}

func (s *organizationService) SetOrganizationAddress(address entity.OrganizationAddress, user entity.User) (entity.OrganizationAddress, error) {
	return s.svc.db.Organization().SetOrganizationAddress(address, user)
}

func (s *organizationService) InactivateOrganizationContact(contact entity.OrganizationContact, user entity.User) error {
	return s.svc.db.Organization().InactivateOrganizationContact(contact, user)
}

func (s *organizationService) SetOrganizationContact(contact entity.OrganizationContact, user entity.User) (entity.OrganizationContact, error) {
	return s.svc.db.Organization().SetOrganizationContact(contact, user)
}

func (s *organizationService) AddOrganization(organization entity.Organization, user entity.User) (entity.Organization, error) {
	return s.svc.db.Organization().AddOrganization(organization, user)
}

func (s *organizationService) GetTypeByKey(key string) (entity.OrganizationType, error) {
	return s.svc.db.Organization().GetTypeByKey(key)
}
