package storage

import (
	"encoding/json"
	"os"
	"path/filepath"
	"sync"
	"time"

	"mengyaping-backend/config"
	"mengyaping-backend/models"
)

// Storage 数据存储
type Storage struct {
	dataPath string
	mu       sync.RWMutex
	websites []models.Website
	records  map[string][]models.MonitorRecord // key: websiteID_urlID
	groups   []models.Group
}

var (
	store *Storage
	once  sync.Once
)

// GetStorage 获取存储单例
func GetStorage() *Storage {
	once.Do(func() {
		cfg := config.GetConfig()
		store = &Storage{
			dataPath: cfg.DataPath,
			websites: []models.Website{},
			records:  make(map[string][]models.MonitorRecord),
			groups:   models.DefaultGroups,
		}
		store.ensureDataDir()
		store.load()
	})
	return store
}

// ensureDataDir 确保数据目录存在
func (s *Storage) ensureDataDir() {
	os.MkdirAll(s.dataPath, 0755)
}

// load 加载数据
func (s *Storage) load() {
	s.loadWebsites()
	s.loadRecords()
	s.loadGroups()
}

// loadWebsites 加载网站数据
func (s *Storage) loadWebsites() {
	filePath := filepath.Join(s.dataPath, "websites.json")
	data, err := os.ReadFile(filePath)
	if err != nil {
		return
	}
	json.Unmarshal(data, &s.websites)
	s.migrateWebsiteGroups()
}

// migrateWebsiteGroups 将旧的单分组字段迁移到多分组数组
func (s *Storage) migrateWebsiteGroups() {
	migrated := false
	for i := range s.websites {
		w := &s.websites[i]
		if len(w.Groups) == 0 && w.Group != "" {
			w.Groups = []string{w.Group}
			w.Group = ""
			migrated = true
		}
	}
	if migrated {
		s.saveWebsites()
	}
}

// loadRecords 加载监控记录
func (s *Storage) loadRecords() {
	filePath := filepath.Join(s.dataPath, "records.json")
	data, err := os.ReadFile(filePath)
	if err != nil {
		return
	}
	json.Unmarshal(data, &s.records)

	// 清理过期记录
	s.cleanOldRecords()
}

// loadGroups 加载分组
func (s *Storage) loadGroups() {
	filePath := filepath.Join(s.dataPath, "groups.json")
	data, err := os.ReadFile(filePath)
	if err != nil {
		// 使用默认分组
		s.groups = models.DefaultGroups
		s.saveGroups()
		return
	}
	json.Unmarshal(data, &s.groups)
}

// saveWebsites 保存网站数据
func (s *Storage) saveWebsites() error {
	filePath := filepath.Join(s.dataPath, "websites.json")
	data, err := json.MarshalIndent(s.websites, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(filePath, data, 0644)
}

// saveRecords 保存监控记录
func (s *Storage) saveRecords() error {
	filePath := filepath.Join(s.dataPath, "records.json")
	data, err := json.MarshalIndent(s.records, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(filePath, data, 0644)
}

// saveGroups 保存分组
func (s *Storage) saveGroups() error {
	filePath := filepath.Join(s.dataPath, "groups.json")
	data, err := json.MarshalIndent(s.groups, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(filePath, data, 0644)
}

// cleanOldRecords 清理过期记录
func (s *Storage) cleanOldRecords() {
	cfg := config.GetConfig()
	cutoff := time.Now().AddDate(0, 0, -cfg.Monitor.HistoryDays)

	for key, records := range s.records {
		var newRecords []models.MonitorRecord
		for _, r := range records {
			if r.CheckedAt.After(cutoff) {
				newRecords = append(newRecords, r)
			}
		}
		s.records[key] = newRecords
	}
}

// GetWebsites 获取所有网站
func (s *Storage) GetWebsites() []models.Website {
	s.mu.RLock()
	defer s.mu.RUnlock()

	result := make([]models.Website, len(s.websites))
	copy(result, s.websites)
	return result
}

// GetWebsite 获取单个网站
func (s *Storage) GetWebsite(id string) *models.Website {
	s.mu.RLock()
	defer s.mu.RUnlock()

	for _, w := range s.websites {
		if w.ID == id {
			website := w
			return &website
		}
	}
	return nil
}

// AddWebsite 添加网站
func (s *Storage) AddWebsite(website models.Website) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.websites = append(s.websites, website)
	return s.saveWebsites()
}

// UpdateWebsite 更新网站
func (s *Storage) UpdateWebsite(website models.Website) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	for i, w := range s.websites {
		if w.ID == website.ID {
			s.websites[i] = website
			return s.saveWebsites()
		}
	}
	return nil
}

// DeleteWebsite 删除网站
func (s *Storage) DeleteWebsite(id string) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	for i, w := range s.websites {
		if w.ID == id {
			s.websites = append(s.websites[:i], s.websites[i+1:]...)
			// 删除相关记录
			for key := range s.records {
				if len(key) > len(id) && key[:len(id)] == id {
					delete(s.records, key)
				}
			}
			s.saveRecords()
			return s.saveWebsites()
		}
	}
	return nil
}

// AddRecord 添加监控记录
func (s *Storage) AddRecord(record models.MonitorRecord) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	key := record.WebsiteID + "_" + record.URLID
	s.records[key] = append(s.records[key], record)

	// 每100条记录保存一次
	if len(s.records[key])%100 == 0 {
		return s.saveRecords()
	}
	return nil
}

// GetRecords 获取监控记录
func (s *Storage) GetRecords(websiteID, urlID string, since time.Time) []models.MonitorRecord {
	s.mu.RLock()
	defer s.mu.RUnlock()

	key := websiteID + "_" + urlID
	records := s.records[key]

	var result []models.MonitorRecord
	for _, r := range records {
		if r.CheckedAt.After(since) {
			result = append(result, r)
		}
	}
	return result
}

// GetLatestRecord 获取最新记录
func (s *Storage) GetLatestRecord(websiteID, urlID string) *models.MonitorRecord {
	s.mu.RLock()
	defer s.mu.RUnlock()

	key := websiteID + "_" + urlID
	records := s.records[key]

	if len(records) == 0 {
		return nil
	}

	latest := records[len(records)-1]
	return &latest
}

// GetGroups 获取所有分组
func (s *Storage) GetGroups() []models.Group {
	s.mu.RLock()
	defer s.mu.RUnlock()

	result := make([]models.Group, len(s.groups))
	copy(result, s.groups)
	return result
}

// AddGroup 添加分组
func (s *Storage) AddGroup(group models.Group) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	s.groups = append(s.groups, group)
	return s.saveGroups()
}

// SaveAll 保存所有数据
func (s *Storage) SaveAll() error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if err := s.saveWebsites(); err != nil {
		return err
	}
	if err := s.saveRecords(); err != nil {
		return err
	}
	return s.saveGroups()
}
