package scraper

import (
	"context"
	"git.leaktechnologies.dev/stu/Goondex/internal/model"
	adultemp "git.leaktechnologies.dev/stu/Goondex/internal/scraper/adultemp"
)

// BulkScraper interface defines bulk import capabilities
type BulkScraper interface {
	SearchAllPerformers(ctx context.Context) ([]adultemp.SearchResult, error)
	SearchAllStudios(ctx context.Context) ([]adultemp.SearchResult, error)
	SearchAllScenes(ctx context.Context) ([]adultemp.SearchResult, error)
	ConvertPerformerToModel(data interface{}) *model.Performer
	ConvertStudioToModel(data interface{}) *model.Studio
	ConvertSceneToModel(data interface{}) *model.Scene
}

// AdultEmpireBulkScraper implements bulk operations using individual searches
type AdultEmpireBulkScraper struct {
	scraper *adultemp.Scraper
}

// NewAdultEmpireBulkScraper creates a bulk scraper for Adult Empire
func NewAdultEmpireBulkScraper() (*AdultEmpireBulkScraper, error) {
	scraper, err := adultemp.NewScraper()
	if err != nil {
		return nil, err
	}

	return &AdultEmpireBulkScraper{
		scraper: scraper,
	}, nil
}

// SearchAllPerformers fetches all performers by using generic searches
func (a *AdultEmpireBulkScraper) SearchAllPerformers(ctx context.Context) ([]adultemp.SearchResult, error) {
	searchTerms := []string{"", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}

	var allResults []adultemp.SearchResult
	seen := make(map[string]bool)

	for _, term := range searchTerms {
		if len(allResults) >= 1000 {
			break
		}

		results, err := a.scraper.SearchPerformersByName(ctx, term)
		if err != nil {
			continue
		}

		for _, result := range results {
			if !seen[result.URL] {
				seen[result.URL] = true
				allResults = append(allResults, result)
			}
		}
	}

	return allResults, nil
}

// SearchAllStudios fetches all studios (not fully supported by Adult Empire)
func (a *AdultEmpireBulkScraper) SearchAllStudios(ctx context.Context) ([]adultemp.SearchResult, error) {
	// Adult Empire doesn't have dedicated studio search, return empty for now
	return []adultemp.SearchResult{}, nil
}

// SearchAllScenes fetches all scenes
func (a *AdultEmpireBulkScraper) SearchAllScenes(ctx context.Context) ([]adultemp.SearchResult, error) {
	searchTerms := []string{"", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}

	var allResults []adultemp.SearchResult
	seen := make(map[string]bool)

	for _, term := range searchTerms {
		if len(allResults) >= 2000 {
			break
		}

		results, err := a.scraper.SearchScenesByName(ctx, term)
		if err != nil {
			continue
		}

		for _, result := range results {
			if !seen[result.URL] {
				seen[result.URL] = true
				allResults = append(allResults, result)
			}
		}
	}

	return allResults, nil
}

// ConvertPerformerToModel converts Adult Empire performer data
func (a *AdultEmpireBulkScraper) ConvertPerformerToModel(data interface{}) *model.Performer {
	if performerData, ok := data.(*adultemp.PerformerData); ok {
		return a.scraper.ConvertPerformerToModel(performerData)
	}
	return nil
}

// ConvertStudioToModel converts studio data (not implemented for Adult Empire)
func (a *AdultEmpireBulkScraper) ConvertStudioToModel(data interface{}) *model.Studio {
	return nil
}

// ConvertSceneToModel converts scene data
func (a *AdultEmpireBulkScraper) ConvertSceneToModel(data interface{}) *model.Scene {
	if sceneData, ok := data.(*adultemp.SceneData); ok {
		return a.scraper.ConvertSceneToModel(sceneData)
	}
	return nil
}
