package analytics

import (
	"context"
	"fmt"

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

// TokenDistribution provides token distribution analytics
type TokenDistribution struct {
	db *pgxpool.Pool
	chainID int
}

// NewTokenDistribution creates a new token distribution analyzer
func NewTokenDistribution(db *pgxpool.Pool, chainID int) *TokenDistribution {
	return &TokenDistribution{
		db:      db,
		chainID: chainID,
	}
}

// DistributionStats represents token distribution statistics
type DistributionStats struct {
	Contract          string
	Symbol            string
	TotalSupply       string
	Holders           int
	Distribution      map[string]string
	TopHolders        []HolderInfo
}

// HolderInfo represents holder information
type HolderInfo struct {
	Address    string
	Balance    string
	Percentage string
}

// GetTokenDistribution gets token distribution for a contract
func (td *TokenDistribution) GetTokenDistribution(ctx context.Context, contract string, topN int) (*DistributionStats, error) {
	// Refresh materialized view
	_, err := td.db.Exec(ctx, `REFRESH MATERIALIZED VIEW CONCURRENTLY token_distribution`)
	if err != nil {
		// Ignore error if view doesn't exist yet
	}

	// Get distribution from materialized view
	query := `
		SELECT holder_count, total_balance
		FROM token_distribution
		WHERE token_contract = $1 AND chain_id = $2
	`

	var holders int
	var totalSupply string
	err = td.db.QueryRow(ctx, query, contract, td.chainID).Scan(&holders, &totalSupply)
	if err != nil {
		return nil, fmt.Errorf("failed to get distribution: %w", err)
	}

	// Get top holders
	topHoldersQuery := `
		SELECT address, balance
		FROM token_balances
		WHERE token_contract = $1 AND chain_id = $2 AND balance > 0
		ORDER BY balance DESC
		LIMIT $3
	`

	rows, err := td.db.Query(ctx, topHoldersQuery, contract, td.chainID, topN)
	if err != nil {
		return nil, fmt.Errorf("failed to get top holders: %w", err)
	}
	defer rows.Close()

	topHolders := []HolderInfo{}
	for rows.Next() {
		var holder HolderInfo
		if err := rows.Scan(&holder.Address, &holder.Balance); err != nil {
			continue
		}
		// Calculate percentage (simplified)
		holder.Percentage = "0.0" // TODO: Calculate from total supply
		topHolders = append(topHolders, holder)
	}

	stats := &DistributionStats{
		Contract:     contract,
		Holders:      holders,
		TotalSupply:  totalSupply,
		Distribution: make(map[string]string),
		TopHolders:   topHolders,
	}

	// Calculate distribution metrics
	stats.Distribution["top_10_percent"] = "0.0" // TODO: Calculate
	stats.Distribution["top_1_percent"] = "0.0"   // TODO: Calculate
	stats.Distribution["gini_coefficient"] = "0.0" // TODO: Calculate

	return stats, nil
}

