package sprite

import (
	"image"
	"image/color"
	"testing"
)

// 测试在精灵上绘制线条
func TestLineToSprite(t *testing.T) {
	// 创建一个新的空白精灵
	sprite := &Sprite{
		Name:     "test_line",
		Position: image.Point{X: 10, Y: 10},
		Index:    1,
	}

	// 定义一条线
	line := &Line{
		Start: image.Point{X: 10, Y: 10}, // 起点设置为与精灵位置相同
		End:   image.Point{X: 50, Y: 30},
		Width: 5,                                      // 增加线宽以便更容易找到
		Color: color.RGBA{R: 255, G: 0, B: 0, A: 255}, // 红色
	}

	// 在精灵上绘制线
	line.AddToSprite(sprite)

	// 验证精灵现在有了图像
	if sprite.Image == nil {
		t.Fatalf("精灵图像为空")
	}

	// 验证精灵位置未变（因为线条在精灵边界内）
	if sprite.Position.X != 10 || sprite.Position.Y != 10 {
		t.Errorf("精灵位置错误：期望(10,10)，实际(%d,%d)",
			sprite.Position.X, sprite.Position.Y)
	}

	// 检查图像大小
	bounds := sprite.Image.Bounds()
	t.Logf("图像大小：%dx%d", bounds.Dx(), bounds.Dy())
	if bounds.Dx() < 41 || bounds.Dy() < 21 {
		t.Errorf("图像大小错误：期望至少(41x21)，实际(%dx%d)",
			bounds.Dx(), bounds.Dy())
	}

	// 检查图像中是否有红色像素
	redPixelFound := false

	// 扫描整个图像查找红色像素
	var redPixels []image.Point
	for y := 0; y < bounds.Dy(); y++ {
		for x := 0; x < bounds.Dx(); x++ {
			pixelColor := sprite.Image.At(x, y)
			r, g, b, _ := pixelColor.RGBA()
			if r>>8 > 200 && g>>8 < 50 && b>>8 < 50 {
				redPixelFound = true
				redPixels = append(redPixels, image.Point{X: x, Y: y})
				if len(redPixels) >= 5 { // 找到5个点就足够了
					break
				}
			}
		}
		if len(redPixels) >= 5 {
			break
		}
	}

	// 打印找到的红色像素位置
	if len(redPixels) > 0 {
		t.Logf("找到 %d 个红色像素点", len(redPixels))
		for i, p := range redPixels {
			t.Logf("  红色像素点 #%d: (%d,%d)", i+1, p.X, p.Y)
		}
	}

	if !redPixelFound {
		// 如果没找到，保存图像用于调试
		board := NewNamedSpriteBoard()
		board.AddSprite(sprite)
		board.SaveToPng("test_line1.png")
		t.Errorf("未找到红色线条像素")
	}

	// 保存初始图像大小用于后续比较
	initialWidth := bounds.Dx()
	initialHeight := bounds.Dy()

	// 再绘制一条线（线条一部分超出当前图像边界，应导致图像扩展）
	line2 := &Line{
		Start: image.Point{X: 5, Y: 20},
		End:   image.Point{X: 65, Y: 40},
		Width: 5,                                      // 增加线宽
		Color: color.RGBA{R: 0, G: 0, B: 255, A: 255}, // 蓝色
	}

	// 使用Sprite.DrawLine方法
	sprite.DrawLine(line2)

	// 检查图像是否扩展以容纳新线
	newBounds := sprite.Image.Bounds()
	t.Logf("扩展后图像大小：%dx%d", newBounds.Dx(), newBounds.Dy())
	if newBounds.Dx() <= initialWidth || newBounds.Dy() <= initialHeight {
		t.Errorf("图像未扩展：原始(%dx%d)，现在(%dx%d)",
			initialWidth, initialHeight, newBounds.Dx(), newBounds.Dy())
	}

	// 检查图像中是否有蓝色像素
	bluePixelFound := false

	// 扫描整个图像查找蓝色像素
	var bluePixels []image.Point
	for y := 0; y < newBounds.Dy(); y++ {
		for x := 0; x < newBounds.Dx(); x++ {
			pixelColor := sprite.Image.At(x, y)
			r, g, b, _ := pixelColor.RGBA()
			if r>>8 < 50 && g>>8 < 50 && b>>8 > 200 {
				bluePixelFound = true
				bluePixels = append(bluePixels, image.Point{X: x, Y: y})
				if len(bluePixels) >= 5 { // 找到5个点就足够了
					break
				}
			}
		}
		if len(bluePixels) >= 5 {
			break
		}
	}

	// 打印找到的蓝色像素位置
	if len(bluePixels) > 0 {
		t.Logf("找到 %d 个蓝色像素点", len(bluePixels))
		for i, p := range bluePixels {
			t.Logf("  蓝色像素点 #%d: (%d,%d)", i+1, p.X, p.Y)
		}
	}

	if !bluePixelFound {
		// 保存图像用于调试
		board := NewNamedSpriteBoard()
		board.AddSprite(sprite)
		board.SaveToPng("test_line2.png")
		t.Errorf("未找到蓝色线条像素")
	}

	// 总是保存最终图像以便查看结果
	board := NewNamedSpriteBoard()
	board.AddSprite(sprite)
	board.SaveToPng("test_line_final.png")
}

// 测试在精灵上绘制圆形
func TestCircleToSprite(t *testing.T) {
	// 创建一个新的空白精灵
	sprite := &Sprite{
		Name:     "test_circle",
		Position: image.Point{X: 20, Y: 20},
		Index:    1,
	}

	// 定义一个圆
	circle := &Circle{
		Center: image.Point{X: 30, Y: 30},
		Radius: 10,
		Color:  color.RGBA{R: 0, G: 255, B: 0, A: 255}, // 绿色
	}

	// 在精灵上绘制圆
	circle.AddToSprite(sprite)

	// 验证精灵现在有了图像
	if sprite.Image == nil {
		t.Fatalf("精灵图像为空")
	}

	// 验证精灵位置正确更新
	if sprite.Position.X != 20 || sprite.Position.Y != 20 {
		t.Errorf("精灵位置错误：期望(20,20)，实际(%d,%d)",
			sprite.Position.X, sprite.Position.Y)
	}

	// 检查图像大小
	bounds := sprite.Image.Bounds()
	t.Logf("图像大小：%dx%d", bounds.Dx(), bounds.Dy())

	// 圆的相对坐标是 (30-20, 30-20) 即 (10,10) 中心
	// 记录找到绿色像素的位置，用于调试
	foundPoints := make([]image.Point, 0)

	// 在图像中寻找绿色像素
	for y := 0; y < bounds.Dy(); y++ {
		for x := 0; x < bounds.Dx(); x++ {
			pixelColor := sprite.Image.At(x, y)
			r, g, b, _ := pixelColor.RGBA()
			if r>>8 < 50 && g>>8 > 200 && b>>8 < 50 {
				foundPoints = append(foundPoints, image.Point{X: x, Y: y})
				if len(foundPoints) > 10 {
					break // 找到足够多的点了
				}
			}
		}
		if len(foundPoints) > 10 {
			break
		}
	}

	// 如果找到了绿色像素，则测试通过
	if len(foundPoints) == 0 {
		// 保存图像用于调试
		board := NewNamedSpriteBoard()
		board.AddSprite(sprite)
		board.SaveToPng("test_circle1.png")
		t.Errorf("未找到绿色圆形像素")
	} else {
		t.Logf("找到 %d 个绿色像素点", len(foundPoints))
		for i, p := range foundPoints {
			if i < 5 { // 只打印前5个点
				t.Logf("  绿色像素点 #%d: (%d,%d)", i+1, p.X, p.Y)
			}
		}
	}

	// 保存初始图像大小用于后续比较
	initialWidth := bounds.Dx()
	initialHeight := bounds.Dy()

	// 再绘制一个圆（部分在图像边界外，应导致图像扩展）
	circle2 := &Circle{
		Center: image.Point{X: 15, Y: 15},
		Radius: 15,
		Color:  color.RGBA{R: 255, G: 255, B: 0, A: 255}, // 黄色
	}

	// 在已有精灵上绘制第二个圆
	circle2.AddToSprite(sprite)

	// 检查图像是否扩展
	newBounds := sprite.Image.Bounds()
	t.Logf("扩展后图像大小：%dx%d", newBounds.Dx(), newBounds.Dy())

	// 检查图像是否扩展了
	if newBounds.Dx() <= initialWidth || newBounds.Dy() <= initialHeight {
		t.Errorf("图像未正确扩展：原始(%dx%d)，现在(%dx%d)",
			initialWidth, initialHeight, newBounds.Dx(), newBounds.Dy())
	}

	// 查找黄色像素
	yellowPixelFound := false
	yellowPoints := make([]image.Point, 0)

	// 在图像中寻找黄色像素
	for y := 0; y < newBounds.Dy(); y++ {
		for x := 0; x < newBounds.Dx(); x++ {
			pixelColor := sprite.Image.At(x, y)
			r, g, b, _ := pixelColor.RGBA()
			if r>>8 > 200 && g>>8 > 200 && b>>8 < 50 {
				yellowPixelFound = true
				yellowPoints = append(yellowPoints, image.Point{X: x, Y: y})
				if len(yellowPoints) > 10 {
					break // 找到足够多的点了
				}
			}
		}
		if len(yellowPoints) > 10 {
			break
		}
	}

	if !yellowPixelFound {
		// 保存图像用于调试
		board := NewNamedSpriteBoard()
		board.AddSprite(sprite)
		board.SaveToPng("test_circle2.png")
		t.Errorf("未找到黄色圆形像素")
	} else {
		t.Logf("找到 %d 个黄色像素点", len(yellowPoints))
		for i, p := range yellowPoints {
			if i < 5 { // 只打印前5个点
				t.Logf("  黄色像素点 #%d: (%d,%d)", i+1, p.X, p.Y)
			}
		}
	}
}
