package com.storycove.config;

import com.storycove.entity.Author;
import com.storycove.entity.Collection;
import com.storycove.entity.Story;
import com.storycove.repository.AuthorRepository;
import com.storycove.repository.CollectionRepository;
import com.storycove.repository.StoryRepository;
import com.storycove.service.LibraryService;
import com.storycove.service.SearchServiceAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Automatically performs bulk reindexing of all entities on application startup.
 * This ensures that the search index is always in sync with the database,
 * especially after Solr volume recreation during deployment.
 */
@Component
public class StartupIndexingRunner implements ApplicationRunner {

    private static final Logger logger = LoggerFactory.getLogger(StartupIndexingRunner.class);

    @Autowired
    private SearchServiceAdapter searchServiceAdapter;

    @Autowired
    private StoryRepository storyRepository;

    @Autowired
    private AuthorRepository authorRepository;

    @Autowired
    private CollectionRepository collectionRepository;

    @Autowired
    private LibraryService libraryService;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info("========================================");
        logger.info("Starting automatic bulk reindexing...");
        logger.info("========================================");

        try {
            // Check if search service is available
            if (!searchServiceAdapter.isSearchServiceAvailable()) {
                logger.warn("Search service (Solr) is not available. Skipping bulk reindexing.");
                logger.warn("Make sure Solr is running and accessible.");
                return;
            }

            // Skip indexing if no library is authenticated yet.
            // Without an active library, SolrService falls back to libraryId="default" for every
            // document, which would overwrite correctly-indexed documents (indexed with the real
            // library ID at creation time) and make them invisible to all subsequent searches.
            // The nightly reindex scheduler (NightlyReindexScheduler) will handle resyncing once
            // a user has authenticated and a library is active. A manual reindex can also be
            // triggered via POST /api/admin/search/solr/reindex.
            if (libraryService.getCurrentLibraryId() == null) {
                logger.warn("No active library at startup — skipping bulk reindexing to avoid");
                logger.warn("overwriting documents with an incorrect libraryId.");
                logger.warn("Trigger POST /api/admin/search/solr/reindex after authentication.");
                return;
            }

            long startTime = System.currentTimeMillis();

            // Index all stories
            logger.info("📚 Indexing stories...");
            List<Story> stories = storyRepository.findAllWithAssociations();
            if (!stories.isEmpty()) {
                searchServiceAdapter.bulkIndexStories(stories);
                logger.info("✅ Indexed {} stories", stories.size());
            } else {
                logger.info("ℹ️  No stories to index");
            }

            // Index all authors
            logger.info("👤 Indexing authors...");
            List<Author> authors = authorRepository.findAll();
            if (!authors.isEmpty()) {
                searchServiceAdapter.bulkIndexAuthors(authors);
                logger.info("✅ Indexed {} authors", authors.size());
            } else {
                logger.info("ℹ️  No authors to index");
            }

            // Index all collections
            logger.info("📂 Indexing collections...");
            List<Collection> collections = collectionRepository.findAllWithTags();
            if (!collections.isEmpty()) {
                searchServiceAdapter.bulkIndexCollections(collections);
                logger.info("✅ Indexed {} collections", collections.size());
            } else {
                logger.info("ℹ️  No collections to index");
            }

            long duration = System.currentTimeMillis() - startTime;
            logger.info("========================================");
            logger.info("✅ Bulk reindexing completed successfully in {}ms", duration);
            logger.info("📊 Total indexed: {} stories, {} authors, {} collections",
                stories.size(), authors.size(), collections.size());
            logger.info("========================================");

        } catch (Exception e) {
            logger.error("========================================");
            logger.error("❌ Bulk reindexing failed", e);
            logger.error("========================================");
            // Don't throw the exception - let the application start even if indexing fails
            // This allows the application to be functional even with search issues
        }
    }
}
