package contract

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

type repoManager interface {
	Users() UserRepo
	Rides() RideRepo
	Visits() VisitRepo
	Provider() ProviderRepo
	Notification() NotificationRepo
	Profile() ProfileRepo
	Organization() OrganizationRepo
	Zipcodes() ZipcodeRepo
	Plans() PlanRepo
	PasswordReset() PasswordResetRepo
}

// UserRepo defines the data set for users
type UserRepo interface {
	GetAll() (list []entity.User, err error)
	GetByID(userID int64) (retVal entity.User, err error)
	GetByUUID(uuid string, profile string) (entity.User, error)
	GetByMemberID(memberID string) (entity.User, error)
	GetByEmail(email string) (entity.User, error)
	Login(email string, pass string) (entity.User, error)
	FullLogin(loginType string, key string, pass string, profile string) (entity.User, error)
	Create(user entity.User) (entity.User, error)
	GetUsersByProfile(profile string) ([]entity.User, error)
	SaveAddress(address entity.Address) (entity.Address, error)
	GetAddressByUUID(addressUUID string) (entity.Address, error)
	GetContactType() (retVal []entity.ContactType, err error)
	RemoveAddress(addressUUID string) error
	SaveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
	RemoveContact(contact entity.ContactInfo) (entity.ContactInfo, error)
	UpdateLogin(user entity.User) error
}

// RideRepo defines the data set for Rides
type RideRepo interface {
	Save(ride entity.Ride) (entity.Ride, error)
	GetAll(user entity.User) ([]entity.Ride, error)
	GetByID(id int64, user entity.User) (entity.Ride, error)
	GetByUUID(uuid string, user entity.User) (entity.Ride, error)
	GetByInternalID(internalID string) (entity.Ride, error)
	GetByUserID(userID int64, user entity.User) ([]entity.Ride, error)
	GetByUserUUID(userUUID string, user entity.User) ([]entity.Ride, error)
	GetByUUIDAndUserUUID(UUID string, userUUID string) (entity.Ride, error)
	UpdateStatus(rideUUID string, status string) error
	Update(hook entity.WebhookResponse, user entity.User) (entity.Ride, error)
	GetLastRideByPhoneNumber(phoneNumber string) (entity.Ride, error)
	GetLastRideByDriversNumber(phoneNumber string) (entity.Ride, error)
	GetByInternalPassengerID(internalPassengerID string) (entity.Ride, error)
	GetByVisitUUID(visitUUID string, user entity.User) ([]entity.Ride, error)
	GetByVisitUUIDAndTripType(visitUUID string, tripTypeKey string, user entity.User) (entity.Ride, error)
}

// ProviderRepo defines the data set for Provider
type ProviderRepo interface {
	Save(providers []entity.ProviderResponse, user entity.User) ([]entity.Provider, error)
	GetAll(user entity.User) ([]entity.Provider, error)
	Get(query string, lat float64, long float64, distance int64, planCode string, productID string, mukID string, internalID string, sort string, user entity.User) ([]entity.Provider, error)
	GetByMukID(mukID string, user entity.User) (entity.Provider, error)
	GetByUUID(providerUUID string, user entity.User) (entity.Provider, error)
	GetByNPI(NPI string, user entity.User) (entity.Provider, error)
	GetByID(providerID int64, user entity.User) (entity.Provider, error)
}

// NotificationRepo defines the data set for Notification
type NotificationRepo interface {
	Create(notification entity.Notification) (entity.Notification, error)
	GetByUserUUIDAndReadStatus(userUUID string, status string, isRead bool) ([]entity.Notification, error)
	GetByUserUUID(userUUID string, status string) ([]entity.Notification, error)
	ReadStatus(notificationUUID string, readed bool) error
	GetLastNotificationFromPhoneNumber(notificationType string, phoneNumber string, status string) (entity.Notification, error)
}

// ProviderRepo defines the data set for Rides
type OrganizationRepo interface {
	GetAllTypes() ([]entity.OrganizationType, error)
	GetByType(organizationTypeKey string, user entity.User) ([]entity.Organization, error)
	GetByUUID(organizationUUID string, user entity.User) (entity.Organization, error)
	GetByTypeAndReferenceID(typeKey string, referenceID int64, user entity.User) (entity.Organization, error)
	GetContactsByOrganizationUUID(organizationUUID string) ([]entity.OrganizationContact, error)
	GetContactsByOrganizationID(organizationID int64) ([]entity.OrganizationContact, error)
	GetContactsByUUID(contactUUID string) (entity.OrganizationContact, error)
	GetAddressByOrganizationUUID(organizationUUID string) ([]entity.OrganizationAddress, error)
	GetAddressByOrganizationID(organizationID int64) ([]entity.OrganizationAddress, error)
	GetAddressByUUID(contactUUID string) (entity.OrganizationAddress, error)
	GetByID(organizationID int64, user entity.User) (entity.Organization, error)
	GetChildsByID(organizationID int64, user entity.User) ([]entity.Organization, error)
	GetByName(name string, searchType string, user entity.User) ([]entity.Organization, error)
	SetParentOrganization(organizationID int64, parentOrganizationID int64) error
	InactivateOrganizationAddress(address entity.OrganizationAddress, user entity.User) error
	SetOrganizationAddress(address entity.OrganizationAddress, user entity.User) (entity.OrganizationAddress, error)
	InactivateOrganizationContact(contact entity.OrganizationContact, user entity.User) error
	SetOrganizationContact(contact entity.OrganizationContact, user entity.User) (entity.OrganizationContact, error)
	AddOrganization(organization entity.Organization, user entity.User) (entity.Organization, error)
	GetTypeByKey(key string) (entity.OrganizationType, error)
}

type PlanRepo interface {
	GetByAlphaPrefix(alphaPrefix string) (entity.Plan, error)
	GetByUUID(planUUID string) ([]entity.Plan, error)
	GetByID(planID int64) ([]entity.Plan, error)
	GetByPrefixUUID(prefixUUID string) (entity.Plan, error)
}

// VisitRepo defines the data set for Rides
type VisitRepo interface {
	Create(visit entity.Visit) (entity.Visit, error)
	GetAll(user entity.User) ([]entity.Visit, error)
	GetByUUID(visitUUID string, user entity.User) (entity.Visit, error)
	GetByID(visitID int64, user entity.User) (entity.Visit, error)
}

type ProfileRepo interface {
	GetAll() ([]entity.Profile, error)
	GetByKey(key string) (entity.Profile, error)
	GetVisibles(visible bool) ([]entity.Profile, error)
	GetByOrganizationType(organizationTypeID int64) ([]entity.Profile, error)
}

type ZipcodeRepo interface {
	GetAll() ([]entity.Zipcode, error)
	GetByParticipatingZipcode(zipcode string) (entity.Zipcode, error)
}

type PasswordResetRepo interface {
	GetAll() ([]entity.PasswordReset, error)
	CreatePasswordResetEntry(passwordResetEntry entity.PasswordReset) (entity.PasswordReset, error)
	GetByID(ID int64) (entity.PasswordReset, error)
	GetByToken(token string) (entity.PasswordReset, error)
	SetTokenOpened(token string) error
	SetTokenUsed(token string) error
}
