package entitymapping

import (
	"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/entity"
)

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

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderRespEntitySlice(list []viewmodel.ProviderResp) (retVal []entity.Provider) {
	retVal = make([]entity.Provider, 0)

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

	return retVal
}

func (mapping *providerMapping) ToProviderRespEntity(item viewmodel.ProviderResp) entity.Provider {
	return entity.Provider{
		ProviderUUID:      item.ProviderUUID,
		InternalID:        item.InternalID,
		InternalSuffixID:  item.InternalSuffixID,
		MukID:             item.MukID,
		OrganizatioName:   item.OrganizatioName,
		Gender:            item.Gender,
		AcceptNewPatients: item.AcceptNewPatients,
		Name:              item.Name,
		FirstName:         item.FirstName,
		MiddleName:        item.MiddleName,
		LastName:          item.LastName,
		Title:             item.Title,
		Distance:          item.Distance,
		Organization:      mapping.mapper.Organization.ToOrganizationEntity(item.Organization),
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderRespModelSlice(list []entity.Provider) (retVal []viewmodel.ProviderResp) {
	retVal = make([]viewmodel.ProviderResp, 0)

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

	return retVal
}

func (mapping *providerMapping) ToProviderRespModel(item entity.Provider) viewmodel.ProviderResp {
	return viewmodel.ProviderResp{
		ProviderUUID:      item.ProviderUUID,
		InternalID:        item.InternalID,
		InternalSuffixID:  item.InternalSuffixID,
		MukID:             item.MukID,
		OrganizatioName:   item.OrganizatioName,
		Gender:            item.Gender,
		AcceptNewPatients: item.AcceptNewPatients,
		Name:              item.Name,
		FirstName:         item.FirstName,
		MiddleName:        item.MiddleName,
		LastName:          item.LastName,
		Title:             item.Title,
		Keys:              mapping.ToProviderKeyModelSlice(item.Keys),
		Address:           mapping.ToProviderRespAddressModel(item.Address),
		Distance:          item.Distance,
		Organization:      mapping.mapper.Organization.ToOrganizationModel(item.Organization),
	}
}

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

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

	return retVal
}

func (mapping *providerMapping) ToProviderKeyModel(item entity.ProviderKey) viewmodel.ProviderKey {
	return viewmodel.ProviderKey{
		InternalID:            item.InternalID,
		InternalSuffixID:      item.InternalSuffixID,
		LocationSeqNumber:     item.LocationSeqNumber,
		PlanCode:              item.PlanCode,
		ProductID:             item.ProductID,
		TreatmentCategoryCode: item.TreatmentCategoryCode,
	}
}

func (mapping *providerMapping) ToProviderRespAddressModel(item entity.ProviderAddress) viewmodel.ProviderAddress {
	return viewmodel.ProviderAddress{
		StreetAddress1: item.StreetAddress1,
		StreetAddress2: item.StreetAddress2,
		CityName:       item.CityName,
		State:          item.State,
		ZipCode:        item.ZipCode,
		Country:        item.Country,
		Latitude:       item.Latitude,
		Longitude:      item.Longitude,
		PhoneNumber:    item.PhoneNumber,
	}
}

func (mapping *providerMapping) ToProviderEntity(item npdmodel.ProviderResponse) entity.ProviderResponse {
	return entity.ProviderResponse{
		MukID:                     item.MukID,
		FivePartKeyGroups:         mapping.ToPartKeyGroupEntitySlice(item.FivePartKeyGroups),
		OrgName:                   item.OrgName,
		Gender:                    item.Gender,
		AcceptNewPatients:         item.AcceptNewPatients,
		ProviderName:              item.ProviderName,
		FirstName:                 item.FirstName,
		LastName:                  item.LastName,
		MiddleName:                item.MiddleName,
		ProviderTitle:             item.ProviderTitle,
		StreetName1:               item.StreetName1,
		StreetName2:               item.StreetName2,
		CityName:                  item.CityName,
		State:                     item.State,
		ZipCode:                   item.ZipCode,
		Country:                   item.Country,
		Latitude:                  item.Latitude,
		Longitude:                 item.Longitude,
		PhoneNumber:               item.PhoneNumber,
		ProviderEntityName:        item.ProviderEntityName,
		ProviderEntityCode:        item.ProviderEntityCode,
		ProviderTypeCode:          mapping.ToProviderTypeCodeEntitySlice(item.ProviderTypeCode),
		Distance:                  item.Distance,
		AvailabilityOfCost:        item.AvailabilityOfCost,
		TDDPhoneNumber:            item.TDDPhoneNumber,
		ExtendedOfficeHours:       item.ExtendedOfficeHours,
		ProviderCountyCode:        item.ProviderCountyCode,
		ProviderCountyName:        item.ProviderCountyName,
		HospitalAffiliationNames:  mapping.ToHospitalAffiliationNamesEntitySlice(item.HospitalAffiliationNames),
		ProviderAffiliationNumber: item.ProviderAffiliationNumber,
		ProviderAffiliationName:   item.ProviderAffiliationName,
		LanguagesSpoken:           mapping.ToLanguagesEntitySlice(item.LanguagesSpoken),
		OfficeLanguagesSpoken:     mapping.ToLanguagesEntitySlice(item.OfficeLanguagesSpoken),
		MedSchool:                 item.MedSchool,
		MedSchoolYear:             item.MedSchoolYear,
		Internship:                item.Internship,
		Residence:                 item.Residence,
		Specialty1:                item.Specialty1,
		Specialty2:                item.Specialty2,
		Specialty3:                item.Specialty3,
		Specialty4:                item.Specialty4,
		Certification1:            item.Certification1,
		Certification2:            item.Certification2,
		Certification3:            item.Certification3,
		Certification4:            item.Certification4,
	}
}

func (mapping *providerMapping) ToProviderModel(item entity.ProviderResponse) npdmodel.ProviderResponse {
	return npdmodel.ProviderResponse{
		MukID:                     item.MukID,
		FivePartKeyGroups:         mapping.ToPartKeyGroupModelSlice(item.FivePartKeyGroups),
		OrgName:                   item.OrgName,
		Gender:                    item.Gender,
		AcceptNewPatients:         item.AcceptNewPatients,
		ProviderName:              item.ProviderName,
		FirstName:                 item.FirstName,
		LastName:                  item.LastName,
		MiddleName:                item.MiddleName,
		ProviderTitle:             item.ProviderTitle,
		StreetName1:               item.StreetName1,
		StreetName2:               item.StreetName2,
		CityName:                  item.CityName,
		State:                     item.State,
		ZipCode:                   item.ZipCode,
		Country:                   item.Country,
		Latitude:                  item.Latitude,
		Longitude:                 item.Longitude,
		PhoneNumber:               item.PhoneNumber,
		ProviderEntityName:        item.ProviderEntityName,
		ProviderEntityCode:        item.ProviderEntityCode,
		ProviderTypeCode:          mapping.ToProviderTypeCodeModelSlice(item.ProviderTypeCode),
		Distance:                  item.Distance,
		AvailabilityOfCost:        item.AvailabilityOfCost,
		TDDPhoneNumber:            item.TDDPhoneNumber,
		ExtendedOfficeHours:       item.ExtendedOfficeHours,
		ProviderCountyCode:        item.ProviderCountyCode,
		ProviderCountyName:        item.ProviderCountyName,
		HospitalAffiliationNames:  mapping.ToHospitalAffiliationNamesModelSlice(item.HospitalAffiliationNames),
		ProviderAffiliationNumber: item.ProviderAffiliationNumber,
		ProviderAffiliationName:   item.ProviderAffiliationName,
		LanguagesSpoken:           mapping.ToLanguagesModelSlice(item.LanguagesSpoken),
		OfficeLanguagesSpoken:     mapping.ToLanguagesModelSlice(item.OfficeLanguagesSpoken),
		MedSchool:                 item.MedSchool,
		MedSchoolYear:             item.MedSchoolYear,
		Internship:                item.Internship,
		Residence:                 item.Residence,
		Specialty1:                item.Specialty1,
		Specialty2:                item.Specialty2,
		Specialty3:                item.Specialty3,
		Specialty4:                item.Specialty4,
		Certification1:            item.Certification1,
		Certification2:            item.Certification2,
		Certification3:            item.Certification3,
		Certification4:            item.Certification4}
}

func (mapping *providerMapping) ToHospitalAffiliationNamesEntity(item npdmodel.HospitalAffiliationNames) entity.HospitalAffiliationNames {
	return entity.HospitalAffiliationNames{
		HospAffProvOrgName: item.HospAffProvOrgName,
	}
}

func (mapping *providerMapping) ToHospitalAffiliationNamesModel(item entity.HospitalAffiliationNames) npdmodel.HospitalAffiliationNames {
	return npdmodel.HospitalAffiliationNames{
		HospAffProvOrgName: item.HospAffProvOrgName,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToHospitalAffiliationNamesEntitySlice(list []npdmodel.HospitalAffiliationNames) (retVal []entity.HospitalAffiliationNames) {
	retVal = make([]entity.HospitalAffiliationNames, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToHospitalAffiliationNamesModelSlice(list []entity.HospitalAffiliationNames) (retVal []npdmodel.HospitalAffiliationNames) {
	retVal = make([]npdmodel.HospitalAffiliationNames, 0)

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

	return retVal
}

func (mapping *providerMapping) ToLanguagesEntity(item npdmodel.Languages) entity.Languages {
	return entity.Languages{
		Code: item.Code,
	}
}

func (mapping *providerMapping) ToLanguagesModel(item entity.Languages) npdmodel.Languages {
	return npdmodel.Languages{
		Code: item.Code,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToLanguagesEntitySlice(list []npdmodel.Languages) (retVal []entity.Languages) {
	retVal = make([]entity.Languages, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToLanguagesModelSlice(list []entity.Languages) (retVal []npdmodel.Languages) {
	retVal = make([]npdmodel.Languages, 0)

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

	return retVal
}

func (mapping *providerMapping) ToProviderTypeCodeEntity(item npdmodel.ProviderTypeCode) entity.ProviderTypeCode {
	return entity.ProviderTypeCode{
		Code: item.Code,
	}
}

func (mapping *providerMapping) ToProviderTypeCodeModel(item entity.ProviderTypeCode) npdmodel.ProviderTypeCode {
	return npdmodel.ProviderTypeCode{
		Code: item.Code,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderTypeCodeEntitySlice(list []npdmodel.ProviderTypeCode) (retVal []entity.ProviderTypeCode) {
	retVal = make([]entity.ProviderTypeCode, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderTypeCodeModelSlice(list []entity.ProviderTypeCode) (retVal []npdmodel.ProviderTypeCode) {
	retVal = make([]npdmodel.ProviderTypeCode, 0)

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

	return retVal
}

func (mapping *providerMapping) ToPartKeyGroupEntity(item npdmodel.PartKeyGroup) entity.PartKeyGroup {
	return entity.PartKeyGroup{
		ProviderNum:           item.ProviderNum,
		ProviderNumSuffix:     item.ProviderNumSuffix,
		LocationSeqNum:        item.LocationSeqNum,
		PlanCode:              item.PlanCode,
		ProductID:             item.ProductID,
		TreatmentCategoryCode: item.TreatmentCategoryCode,
	}
}

func (mapping *providerMapping) ToPartKeyGroupModel(item entity.PartKeyGroup) npdmodel.PartKeyGroup {
	return npdmodel.PartKeyGroup{
		ProviderNum:           item.ProviderNum,
		ProviderNumSuffix:     item.ProviderNumSuffix,
		LocationSeqNum:        item.LocationSeqNum,
		PlanCode:              item.PlanCode,
		ProductID:             item.ProductID,
		TreatmentCategoryCode: item.TreatmentCategoryCode,
	}
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToPartKeyGroupEntitySlice(list []npdmodel.PartKeyGroup) (retVal []entity.PartKeyGroup) {
	retVal = make([]entity.PartKeyGroup, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToPartKeyGroupModelSlice(list []entity.PartKeyGroup) (retVal []npdmodel.PartKeyGroup) {
	retVal = make([]npdmodel.PartKeyGroup, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderEntitySlice(list []npdmodel.ProviderResponse) (retVal []entity.ProviderResponse) {
	retVal = make([]entity.ProviderResponse, 0)

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

	return retVal
}

// ToUserEntitySlice maps a User entity slice to User view model slice
func (mapping *providerMapping) ToProviderModelSlice(list []entity.ProviderResponse) (retVal []npdmodel.ProviderResponse) {
	retVal = make([]npdmodel.ProviderResponse, 0)

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

	return retVal
}
