package queue

import (
	"context"
	"errors"
	"testing"

	filemanager "wucher/internal/domain/file_manager"
	"wucher/internal/shared/pkg/uuidv7"
)

type stubFileProcessingProcessor struct {
	err error
}

func (p stubFileProcessingProcessor) Process(context.Context, filemanager.FileProcessingJob, string) error {
	return p.err
}

func TestFileProcessingJobQueueHandlerHandleSuccess(t *testing.T) {
	fileUUID, err := uuidv7.String(uuidv7.MustNew())
	if err != nil {
		t.Fatalf("uuid string: %v", err)
	}
	handler := NewFileProcessingJobQueueHandler(stubFileProcessingProcessor{}, nil)

	err = handler.Handle(context.Background(), &FileProcessingEnvelope{
		MessageID: "msg-1",
		Payload: FileProcessingJob{
			FileUUID:  fileUUID,
			Bucket:    "bucket-a",
			ObjectKey: "files/a.pdf",
			SizeBytes: 12,
		},
	})
	if err != nil {
		t.Fatalf("handle: %v", err)
	}
}

func TestFileProcessingJobQueueHandlerHandleNilEnvelopePermanent(t *testing.T) {
	handler := NewFileProcessingJobQueueHandler(stubFileProcessingProcessor{}, nil)
	err := handler.Handle(context.Background(), nil)
	if err == nil {
		t.Fatalf("expected error")
	}
	if !IsPermanent(err) {
		t.Fatalf("expected permanent error")
	}
}

func TestFileProcessingJobQueueHandlerHandleInvalidPayloadPermanent(t *testing.T) {
	handler := NewFileProcessingJobQueueHandler(stubFileProcessingProcessor{}, nil)
	err := handler.Handle(context.Background(), &FileProcessingEnvelope{
		MessageID: "msg-2",
		Payload: FileProcessingJob{
			FileUUID: "not-a-uuid",
			Bucket:   "bucket-a",
		},
	})
	if err == nil {
		t.Fatalf("expected error")
	}
	if !IsPermanent(err) {
		t.Fatalf("expected permanent error")
	}
}

func TestFileProcessingJobQueueHandlerHandleTransientError(t *testing.T) {
	fileUUID, err := uuidv7.String(uuidv7.MustNew())
	if err != nil {
		t.Fatalf("uuid string: %v", err)
	}
	handler := NewFileProcessingJobQueueHandler(stubFileProcessingProcessor{
		err: errors.New("temporary timeout"),
	}, nil)

	err = handler.Handle(context.Background(), &FileProcessingEnvelope{
		MessageID: "msg-3",
		Payload: FileProcessingJob{
			FileUUID:  fileUUID,
			Bucket:    "bucket-a",
			ObjectKey: "files/a.pdf",
			SizeBytes: 12,
		},
	})
	if err == nil {
		t.Fatalf("expected error")
	}
	if !IsTransient(err) {
		t.Fatalf("expected transient error")
	}
}

func TestFileProcessingJobQueueHandlerHandlePermanentClassification(t *testing.T) {
	fileUUID, err := uuidv7.String(uuidv7.MustNew())
	if err != nil {
		t.Fatalf("uuid string: %v", err)
	}
	permanentErr := errors.New("not found")
	handler := NewFileProcessingJobQueueHandler(stubFileProcessingProcessor{
		err: permanentErr,
	}, func(err error) bool {
		return errors.Is(err, permanentErr)
	})

	err = handler.Handle(context.Background(), &FileProcessingEnvelope{
		MessageID: "msg-4",
		Payload: FileProcessingJob{
			FileUUID:  fileUUID,
			Bucket:    "bucket-a",
			ObjectKey: "files/a.pdf",
			SizeBytes: 12,
		},
	})
	if err == nil {
		t.Fatalf("expected error")
	}
	if !IsPermanent(err) {
		t.Fatalf("expected permanent error")
	}
}
