package storage

import (
	"context"
	"errors"
	"time"

	"git.toki-labs.com/toki/alt/packages/domain/backtest"
	"git.toki-labs.com/toki/alt/packages/domain/market"
)

var ErrRunNotFound = errors.New("backtest run not found")
var ErrResultNotFound = errors.New("backtest result not found")
var ErrInstrumentNotFound = errors.New("instrument not found")

type InstrumentStore interface {
	UpsertInstrument(ctx context.Context, inst market.Instrument) error
	GetInstrument(ctx context.Context, id market.InstrumentID) (market.Instrument, error)
	ListInstruments(ctx context.Context) ([]market.Instrument, error)
}

type BarStore interface {
	UpsertBar(ctx context.Context, bar market.Bar) error
	GetBars(ctx context.Context, id market.InstrumentID, timeframe market.Timeframe, from, to time.Time) ([]market.Bar, error)
}

type BacktestRunStore interface {
	UpsertRun(ctx context.Context, run backtest.Run) error
	GetRun(ctx context.Context, id backtest.RunID) (backtest.Run, error)
}

type BacktestResultStore interface {
	UpsertResult(ctx context.Context, result backtest.Result) error
	GetResult(ctx context.Context, id backtest.RunID) (backtest.Result, error)
}

// RunDetail bundles a run with its analysis result for detail views. HasResult is
// false when the run exists but has not produced a result yet.
type RunDetail struct {
	Run       backtest.Run
	Result    backtest.Result
	HasResult bool
}

// BacktestAnalysisStore exposes list, detail, and compare read access for the
// analysis surface. It is separate from the execution-side run/result stores so the
// engine and job handlers keep a minimal write dependency.
type BacktestAnalysisStore interface {
	ListRuns(ctx context.Context, status backtest.RunStatus) ([]backtest.Run, error)
	GetRunDetail(ctx context.Context, id backtest.RunID) (RunDetail, error)
	CompareResults(ctx context.Context, ids []backtest.RunID) ([]backtest.Result, error)
}
