/*
 * SearchHistoryStore.vala
 * 
 * CRUD operations for search history.
 */

/**
 * SearchHistoryStore - Manages search history persistence
 */
public class RSSuper.SearchHistoryStore : Object {
    private Database db;
    
    /**
     * Maximum number of history entries to keep
     */
    public int max_entries { get; set; default = 100; }
    
    /**
     * Signal emitted when a search is recorded
     */
    public signal void search_recorded(SearchQuery query, int result_count);
    
    /**
     * Signal emitted when history is cleared
     */
    public signal void history_cleared();
    
    /**
     * Create a new search history store
     */
    public SearchHistoryStore(Database db) {
        this.db = db;
    }
    
    /**
     * Record a search query
     */
    public int record_search(SearchQuery query, int result_count = 0) throws Error {
        var stmt = db.prepare(
            "INSERT INTO search_history (query, filters_json, sort_option, page, page_size, result_count) " +
            "VALUES (?, ?, ?, ?, ?, ?);"
        );
        
        stmt.bind_text(1, query.query, -1, null);
        stmt.bind_text(2, query.filters_json ?? "", -1, null);
        stmt.bind_text(3, SearchFilters.sort_option_to_string(query.sort), -1, null);
        stmt.bind_int(4, query.page);
        stmt.bind_int(5, query.page_size);
        stmt.bind_int(6, result_count);
        
        stmt.step();
        
        debug("Search recorded: %s (%d results)", query.query, result_count);
        search_recorded(query, result_count);
        
        // Clean up old entries if needed
        cleanup_old_entries();
        
        return 0;  // Returns the last inserted row ID in SQLite
    }
    
    /**
     * Get search history
     */
    public SearchQuery[] get_history(int limit = 50) throws Error {
        var queries = new GLib.List<SearchQuery?>();
        
        var stmt = db.prepare(
            "SELECT query, filters_json, sort_option, page, page_size, result_count, created_at " +
            "FROM search_history " +
            "ORDER BY created_at DESC " +
            "LIMIT ?;"
        );
        
        stmt.bind_int(1, limit);
        
        while (stmt.step() == Sqlite.ROW) {
            var query = row_to_query(stmt);
            queries.append(query);
        }
        
        return queries_to_array(queries);
    }
    
    /**
     * Get recent searches (last 24 hours)
     */
    public SearchQuery[] get_recent() throws Error {
        var queries = new GLib.List<SearchQuery?>();
        var now = new DateTime.now_local();
        var yesterday = now.add_days(-1);
        var threshold = yesterday.format("%Y-%m-%dT%H:%M:%S");
        
        var stmt = db.prepare(
            "SELECT query, filters_json, sort_option, page, page_size, result_count, created_at " +
            "FROM search_history " +
            "WHERE created_at >= ? " +
            "ORDER BY created_at DESC " +
            "LIMIT 20;"
        );
        
        stmt.bind_text(1, threshold, -1, null);
        
        while (stmt.step() == Sqlite.ROW) {
            var query = row_to_query(stmt);
            queries.append(query);
        }
        
        return queries_to_array(queries);
    }
    
    /**
     * Delete a search history entry by ID
     */
    public void delete(int id) throws Error {
        var stmt = db.prepare("DELETE FROM search_history WHERE id = ?;");
        stmt.bind_int(1, id);
        stmt.step();
        
        debug("Search history entry deleted: %d", id);
    }
    
    /**
     * Clear all search history
     */
    public void clear() throws Error {
        var stmt = db.prepare("DELETE FROM search_history;");
        stmt.step();
        
        debug("Search history cleared");
        history_cleared();
    }
    
    /**
     * Clear old search history entries
     */
    private void cleanup_old_entries() throws Error {
        var stmt = db.prepare(
            "DELETE FROM search_history WHERE id NOT IN (" +
            "SELECT id FROM search_history ORDER BY created_at DESC LIMIT ?" +
            ");"
        );
        
        stmt.bind_int(1, max_entries);
        stmt.step();
    }
    
    /**
     * Convert a database row to a SearchQuery
     */
    private SearchQuery row_to_query(Sqlite.Statement stmt) {
        string query_str = stmt.column_text(0);
        string? filters_json = stmt.column_text(1);
        string sort_str = stmt.column_text(2);
        int page = stmt.column_int(3);
        int page_size = stmt.column_int(4);
        
        return SearchQuery(query_str, page, page_size, filters_json,
            SearchFilters.sort_option_from_string(sort_str));
    }

    private SearchQuery[] queries_to_array(GLib.List<SearchQuery?> list) {
        SearchQuery[] arr = {};
        for (unowned var node = list; node != null; node = node.next) {
            arr += node.data;
        }
        return arr;
    }

}

