package finance

import (
	"context"
	"photum-backend/internal/db/generated"

	"github.com/jackc/pgx/v5/pgtype"
)

type Service struct {
	queries *generated.Queries
}

func NewService(queries *generated.Queries) *Service {
	return &Service{queries: queries}
}

func (s *Service) Create(ctx context.Context, params generated.CreateTransactionParams) (generated.FinancialTransaction, error) {
	txn, err := s.queries.CreateTransaction(ctx, params)
	if err != nil {
		return generated.FinancialTransaction{}, err
	}

	if params.FotID.Valid {
		_ = s.updateFotExpenses(ctx, params.FotID)
	}

	return txn, nil
}

func (s *Service) Update(ctx context.Context, params generated.UpdateTransactionParams) (generated.FinancialTransaction, error) {
	txn, err := s.queries.UpdateTransaction(ctx, params)
	if err != nil {
		return generated.FinancialTransaction{}, err
	}

	// Recalculate for the new FOT (if changed, we should technically recalc old one too, but simpler for now)
	if params.FotID.Valid {
		_ = s.updateFotExpenses(ctx, params.FotID)
	}
	return txn, nil
}

func (s *Service) Delete(ctx context.Context, id pgtype.UUID) error {
	// First fetch to get FotID
	txn, err := s.queries.GetTransaction(ctx, id)
	if err != nil {
		return err
	}

	err = s.queries.DeleteTransaction(ctx, id)
	if err != nil {
		return err
	}

	if txn.FotID.Valid {
		_ = s.updateFotExpenses(ctx, txn.FotID)
	}
	return nil
}

func (s *Service) ListByFot(ctx context.Context, fotID pgtype.UUID) ([]generated.FinancialTransaction, error) {
	return s.queries.ListTransactionsByFot(ctx, fotID)
}

func (s *Service) ListAll(ctx context.Context) ([]generated.ListTransactionsRow, error) {
	return s.queries.ListTransactions(ctx)
}

func (s *Service) AutoFillSearch(ctx context.Context, fotNumber int32) (generated.GetCadastroFotByFotJoinRow, error) {
	return s.queries.GetCadastroFotByFotJoin(ctx, fotNumber)
}

func (s *Service) ListFotEvents(ctx context.Context, fotID pgtype.UUID) ([]generated.ListAgendasByFotRow, error) {
	return s.queries.ListAgendasByFot(ctx, fotID)
}

func (s *Service) SearchProfessionals(ctx context.Context, query string) ([]generated.SearchProfissionaisRow, error) {
	return s.queries.SearchProfissionais(ctx, pgtype.Text{String: query, Valid: true})
}

func (s *Service) SearchProfessionalsByFunction(ctx context.Context, query string, functionName string) ([]generated.SearchProfissionaisByFunctionRow, error) {
	return s.queries.SearchProfissionaisByFunction(ctx, generated.SearchProfissionaisByFunctionParams{
		Column1: pgtype.Text{String: query, Valid: true}, // $1 - Name
		Nome:    functionName,                            // $2 - Function Name
	})
}

func (s *Service) GetStandardPrice(ctx context.Context, eventName string, serviceName string) (pgtype.Numeric, error) {
	// serviceName here is the Function Name (e.g. Fotógrafo)
	return s.queries.GetStandardPrice(ctx, generated.GetStandardPriceParams{
		Nome:   eventName,   // $1 - Event Name
		Nome_2: serviceName, // $2 - Function Name
	})
}

func (s *Service) SearchFot(ctx context.Context, query string) ([]generated.SearchFotRow, error) {
	return s.queries.SearchFot(ctx, pgtype.Text{String: query, Valid: true})
}

func (s *Service) updateFotExpenses(ctx context.Context, fotID pgtype.UUID) error {
	total, err := s.queries.SumTotalByFot(ctx, fotID)
	if err != nil {
		return err
	}

	return s.queries.UpdateCadastroFotGastos(ctx, generated.UpdateCadastroFotGastosParams{
		ID:             fotID,
		GastosCaptacao: total,
	})
}
