package services

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

// WatchlistItem 관심종목 항목
type WatchlistItem struct {
	Code string `json:"code"`
	Name string `json:"name"`
}

// WatchlistService 관심종목 JSON 파일 CRUD
type WatchlistService struct {
	mu   sync.RWMutex
	path string
	list []WatchlistItem
}

var watchlistServiceInstance *WatchlistService
var watchlistServiceOnce sync.Once

// GetWatchlistService 관심종목 서비스 싱글톤 반환
func GetWatchlistService() *WatchlistService {
	watchlistServiceOnce.Do(func() {
		watchlistServiceInstance = NewWatchlistService("data/watchlist.json")
	})
	return watchlistServiceInstance
}

// NewWatchlistService 관심종목 서비스 초기화 (파일 로드)
func NewWatchlistService(path string) *WatchlistService {
	svc := &WatchlistService{path: path}
	svc.load()
	return svc
}

// GetAll 전체 관심종목 반환
func (s *WatchlistService) GetAll() []WatchlistItem {
	s.mu.RLock()
	defer s.mu.RUnlock()
	result := make([]WatchlistItem, len(s.list))
	copy(result, s.list)
	return result
}

// Add 관심종목 추가 (중복 방지)
func (s *WatchlistService) Add(code, name string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, item := range s.list {
		if item.Code == code {
			return fmt.Errorf("이미 추가된 종목입니다: %s", code)
		}
	}
	s.list = append(s.list, WatchlistItem{Code: code, Name: name})
	return s.save()
}

// Remove 관심종목 삭제
func (s *WatchlistService) Remove(code string) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	newList := make([]WatchlistItem, 0, len(s.list))
	for _, item := range s.list {
		if item.Code != code {
			newList = append(newList, item)
		}
	}
	s.list = newList
	return s.save()
}

// load 파일에서 관심종목 로드 (파일 없으면 빈 배열 초기화)
func (s *WatchlistService) load() {
	data, err := os.ReadFile(s.path)
	if err != nil {
		s.list = []WatchlistItem{}
		return
	}
	if err := json.Unmarshal(data, &s.list); err != nil {
		s.list = []WatchlistItem{}
	}
}

// save 관심종목을 JSON 파일에 저장 (내부용)
func (s *WatchlistService) save() error {
	// data/ 디렉토리 자동 생성
	if err := os.MkdirAll(filepath.Dir(s.path), 0o755); err != nil {
		return err
	}
	data, err := json.MarshalIndent(s.list, "", "  ")
	if err != nil {
		return err
	}
	return os.WriteFile(s.path, data, 0o644)
}
