package asynqqueue

import (
	"context"
	"time"

	"github.com/libnovel/backend/internal/domain"
	"github.com/libnovel/backend/internal/taskqueue"
)

// Consumer wraps the PocketBase-backed Consumer for result write-back only.
//
// When using Asynq, the runner no longer polls for scrape/audio work — Asynq
// delivers those tasks via the ServeMux handlers. However translation tasks
// live in PocketBase (not Redis), so ClaimNextTranslationTask and HeartbeatTask
// still delegate to the underlying PocketBase consumer.
//
// ClaimNextAudioTask, ClaimNextScrapeTask are no-ops here because Asynq owns
// those responsibilities.
type Consumer struct {
	pb taskqueue.Consumer // underlying PocketBase consumer (for write-back)
}

// NewConsumer wraps an existing PocketBase Consumer.
func NewConsumer(pb taskqueue.Consumer) *Consumer {
	return &Consumer{pb: pb}
}

// ── Write-back (delegated to PocketBase) ──────────────────────────────────────

func (c *Consumer) FinishScrapeTask(ctx context.Context, id string, result domain.ScrapeResult) error {
	return c.pb.FinishScrapeTask(ctx, id, result)
}

func (c *Consumer) FinishAudioTask(ctx context.Context, id string, result domain.AudioResult) error {
	return c.pb.FinishAudioTask(ctx, id, result)
}

func (c *Consumer) FinishTranslationTask(ctx context.Context, id string, result domain.TranslationResult) error {
	return c.pb.FinishTranslationTask(ctx, id, result)
}

func (c *Consumer) FinishImportTask(ctx context.Context, id string, result domain.ImportResult) error {
	return c.pb.FinishImportTask(ctx, id, result)
}

func (c *Consumer) FailTask(ctx context.Context, id, errMsg string) error {
	return c.pb.FailTask(ctx, id, errMsg)
}

// ── No-ops (Asynq owns claiming / heartbeating / reaping) ───────────────────

func (c *Consumer) ClaimNextScrapeTask(_ context.Context, _ string) (domain.ScrapeTask, bool, error) {
	return domain.ScrapeTask{}, false, nil
}

func (c *Consumer) ClaimNextAudioTask(_ context.Context, _ string) (domain.AudioTask, bool, error) {
	return domain.AudioTask{}, false, nil
}

// ClaimNextTranslationTask delegates to PocketBase because translation tasks
// are stored in PocketBase (not Redis/Asynq) and must still be polled directly.
func (c *Consumer) ClaimNextTranslationTask(ctx context.Context, workerID string) (domain.TranslationTask, bool, error) {
	return c.pb.ClaimNextTranslationTask(ctx, workerID)
}

// ClaimNextImportTask delegates to PocketBase because import tasks
// are stored in PocketBase (not Redis/Asynq) and must still be polled directly.
func (c *Consumer) ClaimNextImportTask(ctx context.Context, workerID string) (domain.ImportTask, bool, error) {
	return c.pb.ClaimNextImportTask(ctx, workerID)
}

func (c *Consumer) HeartbeatTask(ctx context.Context, id string) error {
	return c.pb.HeartbeatTask(ctx, id)
}

// ReapStaleTasks delegates to PocketBase so stale translation tasks are reset
// to pending and can be reclaimed.
func (c *Consumer) ReapStaleTasks(ctx context.Context, staleAfter time.Duration) (int, error) {
	return c.pb.ReapStaleTasks(ctx, staleAfter)
}
