package services

import (
	"context"
	"fmt"

	"github.com/google/uuid"
	"backend/internal/models"
	"backend/internal/repository"
)

type TransactionService struct {
	repo *repository.TransactionRepository
}

func NewTransactionService(repo *repository.TransactionRepository) *TransactionService {
	return &TransactionService{
		repo: repo,
	}
}

// GetTransaction retrieves a single transaction by ID
func (s *TransactionService) GetTransaction(ctx context.Context, id uuid.UUID, clientID string) (*models.TransactionResponse, error) {
	tx, err := s.repo.FindByID(ctx, id, clientID)
	if err != nil {
		return nil, err
	}

	return s.mapTransactionToResponse(tx), nil
}

// GetAllTransactions retrieves all transactions for a client with pagination and filtering
func (s *TransactionService) GetAllTransactions(
	ctx context.Context,
	clientID string,
	limit, offset int,
	paymentStatus, paymentMethod, searchQuery *string,
) (*models.TransactionsResponse, error) {
	transactions, total, err := s.repo.FindAll(ctx, clientID, limit, offset, paymentStatus, paymentMethod, searchQuery)
	if err != nil {
		return nil, fmt.Errorf("repository error: %w", err)
	}

	responses := make([]models.TransactionResponse, 0, len(transactions))
	for _, tx := range transactions {
		responses = append(responses, *s.mapTransactionToResponse(tx))
	}

	return &models.TransactionsResponse{
		Data:    responses,
		Total:   total,
		Message: "Transactions retrieved successfully",
	}, nil
}

// mapTransactionToResponse converts a Transaction model to TransactionResponse
func (s *TransactionService) mapTransactionToResponse(tx *models.Transaction) *models.TransactionResponse {
	response := &models.TransactionResponse{
		ID:            tx.ID.String(),
		ClientID:      tx.ClientID,
		UserID:        tx.UserID,
		PackageID:     tx.PackageID,
		CheckoutID:    tx.CheckoutID,
		Amount:        tx.Amount,
		Currency:      tx.Currency,
		PaymentMethod: tx.PaymentMethod,
		PaymentStatus: tx.PaymentStatus,
		PhoneNumber:   tx.PhoneNumber,
		Reference:     tx.Reference,
		MpesaReceipt:  tx.MpesaReceipt,
		Description:   tx.Description,
		Provider:      tx.Provider,
		CreatedAt:     tx.CreatedAt,
		UpdatedAt:     tx.UpdatedAt,
	}

	// Convert JSONMap to map[string]interface{}
	if tx.Metadata != nil {
		response.Metadata = map[string]interface{}(*tx.Metadata)
	} else {
		response.Metadata = make(map[string]interface{})
	}

	if tx.ProviderResponse != nil {
		response.ProviderResponse = map[string]interface{}(*tx.ProviderResponse)
	} else {
		response.ProviderResponse = make(map[string]interface{})
	}

	// Include user details if user exists
	if tx.UserID != nil && (tx.UserName != nil || tx.UserUsername != nil) {
		response.User = &models.UserInfo{
			ID:       tx.UserID,
			Name:     tx.UserName,
			Username: tx.UserUsername,
			Email:    tx.UserEmail,
			Phone:    tx.UserPhone,
		}
	}

	// Include package details if package exists
	if tx.PackageID != nil && tx.PackageName != nil {
		response.Package = &models.PackageInfo{
			ID:          tx.PackageID,
			Name:        tx.PackageName,
			PackageType: tx.PackageType,
			Description: tx.PackageDescription,
		}
	}

	return response
}

