package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"
)

type YuafengAPIFreeResponse struct {
	Data struct {
		Song      string `json:"song"`
		Singer    string `json:"singer"`
		Cover     string `json:"cover"`
		AlbumName string `json:"album_name"`
		Music     string `json:"music"`
		Lyric     string `json:"lyric"`
	} `json:"data"`
}

// 枫雨API response handler with multiple API fallback
func YuafengAPIResponseHandler(sources, song, singer string) MusicItem {
	fmt.Printf("[Info] Fetching music data for %s by %s\n", song, singer)
	
	// API hosts to try in order
	apiHosts := []string{
		"https://api.yuafeng.cn",
		"https://api-v2.yuafeng.cn",
		"https://api.yaohud.cn",
	}
	
	var pathSuffix string
	switch sources {
	case "kuwo":
		pathSuffix = "/API/ly/kwmusic.php"
	case "netease":
		pathSuffix = "/API/ly/wymusic.php"
	case "migu":
		pathSuffix = "/API/ly/mgmusic.php"
	case "baidu":
		pathSuffix = "/API/ly/bdmusic.php"
	default:
		return MusicItem{}
	}
	
	var fallbackItem MusicItem // 保存第一个有音乐但没歌词的结果
	
	// Try each API host - 尝试所有API直到找到歌词
	for i, host := range apiHosts {
		fmt.Printf("[Info] Trying API %d/%d: %s\n", i+1, len(apiHosts), host)
		item := tryFetchFromAPI(host+pathSuffix, song, singer)
		if item.Title != "" {
			// 如果有歌词，立即返回
			if item.LyricURL != "" {
				fmt.Printf("[Success] ✓ Found music WITH lyrics from %s\n", host)
				return item
			}
			// 如果没有歌词但有音乐，保存作为fallback并继续尝试
			if fallbackItem.Title == "" {
				fallbackItem = item
				fmt.Printf("[Info] ○ Got music WITHOUT lyrics from %s, saved as fallback, continuing...\n", host)
			} else {
				fmt.Printf("[Info] ○ Got music WITHOUT lyrics from %s, trying next API...\n", host)
			}
		} else {
			fmt.Printf("[Warning] × API %s failed, trying next...\n", host)
		}
	}
	
	// 所有API都试完了
	if fallbackItem.Title != "" {
		fmt.Println("[Info] ▶ All 3 APIs tried - no lyrics found, returning music without lyrics")
		return fallbackItem
	}
	
	fmt.Println("[Error] ✗ All 3 APIs failed completely")
	return MusicItem{}
}

// tryFetchFromAPI attempts to fetch music data from a single API endpoint
func tryFetchFromAPI(APIurl, song, singer string) MusicItem {
	resp, err := http.Get(APIurl + "?msg=" + song + "&n=1")
	if err != nil {
		fmt.Println("[Error] Error fetching the data from API:", err)
		return MusicItem{}
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("[Error] Error reading the response body:", err)
		return MusicItem{}
	}
	
	// Check if response is HTML (starts with < character)
	bodyStr := string(body)
	if len(bodyStr) > 0 && bodyStr[0] == '<' {
		fmt.Println("[Warning] API returned HTML instead of JSON")
		fmt.Printf("[Debug] Saving HTML response to debug.html for inspection\n")
		
		// Save HTML to file for debugging
		os.WriteFile("debug_api_response.html", body, 0644)
		fmt.Println("[Info] HTML response saved to debug_api_response.html")
		
		// Try to extract JSON from HTML if embedded
		// Look for common patterns where JSON might be embedded
		if strings.Contains(bodyStr, `"song"`) && strings.Contains(bodyStr, `"singer"`) {
			fmt.Println("[Info] Attempting to extract JSON from HTML...")
			// Try to find JSON block in HTML
			jsonStart := strings.Index(bodyStr, "{")
			jsonEnd := strings.LastIndex(bodyStr, "}")
			if jsonStart != -1 && jsonEnd != -1 && jsonEnd > jsonStart {
				jsonStr := bodyStr[jsonStart : jsonEnd+1]
				var response YuafengAPIFreeResponse
				err = json.Unmarshal([]byte(jsonStr), &response)
				if err == nil {
					fmt.Println("[Success] Extracted JSON from HTML successfully")
					body = []byte(jsonStr)
					goto parseSuccess
				}
			}
		}
		
		fmt.Println("[Error] Cannot parse HTML response - API may be unavailable")
		return MusicItem{}
	}
	
parseSuccess:
	var response YuafengAPIFreeResponse
	err = json.Unmarshal(body, &response)
	if err != nil {
		fmt.Println("[Error] Error parsing API response:", err)
		return MusicItem{}
	}

	// Create directory
	dirName := fmt.Sprintf("./files/cache/music/%s-%s", response.Data.Singer, response.Data.Song)
	err = os.MkdirAll(dirName, 0755)
	if err != nil {
		fmt.Println("[Error] Error creating directory:", err)
		return MusicItem{}
	}

	if response.Data.Music == "" {
		fmt.Println("[Warning] Music URL is empty")
		return MusicItem{}
	}

	// 获取封面扩展名
	ext := filepath.Ext(response.Data.Cover)
	
	// 保存远程 URL 到文件，供 file.go 流式转码使用
	remoteURLFile := filepath.Join(dirName, "remote_url.txt")
	os.WriteFile(remoteURLFile, []byte(response.Data.Music), 0644)
	
	// ========== 关键优化：先返回，后台异步处理 ==========
	// 把下载、转码等耗时操作放到 goroutine 异步执行
	go func() {
		fmt.Printf("[Async] Starting background processing for: %s - %s\n", response.Data.Singer, response.Data.Song)
		var wg sync.WaitGroup
		
		// ========== 1. 歌词处理 ==========
		wg.Add(1)
		go func() {
			defer wg.Done()
			lyricData := response.Data.Lyric
			if lyricData == "获取歌词失败" {
				fetchLyricFromYaohu(response.Data.Song, response.Data.Singer, dirName)
			} else if !strings.HasPrefix(lyricData, "http://") && !strings.HasPrefix(lyricData, "https://") {
				// 直接写入歌词内容
				lines := strings.Split(lyricData, "\n")
				lyricFilePath := filepath.Join(dirName, "lyric.lrc")
				file, err := os.Create(lyricFilePath)
				if err == nil {
					timeTagRegex := regexp.MustCompile(`^\[(\d+(?:\.\d+)?)\]`)
					for _, line := range lines {
						match := timeTagRegex.FindStringSubmatch(line)
						if match != nil {
							timeInSeconds, _ := strconv.ParseFloat(match[1], 64)
							minutes := int(timeInSeconds / 60)
							seconds := int(timeInSeconds) % 60
							milliseconds := int((timeInSeconds-float64(seconds))*1000) / 100 % 100
							formattedTimeTag := fmt.Sprintf("[%02d:%02d.%02d]", minutes, seconds, milliseconds)
							line = timeTagRegex.ReplaceAllString(line, formattedTimeTag)
						}
						file.WriteString(line + "\r\n")
					}
					file.Close()
					fmt.Printf("[Async] Lyrics saved for: %s - %s\n", response.Data.Singer, response.Data.Song)
				}
			} else {
				downloadFile(filepath.Join(dirName, "lyric.lrc"), lyricData)
			}
		}()
		
		// ========== 2. 封面处理 ==========
		wg.Add(1)
		go func() {
			defer wg.Done()
			downloadFile(filepath.Join(dirName, "cover"+ext), response.Data.Cover)
		}()
		
		// ========== 3. 音频转码 ==========
		wg.Add(1)
		go func() {
			defer wg.Done()
			musicExt, err := getMusicFileExtension(response.Data.Music)
			if err != nil {
				fmt.Println("[Async Warning] Cannot identify music format, using default .mp3:", err)
				musicExt = ".mp3"
			}
			
			outputMp3 := filepath.Join(dirName, "music.mp3")
			err = streamConvertAudio(response.Data.Music, outputMp3)
			if err != nil {
				fmt.Println("[Async Error] Error stream converting audio:", err)
				// 备用方案
				err = downloadFile(filepath.Join(dirName, "music_full"+musicExt), response.Data.Music)
				if err == nil {
					compressAndSegmentAudio(filepath.Join(dirName, "music_full"+musicExt), dirName)
				}
			}
		}()
		
		wg.Wait() // 等待所有任务完成
		fmt.Printf("[Async] Background processing completed for: %s - %s\n", response.Data.Singer, response.Data.Song)
	}()

	// ========== 立即返回 JSON，使用标准 .mp3 URL ==========
	// 注意：返回标准的 .mp3 URL，file.go 会在文件不存在时自动触发流式转码
	basePath := "/cache/music/" + url.QueryEscape(response.Data.Singer+"-"+response.Data.Song)
	
	return MusicItem{
		Title:        response.Data.Song,
		Artist:       response.Data.Singer,
		CoverURL:     basePath + "/cover" + ext,
		LyricURL:     basePath + "/lyric.lrc",
		AudioFullURL: basePath + "/music.mp3", // 标准 .mp3 URL
		AudioURL:     basePath + "/music.mp3",
		M3U8URL:      basePath + "/music.m3u8",
		Duration:     0, // 时长后台获取，先返回0
	}
}

// YaohuQQMusicResponse 妖狐QQ音乐API响应结构
type YaohuQQMusicResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data struct {
		Songname string `json:"songname"`
		Name     string `json:"name"`
		Picture  string `json:"picture"`
		Musicurl string `json:"musicurl"`
		Viplrc   string `json:"viplrc"` // VIP歌词URL链接
	} `json:"data"`
}

// YaohuLyricResponse 妖狐歌词API响应结构
type YaohuLyricResponse struct {
	Code int `json:"code"`
	Data struct {
		Lyric string `json:"lyric"`
	} `json:"data"`
}

// fetchLyricFromYaohu 从妖狐数据QQ音乐VIP API获取歌词（备用方案）
func fetchLyricFromYaohu(songName, artistName, dirPath string) bool {
	apiKey := "bXO9eq1pomwR1cyVhzX"
	apiURL := "https://api.yaohud.cn/api/music/qq"
	
	// 构建请求URL - QQ音乐VIP接口
	requestURL := fmt.Sprintf("%s?key=%s&msg=%s&n=1&size=hq", 
		apiURL, 
		apiKey, 
		url.QueryEscape(songName))
	
	fmt.Printf("[Info] 🎵 Trying to fetch lyric from Yaohu QQ Music VIP API for: %s - %s\n", artistName, songName)
	
	// 创建带超时的HTTP客户端
	client := &http.Client{
		Timeout: 10 * time.Second,
	}
	
	resp, err := client.Get(requestURL)
	if err != nil {
		fmt.Printf("[Error] Yaohu QQ Music API request failed: %v\n", err)
		return false
	}
	defer resp.Body.Close()
	
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("[Error] Failed to read API response: %v\n", err)
		return false
	}
	
	var qqResp YaohuQQMusicResponse
	err = json.Unmarshal(body, &qqResp)
	if err != nil {
		fmt.Printf("[Error] Failed to parse API response: %v\n", err)
		return false
	}
	
	// 检查响应状态
	if qqResp.Code != 200 {
		fmt.Printf("[Warning] API returned error (code: %d, msg: %s)\n", qqResp.Code, qqResp.Msg)
		return false
	}
	
	// 检查viplrc URL是否存在
	if qqResp.Data.Viplrc == "" {
		fmt.Printf("[Warning] No lyric URL available for: %s\n", songName)
		return false
	}
	
	fmt.Printf("[Info] 🔍 Found song: %s - %s\n", qqResp.Data.Songname, qqResp.Data.Name)
	fmt.Printf("[Info] 📝 Fetching lyric from: %s\n", qqResp.Data.Viplrc)
	
	// Step 2: 获取实际歌词内容
	resp2, err := client.Get(qqResp.Data.Viplrc)
	if err != nil {
		fmt.Printf("[Error] Failed to fetch lyric from viplrc URL: %v\n", err)
		return false
	}
	defer resp2.Body.Close()
	
	body2, err := io.ReadAll(resp2.Body)
	if err != nil {
		fmt.Printf("[Error] Failed to read lyric response: %v\n", err)
		return false
	}
	
	// viplrc URL直接返回LRC文本，不是JSON
	lyricText := string(body2)
	
	// 检查歌词内容
	if lyricText == "" || len(lyricText) < 10 {
		fmt.Printf("[Warning] No lyrics returned from viplrc URL\n")
		return false
	}
	
	// 将歌词写入文件
	lyricFilePath := filepath.Join(dirPath, "lyric.lrc")
	file, err := os.Create(lyricFilePath)
	if err != nil {
		fmt.Printf("[Error] Failed to create lyric file: %v\n", err)
		return false
	}
	defer file.Close()
	
	// 写入歌词内容（LRC文本格式）
	_, err = file.WriteString(lyricText)
	if err != nil {
		fmt.Printf("[Error] Failed to write lyric content: %v\n", err)
		return false
	}
	
	fmt.Printf("[Success] ✅ Lyric fetched from Yaohu QQ Music VIP API and saved to %s\n", lyricFilePath)
	return true
}

// getRemoteMusicURLOnly 只获取远程音乐URL，不下载不处理（用于实时流式播放）
func getRemoteMusicURLOnly(song, singer string) string {
	fmt.Printf("[Info] Getting remote music URL for: %s - %s\n", singer, song)
	
	// 尝试多个 API
	apiHosts := []string{
		"https://api.yuafeng.cn",
		"https://api-v2.yuafeng.cn",
	}
	
	sources := []string{"kuwo", "netease", "migu"}
	pathMap := map[string]string{
		"kuwo":    "/API/ly/kwmusic.php",
		"netease": "/API/ly/wymusic.php",
		"migu":    "/API/ly/mgmusic.php",
	}
	
	client := &http.Client{Timeout: 15 * time.Second}
	
	for _, host := range apiHosts {
		for _, source := range sources {
			path := pathMap[source]
			apiURL := fmt.Sprintf("%s%s?song=%s&singer=%s", host, path, url.QueryEscape(song), url.QueryEscape(singer))
			
			resp, err := client.Get(apiURL)
			if err != nil {
				continue
			}
			defer resp.Body.Close()
			
			body, err := io.ReadAll(resp.Body)
			if err != nil {
				continue
			}
			
			var response YuafengAPIFreeResponse
			if err := json.Unmarshal(body, &response); err != nil {
				continue
			}
			
			if response.Data.Music != "" {
				fmt.Printf("[Success] Got remote URL from %s: %s\n", source, response.Data.Music)
				return response.Data.Music
			}
		}
	}
	
	fmt.Println("[Error] Failed to get remote music URL from all APIs")
	return ""
}
