#ifndef COCKATRICE_TAB_ARCHIDEKT_H
#define COCKATRICE_TAB_ARCHIDEKT_H

#include "../../interface/widgets/cards/card_size_widget.h"
#include "../../interface/widgets/quick_settings/settings_button_widget.h"
#include "../../tab.h"
#include "display/archidekt_api_response_deck_listings_display_widget.h"

#include <QCheckBox>
#include <QComboBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QNetworkAccessManager>
#include <QPushButton>
#include <QScrollArea>
#include <QSet>
#include <QSpinBox>
#include <QString>
#include <QTimer>
#include <QVBoxLayout>
#include <QWidget>
#include <libcockatrice/card/database/card_database.h>

/** Base API link for Archidekt deck search */
inline QString archidektApiLink = "https://archidekt.com/api/decks/v3/?name=";

class ManaSymbolWidget;

/**
 * @brief Tab for browsing, searching, and filtering Archidekt decks.
 *
 * This class provides a comprehensive interface for querying decks from the Archidekt API.
 * Users can filter decks by name, owner, included cards, commanders, deck tags, colors, EDH bracket,
 * and formats. It supports infinite scroll pagination for seamless browsing.
 */
class TabArchidekt : public Tab
{
    Q_OBJECT
public:
    /**
     * @brief Construct a new TabArchidekt object
     * @param _tabSupervisor Parent tab supervisor responsible for tab management and callbacks
     *
     * Initializes the network manager, creates all UI components, sets up layouts,
     * connects signals and slots, and triggers an initial fetch of top decks.
     */
    explicit TabArchidekt(TabSupervisor *_tabSupervisor);

    /**
     * @brief Update all UI text to reflect the current language or translation
     *
     * This function re-applies translations to all labels, buttons, and placeholders.
     * It should be called after a language change.
     */
    void retranslateUi() override;

    /**
     * @brief Construct the search URL from all current filters
     * @return QString Fully constructed URL including all query parameters
     *
     * The search URL is dynamically built using the state of all filter widgets.
     * Parameters included:
     * - Deck name
     * - Owner
     * - Included cards
     * - Commander cards
     * - Deck tag
     * - Colors and logical AND requirement
     * - Formats
     * - EDH bracket
     * - Packages toggle
     * - Sorting field and direction
     * - Minimum amount of cards in the deck
     * - Current page (for infinite scroll)
     */
    QString buildSearchUrl();

    /**
     * @brief Retrieve the tab display text
     * @return QString Human-readable title for the tab
     *
     * If a card is pre-selected (cardToQuery), its name is appended to the tab title.
     */
    QString getTabText() const override
    {
        auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
        return tr("Archidekt: ") + cardName;
    }

    /**
     * @brief Get the card size slider widget
     * @return CardSizeWidget* Pointer to the card size adjustment slider
     *
     * Allows external code to read or manipulate the current card size or hook up the sliders signals.
     */
    CardSizeWidget *getCardSizeSlider()
    {
        return cardSizeSlider;
    }

public slots:
    /**
     * @brief Trigger a debounced search using the current filters
     *
     * Resets to page 1 and starts the debounce timer. The actual search will execute
     * after 300ms of inactivity.
     */
    void doSearch();

    /**
     * @brief Immediately trigger a search using the current filters
     *
     * Sends a network request to the Archidekt API using the URL generated by buildSearchUrl().
     * Updates the results display asynchronously.
     */
    void doSearchImmediate();

    /**
     * @brief Load the next page of results for infinite scroll
     *
     * Increments the current page and fetches additional results, which are appended
     * to the existing results display.
     */
    void loadNextPage();

    /**
     * @brief Process a network reply containing JSON data
     * @param reply QNetworkReply object with the API response
     *
     * Determines whether the response corresponds to a deck listing or a single deck,
     * and dispatches it to the appropriate handler.
     */
    void processApiJson(QNetworkReply *reply);

    /**
     * @brief Handle a JSON response containing multiple decks
     * @param reply QJsonObject containing deck listings
     *
     * If this is page 1, clears previous results. Appends new results to the display.
     */
    void processTopDecksResponse(QJsonObject reply);

    /**
     * @brief Handle a JSON response for a single deck
     * @param reply QJsonObject containing deck data
     *
     * Clears the results area and displays the single deck details.
     */
    void processDeckResponse(QJsonObject reply);

    /**
     * @brief Pretty-print a QJsonValue for debugging
     * @param value The JSON value to print
     * @param indentLevel The indentation depth (number of levels)
     */
    void prettyPrintJson(const QJsonValue &value, int indentLevel);

    /**
     * @brief Navigate to a specified page URL
     * @param url The URL to request
     *
     * Typically called when a deck card is clicked in the listing.
     */
    void actNavigatePage(QString url);

    /**
     * @brief Fetch top decks from the Archidekt API
     *
     * Called on initialization to populate the initial results display.
     */
    void getTopDecks();

protected:
    /**
     * @brief Event filter to catch wheel events for infinite scroll
     * @param obj The object that received the event
     * @param event The event to filter
     * @return bool Whether the event was handled
     */
    bool eventFilter(QObject *obj, QEvent *event) override;

private:
    /**
     * @brief Initialize the main UI layout and toolbars
     *
     * Creates the container, main layout, primary toolbar (sort, colors, name, owner, packages),
     * secondary toolbar (advanced filters), and scrollable results area.
     */
    void initializeUi();

    /**
     * @brief Set up all filter widgets
     *
     * Creates filter widgets for:
     * - Card search with autocomplete
     * - Commander search with autocomplete
     * - Deck tags
     * - Format selection (collapsible)
     * - Deck size filter (collapsible)
     */
    void setupFilterWidgets();

    /**
     * @brief Connect all signals and slots for UI interactions
     *
     * Links all widget signals to their appropriate handlers, including
     * search triggers, filter changes, package mode toggling, and infinite scroll.
     */
    void connectSignals();

    /**
     * @brief Update UI state when package mode is toggled
     * @param isPackageMode Whether package mode is currently enabled
     *
     * Disables format-specific and commander-specific filters when searching
     * for card packages instead of full decks.
     */
    void updatePackageModeState(bool isPackageMode);

    // ---------------------------------------------------------------------
    // Network & Timing
    // ---------------------------------------------------------------------

    QNetworkAccessManager *networkManager; ///< Network manager for handling API requests
    QTimer *searchDebounceTimer;           ///< Timer to debounce search requests
    int currentPage;                       ///< Current page number for infinite scroll
    bool isLoadingMore;                    ///< Flag to prevent multiple simultaneous page loads
    bool isListMode;
    ArchidektApiResponseDeckListingsDisplayWidget *listingsWidget = nullptr;

    // ---------------------------------------------------------------------
    // Layout Containers
    // ---------------------------------------------------------------------

    QWidget *container;      ///< Root container for the entire tab
    QVBoxLayout *mainLayout; ///< Outer vertical layout containing toolbars and results

    QWidget *primaryToolbar;           ///< Primary toolbar with most important filters
    QHBoxLayout *primaryToolbarLayout; ///< Layout for primary toolbar

    QWidget *secondaryToolbar;           ///< Secondary toolbar with advanced filters
    QHBoxLayout *secondaryToolbarLayout; ///< Layout for secondary toolbar

    QScrollArea *scrollArea;    ///< Scrollable area for results (enables infinite scroll)
    QWidget *resultsContainer;  ///< Container widget inside scroll area
    QVBoxLayout *resultsLayout; ///< Layout for results (decks appended here)

    // ---------------------------------------------------------------------
    // Primary Toolbar Controls (Most Important)
    // ---------------------------------------------------------------------

    QLabel *sortByLabel;         ///< Label for sort controls
    QComboBox *orderByCombo;     ///< Dropdown for selecting the sort field
    QPushButton *orderDirButton; ///< Toggle button for ascending/descending sort

    QLabel *filterByLabel;                  ///< Label for filter controls
    QList<ManaSymbolWidget *> colorSymbols; ///< Mana symbol toggle buttons
    QSet<QChar> activeColors;               ///< Set of currently active mana colors
    QCheckBox *logicalAndCheck;             ///< Require ALL selected colors instead of ANY

    QLineEdit *nameField;               ///< Input for deck name filter
    QLineEdit *ownerField;              ///< Input for owner name filter
    QCheckBox *packagesCheck;           ///< Toggle for searching card packages instead of full decks
    QPushButton *searchButton;          ///< Button to trigger search
    QPushButton *advancedFiltersButton; ///< Button to show/hide advanced filters

    SettingsButtonWidget *settingsButton; ///< Container for card size settings
    CardSizeWidget *cardSizeSlider;       ///< Slider to adjust card size in results

    // ---------------------------------------------------------------------
    // Secondary Toolbar Controls (Advanced Filters)
    // ---------------------------------------------------------------------

    QLineEdit *cardsField;       ///< Input for cards included in the deck
    QLineEdit *commandersField;  ///< Input for commander cards
    QLineEdit *deckTagNameField; ///< Input for deck tag filtering

    SettingsButtonWidget *formatButton; ///< Collapsible button for format filters
    QVector<QCheckBox *> formatChecks;  ///< Individual checkboxes for each format
    QComboBox *edhBracketCombo;         ///< Dropdown for EDH bracket selection

    SettingsButtonWidget *deckSizeButton; ///< Collapsible button for deck size filter
    QSpinBox *minDeckSizeSpin;            ///< Spinner to select minimum deck size
    QComboBox *minDeckSizeLogicCombo;     ///< Combo box for size comparison logic

    // ---------------------------------------------------------------------
    // Optional Context
    // ---------------------------------------------------------------------

    CardInfoPtr cardToQuery; ///< Optional pre-selected card for initial filtering
};

#endif // COCKATRICE_TAB_ARCHIDEKT_H