package publish

import (
	"context"
	"fmt"
	"sync"
	"sync/atomic"

	"apps/backend/internal/module/studio/domain"

	"github.com/google/uuid"
)

// FakeTransport records every Publish call — OB-02 greppable proof.
type FakeTransport struct {
	mu      sync.Mutex
	Calls   []domain.PublishRequest
	Fail    bool
	FailMsg string
	// FailOnNth fails the Nth call (1-based); 0 = never
	FailOnNth int
	n         int64
}

func NewFake() *FakeTransport {
	return &FakeTransport{}
}

func (f *FakeTransport) Publish(ctx context.Context, req domain.PublishRequest) (*domain.PublishResult, error) {
	_ = ctx
	n := atomic.AddInt64(&f.n, 1)
	f.mu.Lock()
	f.Calls = append(f.Calls, req)
	fail := f.Fail
	failNth := f.FailOnNth
	msg := f.FailMsg
	f.mu.Unlock()
	if fail || (failNth > 0 && int(n) == failNth) {
		if msg == "" {
			msg = "threads publish failed"
		}
		return nil, fmt.Errorf("%s", msg)
	}
	return &domain.PublishResult{MediaID: "media_" + uuid.NewString()[:8]}, nil
}

func (f *FakeTransport) CallCount() int {
	f.mu.Lock()
	defer f.mu.Unlock()
	return len(f.Calls)
}

func (f *FakeTransport) Reset() {
	f.mu.Lock()
	defer f.mu.Unlock()
	f.Calls = nil
	atomic.StoreInt64(&f.n, 0)
	f.Fail = false
	f.FailOnNth = 0
}

// Transport interface used by studio service (context.Context).
type Transport interface {
	Publish(ctx context.Context, req domain.PublishRequest) (*domain.PublishResult, error)
}

var _ Transport = (*FakeTransport)(nil)
