package font

import (
	"bytes"
	"fmt"
	"image/color"
	"io/fs"
	"log"
	"os"
	"path/filepath"
	"strings"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/text/v2"
	"golang.org/x/image/font/gofont/goregular"
)

// FontRenderer handles text rendering with assets/fonts directory support
type FontRenderer struct {
	face *text.GoTextFace
}

// NewFontRenderer creates a new font renderer using only assets/fonts directory
func NewFontRenderer() *FontRenderer {
	var fontData []byte
	var fontSource string

	// 优先加载 assets/fonts 目录中的字体
	if data, source := loadFromAssetsDirectory(); data != nil {
		fontData = data
		fontSource = source
		log.Printf("✅ 使用项目字体: %s", source)
	} else {
		// 如果没有找到项目字体，使用 Go 默认字体
		fontData = goregular.TTF
		fontSource = "Go默认字体 (建议添加中文字体到 assets/fonts 目录)"
		log.Printf("⚠️  未找到项目字体，使用默认字体。建议将中文字体放入 assets/fonts/ 目录")
	}

	// 创建字体源
	source, err := createFontSource(fontData, fontSource)
	if err != nil {
		// 最终回退 - 使用 Go 默认字体
		log.Printf("❌ 字体加载失败，回退到默认字体: %v", err)
		source, err = text.NewGoTextFaceSource(bytes.NewReader(goregular.TTF))
		if err != nil {
			panic(fmt.Sprintf("无法加载默认字体: %v", err))
		}
		fontSource = "Go默认字体 (回退)"
	}

	face := &text.GoTextFace{
		Source: source,
		Size:   16,
	}

	log.Printf("🎨 字体系统初始化完成，使用: %s", fontSource)
	return &FontRenderer{
		face: face,
	}
}

// loadFromAssetsDirectory 专门扫描 assets/fonts 目录并加载字体文件
func loadFromAssetsDirectory() ([]byte, string) {
	// 尝试多个可能的路径
	possiblePaths := []string{
		"assets/fonts",                                    // 开发环境
		"Contents/Resources/assets/fonts",                 // macOS 应用包内部
		"../Resources/assets/fonts",                       // macOS 应用包相对路径
		filepath.Join(getExecutableDir(), "assets/fonts"), // 可执行文件同目录
	}

	var assetsPath string
	var found bool

	// 查找存在的资源路径
	for _, path := range possiblePaths {
		if _, err := os.Stat(path); err == nil {
			assetsPath = path
			found = true
			log.Printf("📁 找到字体目录: %s", path)
			break
		}
	}

	if !found {
		log.Printf("📁 未找到 assets/fonts 目录，已尝试路径: %v", possiblePaths)
		return nil, ""
	}

	// 扫描目录下的所有字体文件
	var fontFiles []string
	err := filepath.WalkDir(assetsPath, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}

		if !d.IsDir() {
			ext := strings.ToLower(filepath.Ext(path))
			if ext == ".ttf" || ext == ".ttc" || ext == ".otf" {
				fontFiles = append(fontFiles, path)
			}
		}
		return nil
	})

	if err != nil {
		log.Printf("❌ 扫描字体目录失败: %v", err)
		return nil, ""
	}

	if len(fontFiles) == 0 {
		log.Printf("📂 字体目录为空，请添加字体文件 (.ttf, .ttc, .otf)")
		return nil, ""
	}

	log.Printf("🔍 在 %s 找到 %d 个字体文件", assetsPath, len(fontFiles))

	// 字体优先级：微软雅黑 > 其他中文字体 > 任意字体
	fontPriorities := [][]string{
		{"msyh", "yahei", "microsoft"},           // 微软雅黑系列
		{"noto", "source", "思源", "源"},            // 思源/Noto系列
		{"pingfang", "hiragino", "苹方"},           // 苹果字体系列
		{"simhei", "simkai", "simsun", "宋", "黑"}, // 系统中文字体
	}

	// 按优先级查找字体
	for _, priorityGroup := range fontPriorities {
		for _, keyword := range priorityGroup {
			for _, fontFile := range fontFiles {
				fileName := strings.ToLower(filepath.Base(fontFile))
				if strings.Contains(fileName, keyword) {
					if data, err := tryLoadFont(fontFile); err == nil {
						log.Printf("🎯 找到优先字体 (%s): %s", keyword, fontFile)
						return data, fontFile
					} else {
						log.Printf("⚠️  字体文件损坏或不支持: %s, 错误: %v", fontFile, err)
					}
				}
			}
		}
	}

	// 如果没有找到优先字体，使用第一个可用的字体
	for _, fontFile := range fontFiles {
		if data, err := tryLoadFont(fontFile); err == nil {
			log.Printf("📝 使用可用字体: %s", fontFile)
			return data, fontFile
		} else {
			log.Printf("⚠️  跳过不可用字体: %s, 错误: %v", fontFile, err)
		}
	}

	log.Printf("❌ 字体目录中没有可用的字体文件")
	return nil, ""
}

// getExecutableDir 获取可执行文件所在目录
func getExecutableDir() string {
	execPath, err := os.Executable()
	if err != nil {
		log.Printf("⚠️  获取可执行文件路径失败: %v", err)
		return "."
	}
	return filepath.Dir(execPath)
}

// tryLoadFont 尝试加载字体文件并验证格式
func tryLoadFont(fontPath string) ([]byte, error) {
	data, err := os.ReadFile(fontPath)
	if err != nil {
		return nil, fmt.Errorf("读取字体文件失败: %w", err)
	}

	// 验证字体数据是否可以被解析
	_, err = createFontSource(data, fontPath)
	if err != nil {
		return nil, fmt.Errorf("字体格式验证失败: %w", err)
	}

	return data, nil
}

// createFontSource 创建字体源，处理可能的collection错误
func createFontSource(fontData []byte, fontSource string) (*text.GoTextFaceSource, error) {
	// 尝试直接加载
	source, err := text.NewGoTextFaceSource(bytes.NewReader(fontData))
	if err != nil {
		// 如果是 collection 错误，提供更详细的信息
		errStr := err.Error()
		if strings.Contains(errStr, "collection") {
			return nil, fmt.Errorf("TTC集合字体文件不支持，请使用TTF格式: %s", filepath.Base(fontSource))
		}
		return nil, fmt.Errorf("字体文件格式错误: %w", err)
	}

	return source, nil
}

// DrawText draws text at the specified position with proper Chinese support
func (fr *FontRenderer) DrawText(screen *ebiten.Image, str string, x, y float64, clr color.Color) {
	op := &text.DrawOptions{}
	op.GeoM.Translate(x, y)
	op.ColorScale.ScaleWithColor(clr)
	text.Draw(screen, str, fr.face, op)
}

// SetFontSize sets the font size
func (fr *FontRenderer) SetFontSize(size float64) {
	fr.face.Size = size
}

// MeasureText returns text dimensions with better accuracy
func (fr *FontRenderer) MeasureText(str string) (float64, float64) {
	width, _ := text.Measure(str, fr.face, 0)
	return width, fr.face.Size
}

// GetFontInfo returns information about the currently loaded font
func (fr *FontRenderer) GetFontInfo() string {
	return fmt.Sprintf("字体大小: %.1f", fr.face.Size)
}
