package img

import (
	"fmt"
	"image"
	"image/color"
	"math"
	"math/rand"
	"unicode"

	"github.com/disintegration/imaging"
	"github.com/fogleman/gg"
	"github.com/ssgo/u"
)

type LineCap struct {
	Butt   string
	Round  string
	Square string
}

var lineCap = LineCap{
	Butt:   "butt",
	Round:  "round",
	Square: "square",
}

type LineJoin struct {
	Bevel string
	Miter string
	Round string
}

var lineJoin = LineJoin{
	Bevel: "bevel",
	Round: "round",
}

type FillRule struct {
	Winding string
	Evenodd string
}

var fillRule = FillRule{
	Winding: "winding",
	Evenodd: "evenodd",
}

type DrawStyle struct {
	LineColor    string
	LineWidth    float64
	LineCap      string
	LineJoin     string
	Dash         []float64
	DashOffset   float64
	FillColor    string
	FillRule     string
	ShadowColor  string
	ShadowOffset float64
	ShadowBlur   float64
}

func (g *Graphics) draw(fn func(offset float64), opt *DrawStyle) {
	if opt == nil {
		opt = &DrawStyle{}
	}

	needFill := opt.FillColor != ""
	needStroke := !needFill || opt.LineColor != "" || opt.LineWidth >= 0.01

	// 绘制阴影
	if opt.ShadowColor != "" || (opt.ShadowOffset >= 0.01 || opt.ShadowBlur <= -0.01) {
		if opt.ShadowColor == "" {
			opt.ShadowColor = "#333333"
		}
		if opt.ShadowOffset > -0.01 && opt.ShadowOffset < 0.01 {
			opt.ShadowOffset = 2
		}

		useBlur := opt.ShadowBlur >= 0.01
		var tmpdc, olddc *gg.Context
		if useBlur {
			bounds := g.dc.Image().Bounds()
			tmpdc = gg.NewContext(bounds.Dx(), bounds.Dy())
			olddc = g.dc
			g.dc = tmpdc
		}

		fn(opt.ShadowOffset)
		g.dc.SetColor(hexToRGBA(opt.ShadowColor))
		if opt.LineWidth >= 0.01 {
			g.dc.SetLineWidth(opt.LineWidth)
		}
		if needFill {
			g.dc.Fill()
		} else {
			g.dc.Stroke()
		}

		if needFill {
			g.dc.Fill()
		} else {
			g.dc.Stroke()
		}
		if useBlur {

			g.dc = olddc
			tmpimg := tmpdc.Image()
			imaging.Blur(tmpimg, opt.ShadowBlur)
			g.dc.DrawImage(tmpimg, 0, 0)
		}
	}

	// 绘制图形
	fn(0)
	if needFill {
		g.dc.SetColor(hexToRGBA(opt.FillColor))
		if opt.FillRule != "" {
			switch opt.FillRule {
			case fillRule.Winding:
				g.dc.SetFillRule(gg.FillRuleWinding)
			case fillRule.Evenodd:
				g.dc.SetFillRule(gg.FillRuleEvenOdd)
			}
		}
		if needStroke {
			g.dc.FillPreserve()
		} else if needFill {
			g.dc.Fill()
		}
	}
	if needStroke {
		if opt.LineWidth >= 0.01 {
			g.dc.SetLineWidth(opt.LineWidth)
			needStroke = true
		}
		if opt.LineCap != "" {
			switch opt.LineCap {
			case lineCap.Butt:
				g.dc.SetLineCap(gg.LineCapButt)
			case lineCap.Round:
				g.dc.SetLineCap(gg.LineCapRound)
			case lineCap.Square:
				g.dc.SetLineCap(gg.LineCapSquare)
			}
		}
		if opt.LineJoin != "" {
			switch opt.LineJoin {
			case lineJoin.Bevel:
				g.dc.SetLineJoin(gg.LineJoinBevel)
			case lineJoin.Round:
				g.dc.SetLineJoin(gg.LineJoinRound)
			}
		}
		if opt.Dash != nil {
			g.dc.SetDash(opt.Dash...)
		}
		if opt.DashOffset >= 0.01 {
			g.dc.SetDashOffset(opt.DashOffset)
		}
		if opt.LineColor != "" {
			g.SetColor(opt.LineColor)
		} else if g.lastColor != "" {
			g.SetColor(g.lastColor)
		}
		g.dc.Stroke()

		if opt.Dash != nil || opt.DashOffset >= 0.01 {
			g.dc.SetDash()
		}
	}
}

// DrawRectangle 绘制矩形
func (g *Graphics) Rect(x, y, w, h float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawRectangle(x+offset, y+offset, w, h)
	}, opt)
}

func (g *Graphics) RoundedRect(x, y, w, h, r float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawRoundedRectangle(x+offset, y+offset, w, h, r)
	}, opt)
}

// Point 绘制点
func (g *Graphics) Point(x, y float64, c *string) {
	if c != nil && *c != "" {
		g.SetColor(*c)
	}
	g.dc.DrawPoint(x, y, 1)
	g.dc.Stroke()
}

// Line 绘制直线
func (g *Graphics) Line(x1, y1, x2, y2 float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.MoveTo(x1+offset, y1+offset)
		g.dc.LineTo(x2+offset, y2+offset)
	}, opt)
}

func convertPoints(points []float64) []gg.Point {
	p := make([]gg.Point, 0, len(points)/2)
	for i := 0; i < len(points)-1; i += 2 {
		p = append(p, gg.Point{X: points[i], Y: points[i+1]})
	}
	return p
}

// Lines 绘制多条连续线段
func (g *Graphics) Lines(points []float64, opt *DrawStyle) {
	pp := convertPoints(points)
	g.draw(func(offset float64) {
		if len(pp) >= 0 {
			g.dc.MoveTo(pp[0].X+offset, pp[0].Y+offset)
			for _, p := range pp[1:] {
				g.dc.LineTo(p.X+offset, p.Y+offset)
			}
		}
	}, opt)
}

// Circle 绘制圆形
func (g *Graphics) Circle(x, y, r float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawCircle(x+offset, y+offset, r)
	}, opt)
}

// Ellipse 绘制椭圆
func (g *Graphics) Ellipse(x, y, rx, ry float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawEllipse(x+offset, y+offset, rx, ry)
	}, opt)
}

// Arc 绘制圆弧
func (g *Graphics) Arc(x, y, r, angle1, angle2 float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawArc(x+offset, y+offset, r, angle1, angle2)
	}, opt)
}

// Sector 绘制扇形
func (g *Graphics) Sector(x, y, r, angle1, angle2 float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.DrawArc(x+offset, y+offset, r, angle1, angle2)
		g.dc.LineTo(x+offset, y+offset)
		g.dc.LineTo(x+offset+r*math.Cos(angle1), y+offset+r*math.Sin(angle1))
	}, opt)
}

// Ring 绘制圆环
func (g *Graphics) Ring(x, y, innerRadius, outerRadius float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		// 绘制外圆
		g.dc.DrawCircle(x+offset, y+offset, outerRadius)
		// 绘制内圆（作为"洞"）
		g.dc.DrawCircle(x+offset, y+offset, innerRadius)
		g.dc.SetFillRule(gg.FillRuleEvenOdd)
	}, opt)
}

// ArcRing 绘制扇形环
func (g *Graphics) ArcRing(x, y, innerRadius, outerRadius, angle1, angle2 float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		// 绘制外圆弧
		g.dc.DrawArc(x+offset, y+offset, outerRadius, angle1, angle2)
		// 绘制内圆弧（反向）
		g.dc.DrawArc(x+offset, y+offset, innerRadius, angle2, angle1)
		g.dc.ClosePath()
	}, opt)
}

// Triangle 绘制三角形
func (g *Graphics) Triangle(x1, y1, x2, y2, x3, y3 float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		g.dc.MoveTo(x1+offset, y1+offset)
		g.dc.LineTo(x2+offset, y2+offset)
		g.dc.LineTo(x3+offset, y3+offset)
		g.dc.ClosePath()
	}, opt)
}

// Polygon 绘制多边形
func (g *Graphics) Polygon(points []float64, opt *DrawStyle) {
	pp := convertPoints(points)
	g.draw(func(offset float64) {
		if len(pp) > 0 {
			pp := convertPoints(points)
			g.dc.MoveTo(pp[0].X+offset, pp[0].Y+offset)
			for _, p := range pp[1:] {
				g.dc.LineTo(p.X+offset, p.Y+offset)
			}
			g.dc.ClosePath()
		}
	}, opt)
}

// RegularPolygon 绘制正多边形
func (g *Graphics) RegularPolygon(n int, x, y, r float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		for i := 0; i < n; i++ {
			angle := float64(i)*2*math.Pi/float64(n) - math.Pi/2
			px := x + offset + r*math.Cos(angle)
			py := y + offset + r*math.Sin(angle)
			if i == 0 {
				g.dc.MoveTo(px, py)
			} else {
				g.dc.LineTo(px, py)
			}
		}
		g.dc.ClosePath()
	}, opt)
}

// Star 绘制星形
func (g *Graphics) Star(n int, x, y, outerRadius, innerRadius float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		for i := 0; i < n*2; i++ {
			angle := float64(i)*math.Pi/float64(n) - math.Pi/2
			r := outerRadius
			if i%2 == 1 {
				r = innerRadius
			}
			px := x + offset + r*math.Cos(angle)
			py := y + offset + r*math.Sin(angle)
			if i == 0 {
				g.dc.MoveTo(px, py)
			} else {
				g.dc.LineTo(px, py)
			}
		}
		g.dc.ClosePath()
	}, opt)
}

// BezierCurve 绘制贝塞尔曲线
func (g *Graphics) BezierCurve(points []float64, opt *DrawStyle) {
	pp := convertPoints(points)
	g.draw(func(offset float64) {
		if len(pp) >= 4 && len(pp)%3 == 1 {
			g.dc.MoveTo(pp[0].X+offset, pp[0].Y+offset)
			for i := 1; i < len(pp); i += 3 {
				g.dc.CubicTo(
					pp[i].X+offset, pp[i].Y+offset,
					pp[i+1].X+offset, pp[i+1].Y+offset,
					pp[i+2].X+offset, pp[i+2].Y+offset,
				)
			}
		}
	}, opt)
}

// QuadraticCurve 绘制二次贝塞尔曲线
func (g *Graphics) QuadraticCurve(points []float64, opt *DrawStyle) {
	pp := convertPoints(points)
	g.draw(func(offset float64) {
		if len(pp) >= 3 && len(pp)%2 == 1 {
			g.dc.MoveTo(pp[0].X+offset, pp[0].Y+offset)
			for i := 1; i < len(pp); i += 2 {
				g.dc.QuadraticTo(
					pp[i].X+offset, pp[i].Y+offset,
					pp[i+1].X+offset, pp[i+1].Y+offset,
				)
			}
		}
	}, opt)
}

type PathCmd struct {
	Cmd  string
	Args []string
}

type RelativePoint struct {
	X, Y float64
}

func (p *RelativePoint) Parse(cmd string, arg string) gg.Point {
	a := u.SplitWithoutNone(arg, ",")
	if len(a) != 2 {
		a = append(a, "")
	}

	if unicode.IsLower(rune(cmd[0])) {
		p.X += u.Float64(a[0])
		p.Y += u.Float64(a[1])
	} else {
		if a[0] != "" {
			p.X = u.Float64(a[0])
		}
		if a[1] != "" {
			p.Y = u.Float64(a[1])
		}
	}
	return gg.Point{X: p.X, Y: p.Y}
}

// Path 绘制复杂路径（支持直线和曲线）
func (g *Graphics) Path(commands string, opt *DrawStyle) {
	a := u.SplitWithoutNone(commands, " ")
	cmds := make([]PathCmd, 0)
	lastCmd := "M"
	args := []string{}
	for _, cmd := range a {
		w1 := cmd[0]
		if (w1 >= 'A' && w1 <= 'Z') || (w1 >= 'a' && w1 <= 'z') {
			if len(args) > 0 {
				// 遇到字母，先处理之前的命令
				cmds = append(cmds, PathCmd{
					Cmd:  lastCmd,
					Args: args,
				})
				args = []string{}
			}
			lastCmd = string(w1)
			cmd = cmd[1:]
		}

		// 遇到结束命令
		if lastCmd == "Z" || lastCmd == "z" {
			cmds = append(cmds, PathCmd{Cmd: lastCmd})
			break
		}

		// 无参数，继续等待
		if len(cmd) > 0 {
			args = append(args, cmd)
		}
	}

	// 添加最后一个命令
	if len(args) > 0 || lastCmd == "Z" || lastCmd == "z" {
		cmds = append(cmds, PathCmd{Cmd: lastCmd, Args: args})
	}

	g.draw(func(offset float64) {
		// 状态跟踪
		p := RelativePoint{}
		var startP *gg.Point
		var prevControl gg.Point
		for _, cmd := range cmds {
			// 绝对/相对模式判断
			switch cmd.Cmd {
			case "M", "m":
				if len(cmd.Args) > 0 {
					pp := p.Parse(cmd.Cmd, cmd.Args[0])
					startP = &pp
					g.dc.MoveTo(pp.X+offset, pp.Y+offset)
					// 如果后面还有参数，则视为隐式的直线命令（L或l）
					for i := 1; i < len(cmd.Args); i++ {
						pp = p.Parse(cmd.Cmd, cmd.Args[i])
						g.dc.LineTo(pp.X+offset, pp.Y+offset)
					}
				}
			case "L", "l":
				for _, arg := range cmd.Args {
					pp := p.Parse(cmd.Cmd, arg)
					g.dc.LineTo(pp.X+offset, pp.Y+offset)
				}
			case "C", "c":
				for i := 0; i < len(cmd.Args)-2; i += 3 {
					pp1 := p.Parse(cmd.Cmd, cmd.Args[i])
					pp2 := p.Parse(cmd.Cmd, cmd.Args[i+1])
					pp3 := p.Parse(cmd.Cmd, cmd.Args[i+2])
					g.dc.CubicTo(
						pp1.X+offset, pp1.Y+offset,
						pp2.X+offset, pp2.Y+offset,
						pp3.X+offset, pp3.Y+offset,
					)
					prevControl = pp2
				}

			case "S", "s":
				// 简化三次贝塞尔曲线
				for i := 0; i < len(cmd.Args); i += 2 {
					if i+1 >= len(cmd.Args) {
						break
					}

					// 计算第一个控制点（对称点）
					cp1 := gg.Point{
						X: 2*p.X - prevControl.X,
						Y: 2*p.Y - prevControl.Y,
					}

					cp2 := p.Parse(cmd.Cmd, cmd.Args[i])
					end := p.Parse(cmd.Cmd, cmd.Args[i+1])

					g.dc.CubicTo(
						cp1.X+offset, cp1.Y+offset,
						cp2.X+offset, cp2.Y+offset,
						end.X+offset, end.Y+offset,
					)

					prevControl = cp2
				}

			case "Q", "q":
				// 二次贝塞尔曲线
				for i := 0; i < len(cmd.Args); i += 2 {
					if i+1 >= len(cmd.Args) {
						break
					}
					cp := p.Parse(cmd.Cmd, cmd.Args[i])
					end := p.Parse(cmd.Cmd, cmd.Args[i+1])

					// 将二次转换为三次贝塞尔曲线
					qToC1, qToC2 := quadToCubic(p.X, p.Y, cp.X, cp.Y, end.X, end.Y)
					g.dc.CubicTo(
						qToC1.X+offset, qToC1.Y+offset,
						qToC2.X+offset, qToC2.Y+offset,
						end.X+offset, end.Y+offset,
					)
					prevControl = cp
				}

			case "T", "t":
				// 简化二次贝塞尔曲线
				for _, arg := range cmd.Args {
					// 计算控制点（对称点）
					cp := gg.Point{
						X: 2*p.X - prevControl.X,
						Y: 2*p.Y - prevControl.Y,
					}

					end := p.Parse(cmd.Cmd, arg)

					// 将二次转换为三次贝塞尔曲线
					qToC1, qToC2 := quadToCubic(p.X, p.Y, cp.X, cp.Y, end.X, end.Y)
					g.dc.CubicTo(
						qToC1.X+offset, qToC1.Y+offset,
						qToC2.X+offset, qToC2.Y+offset,
						end.X+offset, end.Y+offset,
					)

					prevControl = cp
				}

			case "H", "h":
				// 水平线
				for _, arg := range cmd.Args {
					pp := p.Parse(cmd.Cmd, arg+",")
					g.dc.LineTo(pp.X+offset, pp.Y+offset)
				}

			case "V", "v":
				// 垂直线
				for _, arg := range cmd.Args {
					pp := p.Parse(cmd.Cmd, ","+arg)
					g.dc.LineTo(pp.X+offset, pp.Y+offset)
				}

			case "Z", "z":
				if startP != nil {
					g.dc.LineTo(startP.X+offset, startP.Y+offset)
				}
				g.dc.ClosePath()
			}
		}
	}, opt)
}

// 辅助函数：二次到三次贝塞尔转换
func quadToCubic(x0, y0, cx, cy, x1, y1 float64) (gg.Point, gg.Point) {
	return gg.Point{
			X: x0 + (2.0/3.0)*(cx-x0),
			Y: y0 + (2.0/3.0)*(cy-y0),
		}, gg.Point{
			X: x1 + (2.0/3.0)*(cx-x1),
			Y: y1 + (2.0/3.0)*(cy-y1),
		}
}

// Arrow 绘制箭头
func (g *Graphics) Arrow(x1, y1, x2, y2, headSize float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		// 计算箭头方向
		dx := x2 - x1
		dy := y2 - y1
		angle := math.Atan2(dy, dx)
		length := math.Sqrt(dx*dx + dy*dy)

		// 绘制线
		g.dc.MoveTo(x1+offset, y1+offset)
		g.dc.LineTo(x2+offset, y2+offset)

		// 绘制箭头头部
		if headSize > 0 && length > headSize {
			// 箭头头部点1
			x3 := x2 - headSize*math.Cos(angle-math.Pi/6)
			y3 := y2 - headSize*math.Sin(angle-math.Pi/6)

			// 箭头头部点2
			x4 := x2 - headSize*math.Cos(angle+math.Pi/6)
			y4 := y2 - headSize*math.Sin(angle+math.Pi/6)

			// 绘制箭头头部
			g.dc.MoveTo(x2+offset, y2+offset)
			g.dc.LineTo(x3+offset, y3+offset)
			g.dc.MoveTo(x2+offset, y2+offset)
			g.dc.LineTo(x4+offset, y4+offset)
		}
	}, opt)
}

// Grid 绘制网格
func (g *Graphics) Grid(x, y, width, height, step float64, opt *DrawStyle) {
	g.draw(func(offset float64) {
		// 水平线
		for iy := y; iy <= y+height; iy += step {
			g.dc.MoveTo(x+offset, iy+offset)
			g.dc.LineTo(x+width+offset, iy+offset)
		}

		// 垂直线
		for ix := x; ix <= x+width; ix += step {
			g.dc.MoveTo(ix+offset, y+offset)
			g.dc.LineTo(ix+offset, y+height+offset)
		}
	}, opt)
}

// Cross 绘制十字标记
func (g *Graphics) Cross(x, y, size float64, opt *DrawStyle) {
	half := size / 2
	g.draw(func(offset float64) {
		// 水平线
		g.dc.MoveTo(x-half+offset, y+offset)
		g.dc.LineTo(x+half+offset, y+offset)

		// 垂直线
		g.dc.MoveTo(x+offset, y-half+offset)
		g.dc.LineTo(x+offset, y+half+offset)
	}, opt)
}

// RandBG 绘制随机干扰背景（1-10档）
// 档位说明:
//
//	1-3级: 轻微干扰，适合验证码文本前的背景
//	4-6级: 中等干扰，适合文本后的干扰层
//	7-10级: 强干扰，有效防止OCR识别
func (g *Graphics) RandBG(level int) {
	if level < 1 {
		level = 1
	} else if level > 10 {
		level = 10
	}

	bounds := g.dc.Image().Bounds()
	w, h := bounds.Dx(), bounds.Dy()

	// 根据级别确定干扰元素数量 - 大幅增加密度
	elements := 30 + level*150 // 30到1530个元素

	// 绘制多种干扰元素 - 提高不透明度和尺寸
	for i := 0; i < elements; i++ {
		// 随机位置
		x := rand.Float64() * float64(w)
		y := rand.Float64() * float64(h)

		// 大幅提高透明度 - 减少半透明效果
		minAlpha := 120
		maxAlpha := 230
		if level >= 7 {
			minAlpha = 150
			maxAlpha = 255
		}
		r := uint8(rand.Intn(180))
		gVal := uint8(rand.Intn(180))
		bVal := uint8(rand.Intn(180))
		a := uint8(minAlpha + rand.Intn(maxAlpha-minAlpha))
		color := fmt.Sprintf("#%02X%02X%02X%02X", r, gVal, bVal, a)

		// 提高元素尺寸上限
		minSize := float64(1)
		maxSize := 7.0 + float64(level)*1.5 // 最大尺寸从10提高到20
		size := rand.Float64()*(maxSize-minSize) + minSize

		// 线宽也要随级别增加
		lineWidth := 0.5 + rand.Float64()*(0.5+float64(level)*0.3)

		// 元素选择权重
		elementType := rand.Intn(100)

		// 增加高等级特殊干扰的概率
		if level >= 7 && rand.Intn(100) < (level-6)*15 {
			elementType = 95 + rand.Intn(5) // 特殊干扰类型
		}

		switch {
		case elementType < 20: // 20%概率画点
			g.Point(x, y, &color)

		case elementType < 40: // 20%概率画短线
			angle := rand.Float64() * 2 * math.Pi
			length := 3 + rand.Float64()*float64(level)*3
			x2 := x + math.Cos(angle)*length
			y2 := y + math.Sin(angle)*length
			g.Line(x, y, x2, y2, &DrawStyle{
				LineColor: color,
				LineWidth: lineWidth,
			})

		case elementType < 60: // 20%概率画小圆
			radius := 0.5 + rand.Float64()*size
			g.Circle(x, y, radius, &DrawStyle{
				LineWidth: lineWidth,
				LineColor: color,
			})

		case elementType < 80: // 20%概率画小矩形 - 增加比例
			w := 1 + rand.Float64()*size*5
			h := 1 + rand.Float64()*size*3
			g.Rect(x, y, w, h, &DrawStyle{
				LineWidth: lineWidth,
				LineColor: color,
			})

		case elementType < 95: // 15%概率画微弧
			startAngle := rand.Float64() * 2 * math.Pi
			endAngle := startAngle + math.Pi/2 + rand.Float64()*math.Pi
			g.Arc(x, y, size, startAngle, endAngle, &DrawStyle{
				LineWidth: lineWidth,
				LineColor: color,
			})

		default: // 5%概率画特殊干扰
			// 随机选择一种高级干扰
			switch rand.Intn(4) {
			case 0: // 复杂多边形
				points := make([]float64, 0, 14)
				for j := 0; j < 7; j++ {
					points = append(points, x+rand.Float64()*size*3, y+rand.Float64()*size*3)
				}
				g.Polygon(points, &DrawStyle{
					LineWidth: lineWidth,
					LineColor: color,
					FillColor: color,
				})

			case 1: // 交叉网格
				size := 2 + rand.Float64()*size
				g.Line(x-size, y, x+size, y, &DrawStyle{LineColor: color, LineWidth: lineWidth})
				g.Line(x, y-size, x, y+size, &DrawStyle{LineColor: color, LineWidth: lineWidth})
				g.Line(x-size, y-size, x+size, y+size, &DrawStyle{LineColor: color, LineWidth: lineWidth})
				g.Line(x+size, y-size, x-size, y+size, &DrawStyle{LineColor: color, LineWidth: lineWidth})

			case 2: // 扇形环
				inner := size * 0.3
				outer := size
				start := rand.Float64() * 2 * math.Pi
				end := start + math.Pi/2 + rand.Float64()*math.Pi
				g.ArcRing(x, y, inner, outer, start, end, &DrawStyle{
					LineWidth: lineWidth,
					LineColor: color,
					FillColor: color,
				})

			case 3: // 星形
				points := 4 + rand.Intn(5)
				inner := size * 0.4
				outer := size
				g.Star(points, x, y, outer, inner, &DrawStyle{
					LineWidth: lineWidth,
					LineColor: color,
					FillColor: color,
				})
			}
		}
	}

	// 高级干扰特性
	if level >= 7 {
		// 增加高级干扰曲线的数量
		g.drawCurveDisturbance(w, h, level)

		// 增加噪点干扰
		if level >= 8 {
			g.addNoise(level, w, h)
		}
	}
}

// 绘制干扰曲线 - 修复参数错误
func (g *Graphics) drawCurveDisturbance(w, h, level int) {
	// 大幅增加曲线数量
	curves := 15 + (level-7)*20
	for i := 0; i < curves; i++ {
		// 使用更不透明的颜色
		r := uint8(rand.Intn(150))
		gVal := uint8(rand.Intn(150))
		bVal := uint8(rand.Intn(150))
		a := uint8(160 + rand.Intn(80))
		color := fmt.Sprintf("#%02X%02X%02X%02X", r, gVal, bVal, a)

		// 生成控制点 - 避免单个点问题
		points := make([]float64, 0, 8)
		for j := 0; j < 4; j++ {
			points = append(points, rand.Float64()*float64(w))
			points = append(points, rand.Float64()*float64(h))
		}

		// 绘制曲线 - 使用更宽的线条
		g.BezierCurve(points, &DrawStyle{
			LineColor: color,
			LineWidth: 1.0 + rand.Float64()*3.0,
		})
	}
}

// 添加噪点干扰 - 修复并增强效果
func (g *Graphics) addNoise(level int, w, h int) {
	// 创建噪点图层
	noiseImg := image.NewRGBA(image.Rect(0, 0, w, h))

	// 设置噪点密度 - 随等级增加
	density := 0.002 + float64(level-8)*0.003

	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			if rand.Float64() < density {
				// 随机颜色 - 高对比度
				r := uint8(rand.Intn(200))
				g := uint8(rand.Intn(200))
				b := uint8(rand.Intn(200))
				a := uint8(160 + rand.Intn(80))
				noiseImg.SetRGBA(x, y, color.RGBA{r, g, b, a})
			} else {
				// 透明点
				noiseImg.SetRGBA(x, y, color.RGBA{0, 0, 0, 0})
			}
		}
	}

	// 应用高斯模糊使噪点更自然
	if level > 8 {
		blurred := imaging.Blur(noiseImg, 0.8+float64(level-8)*0.4)
		g.dc.DrawImage(blurred, 0, 0)
	} else {
		g.dc.DrawImage(noiseImg, 0, 0)
	}
}
