package backtest

import (
	"context"
	"fmt"
	"sort"
	"time"

	"git.toki-labs.com/toki/alt/packages/domain/market"
	"git.toki-labs.com/toki/alt/services/worker/internal/storage"
)

// StorageBarSource adapts worker market-data storage ports to the backtest
// engine's market/timeframe/date-range input boundary.
type StorageBarSource struct {
	instruments storage.InstrumentStore
	bars        storage.BarStore
}

func NewStorageBarSource(instruments storage.InstrumentStore, bars storage.BarStore) *StorageBarSource {
	return &StorageBarSource{instruments: instruments, bars: bars}
}

func (s *StorageBarSource) GetBars(ctx context.Context, mkt market.Market, timeframe market.Timeframe, from, to time.Time) ([]market.Bar, error) {
	if s == nil || s.instruments == nil || s.bars == nil {
		return nil, fmt.Errorf("backtest storage bar source: storage is not configured")
	}

	instruments, err := s.instruments.ListInstruments(ctx)
	if err != nil {
		return nil, fmt.Errorf("backtest storage bar source: list instruments: %w", err)
	}

	var out []market.Bar
	for _, inst := range instruments {
		if inst.Market != mkt {
			continue
		}
		bars, err := s.bars.GetBars(ctx, inst.ID, timeframe, from, to)
		if err != nil {
			return nil, fmt.Errorf("backtest storage bar source: get bars for %q: %w", inst.ID, err)
		}
		out = append(out, bars...)
	}

	sort.Slice(out, func(i, j int) bool {
		if out[i].Timestamp.Equal(out[j].Timestamp) {
			return out[i].InstrumentID < out[j].InstrumentID
		}
		return out[i].Timestamp.Before(out[j].Timestamp)
	})
	return out, nil
}
