package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const tianapiStarURL = "https://apis.tianapi.com/star/index"

var zodiacToSign = map[string]string{
	"白羊座": "aries", "金牛座": "taurus", "双子座": "gemini", "巨蟹座": "cancer",
	"狮子座": "leo", "处女座": "virgo", "天秤座": "libra", "天蝎座": "scorpio",
	"射手座": "sagittarius", "摩羯座": "capricorn", "水瓶座": "aquarius", "双鱼座": "pisces",
}

type tianapiStarResp struct {
	Code   int `json:"code"`
	Result struct {
		List []struct {
			Type    string `json:"type"`
			Content string `json:"content"`
		} `json:"list"`
	} `json:"result"`
}

type horoscopeInfo struct {
	Zodiac     string `json:"zodiac"`
	Date       string `json:"date"`
	All        string `json:"all"`
	Love       string `json:"love"`
	Work       string `json:"work"`
	Money      string `json:"money"`
	Health     string `json:"health"`
	LuckyColor string `json:"luckyColor"`
	LuckyNum   string `json:"luckyNum"`
	Noble      string `json:"noble"`
	Summary    string `json:"summary"`
}

func horoscopeCachePath() string {
	return filepath.Join(configDir(), "horoscope_cache.json")
}

func saveHoroscopeCache(info *horoscopeInfo) {
	info.Date = time.Now().Format("2006-01-02")
	data, _ := json.Marshal(info)
	os.WriteFile(horoscopeCachePath(), data, 0644)
}

func loadHoroscopeCache() *horoscopeInfo {
	data, err := os.ReadFile(horoscopeCachePath())
	if err != nil {
		return nil
	}
	var info horoscopeInfo
	if json.Unmarshal(data, &info) != nil {
		return nil
	}
	return &info
}

func fetchHoroscope(zodiac string) *horoscopeInfo {
	sign := zodiacToSign[zodiac]
	if sign == "" {
		sign = "sagittarius"
	}

	key := loadConfig().tianapiKey()
	if key == "" {
		log.Println("未配置天聚数行 API Key")
		return nil
	}
	url := fmt.Sprintf("%s?key=%s&astro=%s", tianapiStarURL, key, sign)
	data, err := httpGet(url)
	if err != nil {
		log.Println("星座运势请求失败:", err)
		return nil
	}

	var resp tianapiStarResp
	if json.Unmarshal(data, &resp) != nil || resp.Code != 200 {
		log.Println("星座运势解析失败:", string(data))
		return nil
	}

	info := &horoscopeInfo{Zodiac: zodiac}
	for _, item := range resp.Result.List {
		switch item.Type {
		case "综合指数":
			info.All = strings.TrimSuffix(item.Content, "%")
		case "爱情指数":
			info.Love = strings.TrimSuffix(item.Content, "%")
		case "工作指数":
			info.Work = strings.TrimSuffix(item.Content, "%")
		case "财运指数":
			info.Money = strings.TrimSuffix(item.Content, "%")
		case "健康指数":
			info.Health = strings.TrimSuffix(item.Content, "%")
		case "幸运颜色":
			info.LuckyColor = item.Content
		case "幸运数字":
			info.LuckyNum = item.Content
		case "贵人星座":
			info.Noble = item.Content
		case "今日概述":
			info.Summary = strings.TrimSpace(item.Content)
		}
	}

	log.Printf("星座运势已获取: %s", zodiac)
	return info
}

func pushHoroscopeInfo(info *horoscopeInfo) {
	jsonData, _ := json.Marshal(info)
	log.Printf("星座运势JS: %s", string(jsonData[:min(len(jsonData), 120)]))
	js := fmt.Sprintf(`if(window.updateHoroscopeFromGo) window.updateHoroscopeFromGo(%s)`, string(jsonData))
	evalJS(js)
}

func pushHoroscope(zodiac string) {
	info := fetchHoroscope(zodiac)
	if info == nil {
		log.Println("星座运势: fetchHoroscope返回nil")
		return
	}
	saveHoroscopeCache(info)
	pushHoroscopeInfo(info)
}

func horoscopeLoop() {
	cfg := loadConfig()

	cached := loadHoroscopeCache()
	if cached != nil && !cfg.HideZodiac {
		pushHoroscopeInfo(cached)
	}

	time.Sleep(5 * time.Second)

	cfg = loadConfig()
	today := time.Now().Format("2006-01-02")
	if !cfg.HideZodiac && !(cached != nil && cached.Date == today && cached.Zodiac == cfg.Zodiac) {
		for i := 0; i < 3; i++ {
			pushHoroscope(cfg.Zodiac)
			cached := loadHoroscopeCache()
			if cached != nil && cached.Date == time.Now().Format("2006-01-02") && cached.Zodiac == cfg.Zodiac {
				break
			}
			time.Sleep(30 * time.Second)
		}
	}

	ticker := time.NewTicker(24 * time.Hour)
	for range ticker.C {
		cfg := loadConfig()
		if !cfg.HideZodiac {
			pushHoroscope(cfg.Zodiac)
		}
	}
}

func triggerHoroscopeRefresh(zodiac string) {
	go func() {
		pushHoroscope(zodiac)
	}()
}
