package entitymapping

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

// providerMapping has method to map provider entities to view models
type organizationMapping struct {
	mapper *Mapper
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationTypeEntitySlice(list []viewmodel.OrganizationType) (retVal []entity.OrganizationType) {
	retVal = make([]entity.OrganizationType, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationTypeEntity(item))
	}

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationEntitySlice(list []viewmodel.Organization) (retVal []entity.Organization) {
	retVal = make([]entity.Organization, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationEntity(item))
	}

	return retVal
}

func (mapping *organizationMapping) ToOrganizationEntity(model viewmodel.Organization) entity.Organization {
	return entity.Organization{
		ID:          model.ID,
		UUID:        model.UUID,
		Type:        mapping.ToOrganizationTypeEntity(model.Type),
		Name:        model.Name,
		Description: model.Description,
		ReferenceID: model.ReferenceID,
		ParentID:    model.ParentID,
		Main:        model.Main,
		Created:     model.Created,
		Updated:     model.Updated,
		Active:      model.Active,
		Blocked:     model.Blocked,
		Suspended:   model.Suspended,
		Author:      mapping.mapper.User.ToUserEntity(model.Author),
		LastEditor:  mapping.mapper.User.ToUserEntity(model.LastEditor),
		Contacts:    mapping.ToOrganizationContactEntitySlice(model.Contacts),
		Addresses:   mapping.ToOrganizationAddressEntitySlice(model.Addresses),
		ChildOrgs:   mapping.ToOrganizationEntitySlice(model.ChildOrgs),
		Parent:      mapping.ToOrganizationEntityPointer(model.Parent),
	}
}

func (mapping *organizationMapping) ToOrganizationEntityPointer(model *viewmodel.Organization) *entity.Organization {
	if model != nil {
		convertibleModel := *model
		convertibleEntity := mapping.ToOrganizationEntity(convertibleModel)
		return &convertibleEntity
	} else {
		return nil
	}
}

func (mapping *organizationMapping) ToOrganizationModelPointer(model *entity.Organization) *viewmodel.Organization {
	if model != nil {
		convertibleModel := *model
		convertibleEntity := mapping.ToOrganizationModel(convertibleModel)
		return &convertibleEntity
	} else {
		return nil
	}
}

func (mapping *organizationMapping) ToOrganizationTypeEntity(model viewmodel.OrganizationType) entity.OrganizationType {
	return entity.OrganizationType{
		ID:          model.ID,
		Name:        model.Name,
		Key:         model.Key,
		Description: model.Description,
		Created:     model.Created,
		Updated:     model.Updated,
	}
}

func (mapping *organizationMapping) ToOrganizationTypeModelSlice(list []entity.OrganizationType) (retVal []viewmodel.OrganizationType) {
	retVal = make([]viewmodel.OrganizationType, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationTypeModel(item))
	}

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationModelSlice(list []entity.Organization) (retVal []viewmodel.Organization) {
	retVal = make([]viewmodel.Organization, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationModel(item))
	}

	return retVal
}

func (mapping *organizationMapping) ToOrganizationModel(model entity.Organization) viewmodel.Organization {
	return viewmodel.Organization{
		ID:          model.ID,
		UUID:        model.UUID,
		Type:        mapping.ToOrganizationTypeModel(model.Type),
		Name:        model.Name,
		Description: model.Description,
		ReferenceID: model.ReferenceID,
		ParentID:    model.ParentID,
		Main:        model.Main,
		Created:     model.Created,
		Updated:     model.Updated,
		Active:      model.Active,
		Blocked:     model.Blocked,
		Suspended:   model.Suspended,
		Author:      mapping.mapper.User.ToUserModel(model.Author),
		LastEditor:  mapping.mapper.User.ToUserModel(model.LastEditor),
		Contacts:    mapping.ToOrganizationContactModelSlice(model.Contacts),
		Addresses:   mapping.ToOrganizationAddressModelSlice(model.Addresses),
		ChildOrgs:   mapping.ToOrganizationModelSlice(model.ChildOrgs),
		Parent:      mapping.ToOrganizationModelPointer(model.Parent),
	}
}

func (mapping *organizationMapping) ToOrganizationTypeModel(model entity.OrganizationType) viewmodel.OrganizationType {
	return viewmodel.OrganizationType{
		ID:          model.ID,
		Name:        model.Name,
		Key:         model.Key,
		Description: model.Description,
		Created:     model.Created,
		Updated:     model.Updated,
	}
}

func (mapping *organizationMapping) ToOrganizationContactModel(model entity.OrganizationContact) viewmodel.OrganizationContact {
	return viewmodel.OrganizationContact{
		ID:          model.ID,
		UUID:        model.UUID,
		Type:        mapping.mapper.User.ToContactTypeModel(model.Type),
		Contact:     model.Contact,
		Name:        model.Name,
		Description: model.Description,
		Created:     model.Created,
		CreatedUser: mapping.mapper.User.ToUserModel(model.CreatedUser),
		Updated:     model.Updated,
		UpdatedUser: mapping.mapper.User.ToUserModel(model.UpdatedUser),
		Active:      model.Active,
	}
}

func (mapping *organizationMapping) ToOrganizationContactEntity(model viewmodel.OrganizationContact) entity.OrganizationContact {
	return entity.OrganizationContact{
		ID:          model.ID,
		UUID:        model.UUID,
		Type:        mapping.mapper.User.ToContactTypeEntity(model.Type),
		Contact:     model.Contact,
		Name:        model.Name,
		Description: model.Description,
		Created:     model.Created,
		CreatedUser: mapping.mapper.User.ToUserEntity(model.CreatedUser),
		Updated:     model.Updated,
		UpdatedUser: mapping.mapper.User.ToUserEntity(model.UpdatedUser),
		Active:      model.Active,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationContactModelSlice(list []entity.OrganizationContact) (retVal []viewmodel.OrganizationContact) {
	retVal = make([]viewmodel.OrganizationContact, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationContactModel(item))
	}

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationContactEntitySlice(list []viewmodel.OrganizationContact) (retVal []entity.OrganizationContact) {
	retVal = make([]entity.OrganizationContact, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationContactEntity(item))
	}

	return retVal
}

func (mapping *organizationMapping) ToOrganizationAddressModel(model entity.OrganizationAddress) viewmodel.OrganizationAddress {
	return viewmodel.OrganizationAddress{
		ID:          model.ID,
		UUID:        model.UUID,
		InternalID:  model.InternalID,
		Address:     model.Address,
		Name:        model.Name,
		Description: model.Description,
		Latitude:    model.Latitude,
		Longitude:   model.Longitude,
		Created:     model.Created,
		CreatedUser: mapping.mapper.User.ToUserModel(model.CreatedUser),
		Updated:     model.Updated,
		UpdatedUser: mapping.mapper.User.ToUserModel(model.UpdatedUser),
		Active:      model.Active,
	}
}

func (mapping *organizationMapping) ToOrganizationAddressEntity(model viewmodel.OrganizationAddress) entity.OrganizationAddress {
	return entity.OrganizationAddress{
		ID:          model.ID,
		UUID:        model.UUID,
		InternalID:  model.InternalID,
		Address:     model.Address,
		Name:        model.Name,
		Description: model.Description,
		Latitude:    model.Latitude,
		Longitude:   model.Longitude,
		Created:     model.Created,
		CreatedUser: mapping.mapper.User.ToUserEntity(model.CreatedUser),
		Updated:     model.Updated,
		UpdatedUser: mapping.mapper.User.ToUserEntity(model.UpdatedUser),
		Active:      model.Active,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationAddressModelSlice(list []entity.OrganizationAddress) (retVal []viewmodel.OrganizationAddress) {
	retVal = make([]viewmodel.OrganizationAddress, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationAddressModel(item))
	}

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *organizationMapping) ToOrganizationAddressEntitySlice(list []viewmodel.OrganizationAddress) (retVal []entity.OrganizationAddress) {
	retVal = make([]entity.OrganizationAddress, 0)

	for _, item := range list {
		retVal = append(retVal, mapping.ToOrganizationAddressEntity(item))
	}

	return retVal
}
