package repositories_astrologer

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

type WalletRepository interface {

	//------------------------------------------------
	// Astrologer
	//------------------------------------------------

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

	//------------------------------------------------
	// Wallet
	//------------------------------------------------

	GetWallet(userID uint) (*models.UserWallet, error)

	CreateWallet(wallet *models.UserWallet) error

	UpdateWallet(wallet *models.UserWallet) error

	//------------------------------------------------
	// Wallet Summary
	//------------------------------------------------

	GetAvailableBalance(userID uint) (float64, error)

	GetLastThreeMonthEarnings(astrologerID uint) (float64, error)

	GetMonthlyEarnings(astrologerID uint) (float64, error)

	GetWeeklyEarnings(astrologerID uint) (float64, error)

	GetPendingEarnings(astrologerID uint) (float64, error)

	GetTodayAstromallEarnings(astrologerID uint) (float64, error)

	GetPayableAmount(astrologerID uint) (float64, error)

	GetRank(astrologerID uint) (int, error)

	//------------------------------------------------
	// Transactions
	//------------------------------------------------

	GetTransactions(
		astrologerID uint,
		filter string,
		page int,
		limit int,
	) ([]dto.WalletTransactionResponse, int64, error)

	GetTransactionByID(id uint, astrologer_id uint) (*models.WalletLedger, error)

	CreateTransaction(transaction *models.WalletLedger) error

	//------------------------------------------------
	// Ledger
	//------------------------------------------------

	GetWalletLedger(astrologerID uint) ([]models.WalletLedger, error)

	CreateLedger(ledger *models.WalletLedger) error

	//------------------------------------------------
	// Withdraw
	//------------------------------------------------

	CreateWithdrawRequest(req *models.WalletWithdrawRequest) error

	UpdateWithdrawRequest(req *models.WalletWithdrawRequest) error

	GetWithdrawRequest(id uint) (*models.WalletWithdrawRequest, error)

	GetWithdrawHistory(astrologerID uint) ([]models.WalletWithdrawRequest, error)

	// GetPendingWithdrawRequest returns the open request that blocks a new
	// one, or nil when there is none.
	GetPendingWithdrawRequest(astrologerID uint, withdrawType string) (*models.WalletWithdrawRequest, error)

	// CreateWithdrawWithLedger writes the request, its ledger entry, the
	// settlement row for an instant payout and the debited wallet balance in
	// one transaction. Settlement may be nil for a general withdrawal, which
	// settles only once an admin approves it.
	CreateWithdrawWithLedger(
		withdraw *models.WalletWithdrawRequest,
		ledger *models.WalletLedger,
		settlement *models.WalletSettlement,
		walletID uint,
		debit float64,
		modifiedBy uint,
	) error

	//------------------------------------------------
	// Payout Details
	//------------------------------------------------

	GetBankAccountByAstrologerID(astrologerID uint) (*models.AstrologerBankAccount, error)

	//------------------------------------------------
	// Configuration
	//------------------------------------------------

	// GetSystemFlagFloat reads a numeric systemflag. A missing or unparsable
	// row yields the fallback rather than an error, so the withdraw flow keeps
	// working before the configuration migration has been applied.
	GetSystemFlagFloat(name string, fallback float64) float64

	// GetSystemFlagString is the same for the textual flags — the settlement
	// frequency and run time.
	GetSystemFlagString(name string, fallback string) string

	//------------------------------------------------
	// Settlement
	//------------------------------------------------

	// GetSettlementHistory lists the consultation settlement batches credited
	// to this astrologer. Withdraw payout rows share the table and are
	// excluded — they belong to the withdraw history.
	GetSettlementHistory(astrologerID uint) ([]models.WalletSettlement, error)

	// ListConsultationEarnings is every billed session at any settlement
	// status, with totals across the whole filtered set.
	//
	// This is what an astrologer's earnings screen reads. GetSettlementHistory
	// above lists credited BATCHES, which do not exist until an admin has
	// approved sessions and the settlement job has run — so it is empty, and
	// correctly so, for as long as that takes.
	ListConsultationEarnings(
		astrologerID uint,
		status string,
		medium string,
		page int,
		limit int,
	) ([]models.Consultation, int64, map[string]float64, error)

	// GetSettlementBatches is the paginated form, with the all-time credited
	// total for the screen header.
	GetSettlementBatches(
		astrologerID uint,
		page int,
		limit int,
	) ([]models.WalletSettlement, int64, float64, error)

	GetSettlementBatch(astrologerID uint, settlementID uint) (*models.WalletSettlement, error)

	// GetSettlementConsultations lists the sessions one batch closed.
	GetSettlementConsultations(
		astrologerID uint,
		settlementID uint,
	) ([]models.Consultation, error)

	// GetUnsettledConsultations lists everything billed to a customer that
	// has not reached the wallet yet — PENDING, TO_BE_SETTLED and ON_HOLD.
	GetUnsettledConsultations(astrologerID uint) ([]models.Consultation, error)

	CreateSettlement(settlement *models.WalletSettlement) error
}
