package repositories_astrologer

import (
	"astrology-api/dto_astrologer"
	models "astrology-api/models/astrologermodel"

	"gorm.io/gorm"
)

type AstrologerRepository interface {

	// Profile
	GetByUserID(userID uint) (*models.Astrologer, error)

	GetUserTableByID(userID uint) (*models.User, error)

	GetByID(id uint) (*models.Astrologer, error)

	Create(profile *models.Astrologer) error

	Update(profile *models.Astrologer) error

	UpdateUser(user *models.User) error

	// Languages
	GetMasterLanguages(userID uint) ([]dto_astrologer.LanguageMasterResponse, error)
	SaveLanguages(astrologerID uint, languageIDs []uint) error
	DeleteLanguages(astrologerID uint) error
	CreateLanguage(language *models.AstrologerLanguage) error

	// CreateLanguageTx / CreateSkillTx insert on a caller's transaction. The
	// non-Tx forms run on the base pool, which deadlocks against an uncommitted
	// DELETE on the same rows — see the comment on CreateSkillTx.
	CreateLanguageTx(tx *gorm.DB, language *models.AstrologerLanguage) error

	// Skills
	GetMasterSkills(userID uint) ([]dto_astrologer.SkillMasterResponse, error)
	SaveSkills(skills []models.AstrologerSkill) error
	DeleteSkills(astrologerID uint) error
	CreateSkill(skill *models.AstrologerSkill) error

	CreateSkillTx(tx *gorm.DB, skill *models.AstrologerSkill) error

	// Education
	SaveEducation(education *models.AstrologerEducation) error
	DeleteEducations(astrologerID uint) error
	CreateEducation(education *models.AstrologerEducation) error

	UpdateEducation(education *models.AstrologerEducation) error

	// Professional
	SaveProfessional(professional *models.AstrologerProfessional) error
	DeleteProfessionalByAstrologerID(tx *gorm.DB, astrologerID uint) error
	CreateProfessional(tx *gorm.DB, professional *models.AstrologerProfessional) error

	// Experience
	SaveExperience(exp *models.AstrologerExperience) error
	DeleteExperienceByAstrologerID(tx *gorm.DB, astrologerID uint) error
	CreateExperience(tx *gorm.DB, exp *models.AstrologerExperience) error

	// Bank
	SaveBankAccount(bank *models.AstrologerBank) error
	DeleteBankAccountByAstrologerID(tx *gorm.DB, astrologerID uint) error
	CreateBankAccount(tx *gorm.DB, bank *models.AstrologerBankAccount) error
	GetBankAccountByAstrologerID(astrologerID uint) (*models.AstrologerBankAccount, error)
	UpdateBankAccountRow(bank *models.AstrologerBankAccount) error

	// Documents
	GetMasterDocumentTypes() ([]models.MasterDocumentType, error)
	GetMasterDocumentType(masterType string, documentType string) (*models.MasterDocumentType, error)
	GetDocumentByAstrologerAndType(astrologerID uint, documentType string) (*models.AstrologerDocument, error)

	GetUploadedDocumentTypes(astrologerID uint) ([]string, error)

	SaveDocument(document *models.AstrologerDocument) error
	UpdateDocument(document *models.AstrologerDocument) error

	// Progress
	SaveProgress(tx *gorm.DB, progress *models.AstrologerProfileProgress) error

	UpdateProfileProgress(progress *models.AstrologerProfileProgress) error

	GetDeviceTypes() ([]models.DeviceType, error)

	GetWorkingHours() ([]models.WorkingHourMaster, error)

	DeleteAvailabilityByAstrologerID(tx *gorm.DB, astrologerID uint) error

	GetAvailableScheduleByAstrologerID(astrologerID uint) ([]models.AstrologerAvailability, error)

	CreateAvailability(tx *gorm.DB, availability *models.AstrologerAvailability) error

	GetSocialLinksByAstrologerID(astrologerID uint) (*models.AstrologerSocialLink, error)

	CreateSocialLinks(tx *gorm.DB, social *models.AstrologerSocialLink) error

	UpdateSocialLinks(tx *gorm.DB, social *models.AstrologerSocialLink) error

	UpdateAstrologer(tx *gorm.DB, astrologer *models.Astrologer) error
	UpdateAstrologerAvailablity(tx *gorm.DB, astrologer *models.Astrologer) error

	// Submit
	SubmitProfile(astrologerID uint) error

	// Verification
	CreateVerificationLog(tx *gorm.DB, log *models.AstrologerVerificationLog) error

	GetLanguagesByAstrologerID(astrologerID uint) ([]string, error)

	GetSkillsByAstrologerID(astrologerID uint) ([]string, error)

	GetProfileDetails(astrologerID uint) (*models.Astrologer, error)

	GetProfileProgress(userID uint) (*models.Astrologer, error)

	ChangeStatus(userID uint, status string) error

	DeleteAccount(userID uint) error

	GetProfileProgressByAstrologerID(astrologerID uint) (*models.AstrologerProfileProgress, error)

	GetProfileCompletionByAstrologerID(astrologerID uint) (*models.AstrologerProfileCompletion, error)

	CreateProfileCompletion(completion *models.AstrologerProfileCompletion) error

	UpdateProfileCompletion(completion *models.AstrologerProfileCompletion) error

	GetProgressByAstrologerID(astrologerID uint) (*models.AstrologerProgress, error)

	CreateProgress(progress *models.AstrologerProgress) error

	UpdateProgress(progress *models.AstrologerProgress) error

	CreateInterview(interview *models.AstrologerInterview) error

	GetInterviewByUserID(userID uint) (*models.AstrologerInterview, error)

	// PROFILE OPERATION

	UpdateBasicProfile(tx *gorm.DB, user *models.User, astrologer *models.Astrologer) error

	UpdateProfileImage(tx *gorm.DB, astrologerID uint, image string) error

	DeleteProfileImage(tx *gorm.DB, userID uint, astrologerID uint) error

	GetSkillByID(id uint) (*models.SkillMaster, error)

	DeleteSkillsByAstrologerID(tx *gorm.DB, astrologerID uint) error

	DeleteLanguagesByAstrologerID(tx *gorm.DB, astrologerID uint) error

	GetLanguageByID(id uint) (*models.Language, error)

	// FindExistingLanguageIDs returns the subset of ids that exist in the
	// languages master, in one query, so a selection can be checked before any
	// row is written instead of failing on the foreign key mid-insert.
	FindExistingLanguageIDs(ids []uint) ([]uint, error)

	DeleteEducationsByAstrologerID(tx *gorm.DB, astrologerID uint) error
}
