package main

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

const tianapiAIURL = "https://apis.tianapi.com/ai/index"

type aiNewsResp struct {
	Code   int `json:"code"`
	Result struct {
		Newslist []struct {
			ID          string `json:"id"`
			CTime       string `json:"ctime"`
			Title       string `json:"title"`
			Description string `json:"description"`
			Source      string `json:"source"`
			URL         string `json:"url"`
			PicUrl      string `json:"picUrl"`
		} `json:"newslist"`
	} `json:"result"`
}

type aiNewsItem struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	Source      string `json:"source"`
	CTime       string `json:"ctime"`
	URL         string `json:"url"`
	PicURL      string `json:"picUrl"`
}

var (
	aiNewsMu      sync.Mutex
	aiNewsCache   []aiNewsItem
	aiNewsCacheAt time.Time
)

func aiNewsCachePath() string {
	return filepath.Join(configDir(), "ainews_cache.json")
}

func fetchAINews() []aiNewsItem {
	aiNewsMu.Lock()
	if aiNewsCache != nil && time.Since(aiNewsCacheAt) < 2*time.Hour {
		cached := aiNewsCache
		aiNewsMu.Unlock()
		return cached
	}
	aiNewsMu.Unlock()

	key := loadConfig().tianapiKey()
	if key == "" {
		log.Println("未配置天聚数行 API Key")
		return nil
	}
	url := fmt.Sprintf("%s?key=%s", tianapiAIURL, key)
	data, err := httpGet(url)
	if err != nil {
		log.Println("AI资讯请求失败:", err)
		return nil
	}

	var resp aiNewsResp
	if json.Unmarshal(data, &resp) != nil || resp.Code != 200 {
		log.Println("AI资讯解析失败:", string(data[:min(len(data), 100)]))
		return nil
	}

	var items []aiNewsItem
	for _, n := range resp.Result.Newslist {
		items = append(items, aiNewsItem{
			Title:       n.Title,
			Description: n.Description,
			Source:      n.Source,
			CTime:       n.CTime,
			URL:         n.URL,
			PicURL:      n.PicUrl,
		})
	}

	aiNewsMu.Lock()
	aiNewsCache = items
	aiNewsCacheAt = time.Now()
	aiNewsMu.Unlock()

	// 缓存到文件
	cacheData, _ := json.Marshal(map[string]interface{}{
		"items": items,
		"at":    time.Now().Format(time.RFC3339),
	})
	if err := os.WriteFile(aiNewsCachePath(), cacheData, 0644); err != nil {
		log.Println("AI资讯缓存写入失败:", err)
	}

	log.Printf("AI资讯已获取: %d条", len(items))
	return items
}

func loadAINewsCache() []aiNewsItem {
	data, err := os.ReadFile(aiNewsCachePath())
	if err != nil {
		return nil
	}
	var cached struct {
		Items []aiNewsItem `json:"items"`
		At    string       `json:"at"`
	}
	if json.Unmarshal(data, &cached) != nil {
		return nil
	}
	return cached.Items
}

func pushAINews(items []aiNewsItem) {
	if len(items) == 0 {
		return
	}
	jsonData, _ := json.Marshal(items)
	js := fmt.Sprintf(`if(window.updateAINewsFromGo) window.updateAINewsFromGo(%s)`, string(jsonData))
	evalJS(js)
}

func aiNewsLoop() {
	cfg := loadConfig()
	if !cfg.HideAINews {
		// 先推送缓存
		if cached := loadAINewsCache(); cached != nil {
			pushAINews(cached)
		}
	} else if cached := loadAINewsCache(); cached != nil {
		aiNewsMu.Lock()
		aiNewsCache = cached
		aiNewsCacheAt = time.Now()
		aiNewsMu.Unlock()
	}

	time.Sleep(8 * time.Second)

	cfg = loadConfig()
	if !cfg.HideAINews {
		var items []aiNewsItem
		for i := 0; i < 3; i++ {
			items = fetchAINews()
			if items != nil {
				break
			}
			time.Sleep(30 * time.Second)
		}
		if items != nil {
			pushAINews(items)
		}
	}

	ticker := time.NewTicker(2 * time.Hour)
	for range ticker.C {
		cfg := loadConfig()
		if !cfg.HideAINews {
			if items := fetchAINews(); items != nil {
				pushAINews(items)
			}
		}
	}
}

func triggerAINewsRefresh() {
	go func() {
		if items := fetchAINews(); items != nil {
			pushAINews(items)
		}
	}()
}
