package utils

import (
	"fmt"
	"os"
	"path/filepath"
	"testing"
)

// getProjectRoot 获取项目根目录
func getProjectRoot() string {
	// 假设测试从项目根目录运行
	dir, _ := os.Getwd()
	// 向上查找 go.mod 确定项目根目录
	for {
		if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
			return dir
		}
		parent := filepath.Dir(dir)
		if parent == dir {
			break
		}
		dir = parent
	}
	return ""
}

// TestGenerateCompetitorReportPDF 测试生成竞品报告PDF
func TestGenerateCompetitorReportPDF1(t *testing.T) {
	// 获取项目根目录
	root := getProjectRoot()
	fmt.Printf("项目根目录: %s\n", root)

	// 准备测试数据
	data := CompetitorReportData{
		HighlightAnalysis: HighlightAnalysisData{
			Summary: "本视频通过展示产品使用的真实场景，突出用户产品优势和痛点，内容详实且具有吸引力。",
			Points: PointsData{
				Theme:       "标题简洁有力，突出核心卖点'省时省力'，引发用户好奇心",
				Narrative:   "采用情景剧形式展示产品使用场景，剧情贴近生活，易引发共鸣",
				Content:     "通过前后对比展示产品效果，直观呈现产品价值",
				Copywriting: "文案简洁明了，突出用户痛点解决方案，语气亲切自然",
				Data:        "点赞量10万+，评论5000+，分享2万+，数据表现优异",
				Music:       "背景音乐节奏轻快，与视频内容匹配度高，增强观看体验",
			},
		},
		DataPerformance: DataPerformanceData{
			Views:      "播放量突破500万，推荐流量占比60%，自然流量表现优秀",
			Completion: "完播率45%，高于同类视频平均值（30%），前3秒吸引力强",
			Engagement: "点赞率2%，评论率0.1%，分享率0.4%，互动数据表现优秀",
		},
		OverallSummary: "整体来看，该竞品视频在内容策划、表现形式和互动数据方面都表现优秀。优势在于：1）内容真实可信，通过实际使用场景展示产品效果；2）剧情设计合理，前3秒抓住用户注意力；3）文案简洁有力，直击用户痛点。建议优化方向：1）可以增加更多用户评价内容，增强可信度；2）适当增加福利引导，提高转化率；3）结尾可以增加引导关注话术，提升粉丝沉淀。",
	}

	// 模板路径
	templatePath := filepath.Join(root, "data", "竞品报告pdf模板.pdf")
	// 输出路径
	outputPath := filepath.Join(root, "data", "output", "竞品报告测试_multicell.pdf")

	// 确保输出目录存在
	outputDir := filepath.Dir(outputPath)
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		t.Errorf("创建输出目录失败: %v", err)
		return
	}

	// 调用函数生成PDF
	err := GenerateCompetitorReportPDF(templatePath, outputPath, data)
	if err != nil {
		t.Errorf("生成竞品报告PDF失败: %v", err)
		return
	}

	fmt.Printf("PDF生成成功: %s\n", outputPath)
}

// TestGenerateCompetitorReportPDFImageOnly 测试仅图片的竞品报告PDF（无配乐和完播率）
func TestGenerateCompetitorReportPDFImageOnly(t *testing.T) {
	// 获取项目根目录
	root := getProjectRoot()

	// 准备测试数据（仅图片，没有视频的配乐和完播率）
	data := CompetitorReportData{
		HighlightAnalysis: HighlightAnalysisData{
			Summary: "该图文内容通过精美的视觉设计和精准的标签定位，成功吸引目标用户关注。",
			Points: PointsData{
				Theme:       "标题设置悬念，引发用户点击欲望",
				Narrative:   "采用九宫格形式展示产品特点，视觉冲击力强",
				Content:     "内容排版清晰，重点突出，便于用户快速获取信息",
				Copywriting: "文案简洁，配合表情符号增加趣味性",
				Data:        "收藏量5万+，评论1000+，分享8000+",
				Music:       "", // 图片无配乐
			},
		},
		DataPerformance: DataPerformanceData{
			Views:      "曝光量100万+，点击率3%，表现良好",
			Completion: "", // 图文无完播率
			Engagement: "收藏率5%，评论率0.1%，分享率0.8%",
		},
		OverallSummary: "该图文内容整体表现优秀，特别是在视觉设计和内容排版方面。亮点：1）九宫格形式统一，视觉效果好；2）标签设置精准，触达目标用户；3）发布时间合理，获得更多曝光。优化建议：1）可以增加更多用户案例展示；2）适当加入互动话题，提高评论量。",
	}

	// 模板路径
	templatePath := filepath.Join(root, "data", "竞品报告pdf模板.pdf")
	// 输出路径
	outputPath := filepath.Join(root, "data", "output", "竞品报告测试_图文11.pdf")

	// 确保输出目录存在
	outputDir := filepath.Dir(outputPath)
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		t.Errorf("创建输出目录失败: %v", err)
		return
	}

	// 调用函数生成PDF
	err := GenerateCompetitorReportPDF(templatePath, outputPath, data)
	if err != nil {
		t.Errorf("生成竞品报告PDF失败: %v", err)
		return
	}

	fmt.Printf("PDF生成成功: %s\n", outputPath)
}

// TestGenerateCompetitorReportPDFWithImage 测试带图片的竞品报告PDF
// 注意：此测试需要网络连接来下载图片，如果网络不可用会被跳过
func TestGenerateCompetitorReportPDFWithImage1(t *testing.T) {
	// 获取项目根目录
	root := getProjectRoot()

	// 准备测试数据（带图片）
	// 使用一个已知可用的测试图片URL
	data := CompetitorReportData{
		HighlightAnalysis: HighlightAnalysisData{
			Summary: "本视频通过展示产品使用的真实场景，突出用户产品优势和痛点，内容详实且具有吸引力。",
			Points: PointsData{
				Theme:       "标题简洁有力，突出核心卖点'省时省力'，引发用户好奇心",
				Narrative:   "采用情景剧形式展示产品使用场景，剧情贴近生活，易引发共鸣",
				Content:     "通过前后对比展示产品效果，直观呈现产品价值",
				Copywriting: "文案简洁明了，突出用户痛点解决方案，语气亲切自然",
				Data:        "点赞量10万+，评论5000+，分享2万+，数据表现优异",
				Music:       "背景音乐节奏轻快，与视频内容匹配度高，增强观看体验",
			},
		},
		DataPerformance: DataPerformanceData{
			Views:      "播放量突破500万，推荐流量占比60%，自然流量表现优秀",
			Completion: "完播率45%，高于同类视频平均值（30%），前3秒吸引力强",
			Engagement: "点赞率2%，评论率0.1%，分享率0.4%，互动数据表现优秀",
		},
		OverallSummary: "整体来看，该竞品视频在内容策划、表现形式和互动数据方面都表现优秀。",
		ImageURL:       "https://cdn-test.szjixun.cn/fonchain-main/test/image/12345/artwork/0.png", // 测试用图片URL
	}

	// 模板路径
	templatePath := filepath.Join(root, "data", "竞品报告pdf模板.pdf")
	// 输出路径
	outputPath := filepath.Join(root, "data", "output", "竞品报告测试_带图片.pdf")

	// 确保输出目录存在
	outputDir := filepath.Dir(outputPath)
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		t.Errorf("创建输出目录失败: %v", err)
		return
	}

	// 调用函数生成PDF
	err := GenerateCompetitorReportPDF(templatePath, outputPath, data)
	if err != nil {
		t.Logf("图片下载测试跳过（网络问题）: %v", err)
		t.Skip("网络不可用，跳过图片测试")
		return
	}

	fmt.Printf("PDF生成成功: %s\n", outputPath)
}

// TestGenerateCompetitorReportPDFMixedContent 测试中英混合、数字、符号的复杂情况
func TestGenerateCompetitorReportPDFMixedContent(t *testing.T) {
	root := getProjectRoot()

	// 准备包含中英混合、数字、符号的复杂测试数据
	data := CompetitorReportData{
		HighlightAnalysis: HighlightAnalysisData{
			Summary: "这是一个关于2024年短视频创作的爆款分析报告！视频总播放量达到1.2亿次，点赞率8.5%（远超行业平均3.2%）。内容包括：①生活技巧类占比40% ②知识科普类30% ③娱乐搞笑类30%。推荐算法推荐流量占比85%，搜索流量10%，其他渠道5%。",
			Points: PointsData{
				Theme:       "标题：【逆袭】3个月从0到100万粉丝！我是如何做到的？必看！🔥",
				Narrative:   "采用问题-解决叙事结构：前3秒抛出痛点你还在为XX发愁吗，然后展示解决方案ABC",
				Content:     "内容分为3个板块：①前置干货预告15秒 ②核心内容展示30秒 ③互动引导15秒",
				Copywriting: "文案使用了大量emoji表情🔥💯👍，增加年轻化气息！结尾一句评论区见强化互动",
				Data:        "点赞率8.5%，高于同类平均3.2%，转发率2.1%，评论数2.3万条，评论区活跃度TOP10%",
				Music:       "使用热门BGM孤勇者前奏3秒，配合画面节奏卡点！音量为Original-3dB",
			},
		},
		DataPerformance: DataPerformanceData{
			Views:      "发布24小时内播放量突破500万，48小时达到1200万，72小时稳定在1500万。推荐流量占比85%，搜索流量占比10%，其他渠道5%。数据表现：PV=15000000，UV=8500000。",
			Completion: "平均完播率45.2%，高于行业均值28%，3秒留存率72%，5秒完播率58%，10秒完播率35%，属于高质量流量。平均观看时长18.5秒，视频总时长42秒。",
			Engagement: "点赞数128000，点赞率0.85%，评论数23000，其中神评论占比15%，高赞评论TOP3：①学到了 ②太棒了 ③收藏了，分享数56000。评论区@相关账号12个，引发二次传播。",
		},
		OverallSummary: "该视频成功因素：①标题使用数字热门词激发点击逆袭必看 ②内容结构清晰，每15秒一个高潮点 ③BGM选择契合内容情绪孤勇者 ④评论区运营到位。建议优化：1）可增加合集功能，将同类内容串联 2）提升粉丝粘性到10%以上 3）适当增加直播预告。整体来看，这是一条典型的爆款体质视频，值得借鉴学习！数据支撑：ROI=3.5，CPM=25元，CPC=0.8元。",
		ImageURL:       "",
	}

	// 模板路径
	templatePath := filepath.Join(root, "data", "竞品报告pdf模板.pdf")
	// 输出路径
	outputPath := filepath.Join(root, "data", "output", "竞品报告测试_中英混合.pdf")

	// 确保输出目录存在
	outputDir := filepath.Dir(outputPath)
	if err := os.MkdirAll(outputDir, 0755); err != nil {
		t.Errorf("创建输出目录失败: %v", err)
		return
	}

	// 调用函数生成PDF
	err := GenerateCompetitorReportPDF(templatePath, outputPath, data)
	if err != nil {
		t.Errorf("生成PDF失败: %v", err)
		return
	}

	fmt.Printf("PDF生成成功（中英混合测试）: %s\n", outputPath)
}

// TestTruncateTextByRune 测试按字符权重截断文本
func TestTruncateTextByRune(t *testing.T) {
	tests := []struct {
		name     string
		text     string
		maxWidth float64
		want     string
	}{
		{
			name:     "空文本",
			text:     "",
			maxWidth: 10,
			want:     "",
		},
		{
			name:     "纯中文截断",
			text:     "这是一段很长的中文内容需要被截断",
			maxWidth: 10,
			want:     "这是一段很长的中文内", // 10个中文字=10，正好
		},
		{
			name:     "纯英文截断（按0.5计算）",
			text:     "abcdefghijklmnop",
			maxWidth: 5,
			want:     "abcdefghij", // 10个字母=5.0，正好
		},
		{
			name:     "数字截断（按0.5计算）",
			text:     "1234567890",
			maxWidth: 3,
			want:     "123456", // 6个数字=3.0，正好
		},
		{
			name:     "中英混合截断",
			text:     "hello你好world世界",
			maxWidth: 6,
			// h(0.5)+e(0.5)+l(0.5)+l(0.5)+o(0.5)=2.5
			// +你(1)+好(1)=4.5
			// +w(0.5)+o(0.5)+r(0.5)+l(0.5)=2，再加就超过6了
			// 所以应该是 hello你好wor
			want: "hello你好wor",
		},
		{
			name:     "符号截断（按0.5计算）",
			text:     "hello,world!",
			maxWidth: 5,
			// h(0.5)+e(0.5)+l(0.5)+l(0.5)+o(0.5)+,(0.5)=3
			// +w(0.5)+o(0.5)+r(0.5)+l(0.5)+d(0.5)+!(0.5)=6，超过5
			// 所以保留 hello,worl
			want: "hello,worl",
		},
		{
			name:     "截断到正好边界",
			text:     "中文字符",
			maxWidth: 4,
			want:     "中文字符", // 4个中文字=4.0，正好
		},
		{
			name:     "宽度为0",
			text:     "hello",
			maxWidth: 0,
			want:     "",
		},
		{
			name:     "宽度小于单个字符",
			text:     "hello",
			maxWidth: 0.3,
			want:     "",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := TruncateTextByRune(tt.text, tt.maxWidth)
			if got != tt.want {
				t.Errorf("TruncateTextByRune(%q, %v) = %q, want %q", tt.text, tt.maxWidth, got, tt.want)
			}
		})
	}
}
