package repository

import (
	"context"

	dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db"
	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
	"github.com/jackc/pgx/v5/pgtype"
)

func convertDBTransfer(transfer dbgen.WalletTransfer) domain.Transfer {
	return domain.Transfer{
		ID:               transfer.ID,
		Amount:           domain.Currency(transfer.Amount.Int64),
		Type:             domain.TransferType(transfer.Type.String),
		Verified:         transfer.Verified.Bool,
		ReceiverWalletID: transfer.ReceiverWalletID.Int64,
		SenderWalletID:   transfer.SenderWalletID.Int64,
		CashierID: domain.ValidInt64{
			Value: transfer.CashierID.Int64,
			Valid: transfer.CashierID.Valid,
		},
		PaymentMethod: domain.PaymentMethod(transfer.PaymentMethod.String),
	}
}

func convertCreateTransfer(transfer domain.CreateTransfer) dbgen.CreateTransferParams {
	return dbgen.CreateTransferParams{
		Amount: pgtype.Int8{Int64: int64(transfer.Amount), Valid: true},
		Type:   pgtype.Text{String: string(transfer.Type), Valid: true},
		ReceiverWalletID: pgtype.Int8{
			Int64: transfer.ReceiverWalletID,
			Valid: true,
		},
		SenderWalletID: pgtype.Int8{
			Int64: transfer.SenderWalletID,
			Valid: true,
		},
		CashierID: pgtype.Int8{
			Int64: transfer.CashierID.Value,
			Valid: transfer.CashierID.Valid,
		},
		PaymentMethod: pgtype.Text{String: string(transfer.PaymentMethod), Valid: true},
	}
}

func (s *Store) CreateTransfer(ctx context.Context, transfer domain.CreateTransfer) (domain.Transfer, error) {
	newTransfer, err := s.queries.CreateTransfer(ctx, convertCreateTransfer(transfer))
	if err != nil {
		return domain.Transfer{}, err
	}
	return convertDBTransfer(newTransfer), nil
}

func (s *Store) GetAllTransfers(ctx context.Context) ([]domain.Transfer, error) {
	transfers, err := s.queries.GetAllTransfers(ctx)
	if err != nil {
		return nil, err
	}
	var result []domain.Transfer = make([]domain.Transfer, 0, len(transfers))

	for _, transfer := range transfers {
		result = append(result, convertDBTransfer(transfer))
	}
	return result, nil
}
func (s *Store) GetTransfersByWallet(ctx context.Context, walletID int64) ([]domain.Transfer, error) {
	transfers, err := s.queries.GetTransfersByWallet(ctx, pgtype.Int8{Int64: walletID, Valid: true})
	if err != nil {
		return nil, err
	}

	var result []domain.Transfer = make([]domain.Transfer, 0, len(transfers))

	for _, transfer := range transfers {
		result = append(result, convertDBTransfer(transfer))
	}
	return result, nil
}

func (s *Store) GetTransferByReference(ctx context.Context, reference string) (domain.Transfer, error) {
	transfer, err := s.queries.GetTransferByReference(ctx, pgtype.Text{String: reference, Valid: true})
	if err != nil {
		return domain.Transfer{}, nil
	}
	return convertDBTransfer(transfer), nil
}

func (s *Store) GetTransferByID(ctx context.Context, id int64) (domain.Transfer, error) {
	transfer, err := s.queries.GetTransferByID(ctx, id)
	if err != nil {
		return domain.Transfer{}, nil
	}
	return convertDBTransfer(transfer), nil
}

func (s *Store) UpdateTransferVerification(ctx context.Context, id int64, verified bool) error {
	err := s.queries.UpdateTransferVerification(ctx, dbgen.UpdateTransferVerificationParams{
		ID:       id,
		Verified: pgtype.Bool{Bool: verified, Valid: true},
	})

	return err
}

func (s *Store) UpdateTransferStatus(ctx context.Context, id int64, status string) error {
	err := s.queries.UpdateTransferStatus(ctx, dbgen.UpdateTransferStatusParams{
		ID:     id,
		Status: pgtype.Text{String: status, Valid: true},
	})

	return err
}
