package models

import (
	"database/sql/driver"
	"encoding/json"
	"time"

	"github.com/google/uuid"
)

// JSONMap represents a JSON object in the database
type JSONMap map[string]interface{}

// Value implements the driver.Valuer interface
func (j JSONMap) Value() (driver.Value, error) {
	if j == nil {
		return nil, nil
	}
	return json.Marshal(j)
}

// Scan implements the sql.Scanner interface
func (j *JSONMap) Scan(value interface{}) error {
	if value == nil {
		*j = nil
		return nil
	}
	bytes, ok := value.([]byte)
	if !ok {
		return json.Unmarshal([]byte(value.(string)), j)
	}
	return json.Unmarshal(bytes, j)
}

// UserInfo represents user information in transaction response
type UserInfo struct {
	ID       *string `json:"id,omitempty"`
	Name     *string `json:"name,omitempty"`
	Username *string `json:"username,omitempty"`
	Email    *string `json:"email,omitempty"`
	Phone    *string `json:"phone,omitempty"`
}

// PackageInfo represents internet package information in transaction response
type PackageInfo struct {
	ID          *string `json:"id,omitempty"`
	Name        *string `json:"name,omitempty"`
	PackageType *string `json:"package_type,omitempty"`
	Description *string `json:"description,omitempty"`
}

// Transaction represents a payment transaction
type Transaction struct {
	ID              uuid.UUID  `json:"id" db:"id"`
	ClientID        string     `json:"client_id" db:"client_id"` // character(36) in database
	UserID          *string    `json:"user_id" db:"user_id"`      // character(36) in database, nullable
	CheckoutID      string     `json:"checkout_id" db:"checkout_id"`
	Amount          float64    `json:"amount" db:"amount"`
	Currency        string     `json:"currency" db:"currency"`
	PaymentMethod   string     `json:"payment_method" db:"payment_method"`
	PaymentStatus   string     `json:"payment_status" db:"payment_status"`
	PhoneNumber     string     `json:"phone_number" db:"phone_number"`
	Reference       *string    `json:"reference" db:"reference"`
	MpesaReceipt    *string    `json:"mpesa_receipt" db:"mpesa_receipt"`
	Description     *string    `json:"description" db:"description"`
	Metadata        *JSONMap   `json:"metadata" db:"metadata"`
	Provider        string     `json:"provider" db:"provider"`
	ProviderResponse *JSONMap  `json:"provider_response" db:"provider_response"`
	CreatedAt       *time.Time `json:"created_at" db:"created_at"`
	UpdatedAt       *time.Time `json:"updated_at" db:"updated_at"`
	DeletedAt       *time.Time `json:"deleted_at" db:"deleted_at"`
	// User fields (populated from JOIN)
	UserName     *string `json:"-" db:"user_name"`
	UserUsername *string `json:"-" db:"user_username"`
	UserEmail    *string `json:"-" db:"user_email"`
	UserPhone    *string `json:"-" db:"user_phone"`
	// Package fields (populated from JOIN)
	PackageID          *string `json:"-" db:"package_id"`
	PackageName        *string `json:"-" db:"package_name"`
	PackageType        *string `json:"-" db:"package_type"`
	PackageDescription *string `json:"-" db:"package_description"`
}

// TransactionResponse represents the response format for transactions
type TransactionResponse struct {
	ID              string                 `json:"id"`
	ClientID        string                 `json:"client_id"`
	UserID          *string                `json:"user_id,omitempty"`
	User            *UserInfo              `json:"user,omitempty"`
	PackageID       *string                `json:"package_id,omitempty"`
	Package         *PackageInfo           `json:"package,omitempty"`
	CheckoutID      string                 `json:"checkout_id"`
	Amount          float64                `json:"amount"`
	Currency        string                 `json:"currency"`
	PaymentMethod   string                 `json:"payment_method"`
	PaymentStatus   string                 `json:"payment_status"`
	PhoneNumber     string                 `json:"phone_number"`
	Reference       *string                `json:"reference"`
	MpesaReceipt    *string                `json:"mpesa_receipt"`
	Description     *string                `json:"description"`
	Metadata        map[string]interface{} `json:"metadata"`
	Provider        string                 `json:"provider"`
	ProviderResponse map[string]interface{} `json:"provider_response"`
	CreatedAt       *time.Time             `json:"created_at"`
	UpdatedAt       *time.Time             `json:"updated_at"`
}

// TransactionsResponse represents a paginated list of transactions
type TransactionsResponse struct {
	Data  []TransactionResponse `json:"data"`
	Total int64                 `json:"total"`
	Message string              `json:"message"`
}

