package testmark_test

import (
	"testing"

	testmark "github.com/warpfork/go-testmark/v2"
)

func TestNewHunkGeneric(t *testing.T) {
	// Test with string
	stringHunk := testmark.NewHunk("test1", "text", "Hello, World!")
	if stringHunk.Name() != "test1" {
		t.Errorf("expected name 'test1', got %q", stringHunk.Name())
	}
	if stringHunk.InfoString() != "text" {
		t.Errorf("expected info string 'text', got %q", stringHunk.InfoString())
	}
	if stringHunk.String() != "Hello, World!" {
		t.Errorf("expected body 'Hello, World!', got %q", stringHunk.String())
	}

	// Test with []byte
	byteData := []byte("Binary data \x00\x01\x02")
	byteHunk := testmark.NewHunk("test2", "binary", byteData)
	if byteHunk.Name() != "test2" {
		t.Errorf("expected name 'test2', got %q", byteHunk.Name())
	}
	if byteHunk.InfoString() != "binary" {
		t.Errorf("expected info string 'binary', got %q", byteHunk.InfoString())
	}
	if string(byteHunk.Body()) != string(byteData) {
		t.Errorf("expected body %v, got %v", byteData, byteHunk.Body())
	}

	// Test with more []byte data
	byteData2 := []byte("Data from bytes")
	byteHunk2 := testmark.NewHunk("test3", "json", byteData2)
	if byteHunk2.Name() != "test3" {
		t.Errorf("expected name 'test3', got %q", byteHunk2.Name())
	}
	if byteHunk2.InfoString() != "json" {
		t.Errorf("expected info string 'json', got %q", byteHunk2.InfoString())
	}
	if byteHunk2.String() != string(byteData2) {
		t.Errorf("expected body %q, got %q", string(byteData2), byteHunk2.String())
	}
}

func TestNewHunkLegacyCompatibility(t *testing.T) {
	// Test that generic constructor works with string and []byte
	stringHunk := testmark.NewHunk("test4", "text", "string data")
	if stringHunk.String() != "string data" {
		t.Errorf("NewHunk with string failed: got %q", stringHunk.String())
	}

	byteData := []byte("byte data")
	byteHunk := testmark.NewHunk("test5", "binary", byteData)
	if string(byteHunk.Body()) != string(byteData) {
		t.Errorf("NewHunk with []byte failed: got %v", byteHunk.Body())
	}
}

func TestNewHunkGenericInDocument(t *testing.T) {
	// Test that generic constructor works with document patching
	doc := testmark.MustParse(`# Test

[testmark]:# (original)
` + "```\noriginal content\n```" + `
`)

	// Patch with different body types
	stringPatch := testmark.NewHunk("original", "text", "string replacement")
	stringPatched := doc.Patch(stringPatch)
	if stringPatched.HunkByName("original").String() != "string replacement" {
		t.Error("String patch failed")
	}

	bytePatch := testmark.NewHunk("original", "binary", []byte("byte replacement"))
	bytePatched := doc.Patch(bytePatch)
	if bytePatched.HunkByName("original").String() != "byte replacement" {
		t.Error("Byte patch failed")
	}
}

func TestNewHunkErrorHandling(t *testing.T) {
	// Test panic on empty name
	defer func() {
		if r := recover(); r == nil {
			t.Error("Expected panic for empty name")
		}
	}()
	testmark.NewHunk("", "", "content")
}

func TestNewHunkWithWhitespaceName(t *testing.T) {
	// Test panic on name with whitespace
	defer func() {
		if r := recover(); r == nil {
			t.Error("Expected panic for name with whitespace")
		}
	}()
	testmark.NewHunk("invalid name", "", "content")
}
