package service

import (
	"butterfliu/internal/repository"
	"butterfliu/internal/scanner"
	"log"
)

type LibraryService struct {
	repo *repository.LibraryRepository
}

func NewLibraryService(repo *repository.LibraryRepository) *LibraryService {
	return &LibraryService{repo: repo}
}

func (s *LibraryService) GetAll() ([]repository.Library, error) {
	return s.repo.GetAll()
}

func (s *LibraryService) GetByID(id int) (repository.Library, error) {
	return s.repo.GetByID(id)
}

func (s *LibraryService) Create(name, path string) (repository.Library, error) {
	return s.repo.Create(name, path)
}

func (s *LibraryService) UpdateName(id int, name string) error {
	return s.repo.UpdateName(id, name)
}

func (s *LibraryService) UpdatePath(id int, path string) error {
	return s.repo.UpdatePath(id, path)
}

func (s *LibraryService) Delete(id int) error {
	return s.repo.Delete(id)
}

func (s *LibraryService) GetSongs(id int) ([]repository.SongDetail, error) {
	return s.repo.GetSongsByLibraryWithDetails(id)
}

func (s *LibraryService) GetAllSongs() ([]repository.SongDetail, error) {
	return s.repo.GetAllSongsWithDetails()
}

func (s *LibraryService) GetArtists() ([]repository.Artist, error) {
	return s.repo.GetArtists()
}

func (s *LibraryService) GetAlbums() ([]repository.Album, error) {
	return s.repo.GetAlbums()
}

func (s *LibraryService) Scan(id int) error {
	lib, err := s.repo.GetByID(id)
	if err != nil {
		return err
	}

	scannedSongs, err := scanner.ScanDirectory(lib.Path)
	if err != nil {
		return err
	}

	log.Println("Scanned songs:", len(scannedSongs))

	for _, song := range scannedSongs {
		mediaFile, err := s.repo.GetMediaFileByPath(song.Path)
		if err != nil {
			mediaFile, err = s.repo.CreateMediaFile(song.Path, id)
			if err != nil {
				log.Println("Error adding media file:", song.Path, err)
				continue
			}
		}

		artist, err := s.repo.GetArtistByName(song.Artist)
		if err != nil {
			artist, err = s.repo.CreateArtist(song.Artist)
			if err != nil {
				log.Println("Error adding artist:", song.Artist, err)
				continue
			}
		}

		album, err := s.repo.GetAlbumByTitleAndArtist(song.Album, artist.ID)
		if err != nil {
			album, err = s.repo.CreateAlbum(song.Album, artist.ID)
			if err != nil {
				log.Println("Error adding album:", err)
				continue
			}
		}

		_, err = s.repo.CreateSong(song.Title, artist.ID, album.ID, song.Duration, mediaFile.ID)
		if err != nil {
			log.Printf("Song already exists or error adding: %s - %v", song.Title, err)
			continue
		}
	}

	return nil
}
