// SPDX-FileCopyrightText: 2022 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "searcheventreceiver.h"
#include "searcheventcaller.h"
#include "utils/searchhelper.h"
#include "searchmanager/searchmanager.h"

#include <dfm-base/widgets/filemanagerwindowsmanager.h>
#include <dfm-base/utils/networkutils.h>
#include <dfm-base/utils/protocolutils.h>
#include <dfm-base/utils/highlightprovider.h>
#include <dfm-base/dfm_global_defines.h>

#include <dfm-framework/dpf.h>

#include <QFont>
#include <QFontMetrics>
#include <QTimer>

DFMBASE_USE_NAMESPACE

namespace dfmplugin_search {

dfmplugin_search::SearchEventReceiver *dfmplugin_search::SearchEventReceiver::instance()
{
    static SearchEventReceiver ins;
    return &ins;
}

void SearchEventReceiver::handleSearch(quint64 winId, const QString &keyword)
{
    if (winId < 1) {
        fmWarning() << "Ignore search request with invalid window id";
        return;
    }

    auto *window = FMWindowsIns.findWindowById(winId);
    if (!window) {
        // Fix: shutdown can outlive a delayed search callback from the titlebar.
        fmWarning() << "Ignore search request because window no longer exists:" << winId;
        return;
    }

    const auto &curUrl = window->currentUrl();
    if (ProtocolUtils::isRemoteFile(curUrl)
        && NetworkUtils::instance()->checkFtpOrSmbBusy(curUrl)) {
        fmWarning() << "Network disconnected during search";
        return;
    }

    QUrl searchUrl;
    if (SearchHelper::isSearchFile(curUrl)) {
        const QUrl &targetUrl = SearchHelper::searchTargetUrl(curUrl);
        searchUrl = SearchHelper::fromSearchFile(targetUrl, keyword, QString::number(winId));
    } else {
        searchUrl = SearchHelper::fromSearchFile(curUrl, keyword, QString::number(winId));
    }

    SearchEventCaller::sendChangeCurrentUrl(winId, searchUrl);
}

void SearchEventReceiver::handleStopSearch(quint64 winId)
{
    SearchManager::instance()->stop(winId);
}

void SearchEventReceiver::handleShowAdvanceSearchBar(quint64 winId, bool visible)
{
    SearchEventCaller::sendShowAdvanceSearchBar(winId, visible);
}

void SearchEventReceiver::handleAddressInputStr(quint64 windId, QString *str)
{
    if (str->startsWith("search:?") && !str->contains("winId=")) {
        QString winId = "&winId=" + QString::number(windId);
        str->append(winId);
    }
}

void SearchEventReceiver::handleFileAdd(const QUrl &url)
{
    emit SearchManager::instance()->fileAdd(url);
}

void SearchEventReceiver::handleFileDelete(const QUrl &url)
{
    emit SearchManager::instance()->fileDelete(url);
}

void SearchEventReceiver::handleFileRename(const QUrl &oldUrl, const QUrl &newUrl)
{
    emit SearchManager::instance()->fileRename(oldUrl, newUrl);
}

void SearchEventReceiver::handleUrlChanged(quint64 winId, const QUrl &url)
{
    if (url.scheme() != SearchHelper::scheme())
        return;

    // 延迟到下一事件循环：此时视图已创建完成，列宽已调整
    QTimer::singleShot(0, this, [winId] {
        int nameColWidth = dpfSlotChannel->push("dfmplugin_workspace",
                                                "slot_View_GetColumnWidth",
                                                winId,
                                                DFMGLOBAL_NAMESPACE::kItemFileDisplayNameRole)
                                   .value<int>();
        if (nameColWidth <= 0)
            return;

        int width = QFontMetrics(QApplication::font()).averageCharWidth();
        int avgCharWidth = qMax(11, width);
        int posLen = qMax(30, nameColWidth / avgCharWidth);
        HighlightProvider::instance()->setPositioningMaxLength(posLen);
    });
}

SearchEventReceiver::SearchEventReceiver(QObject *parent)
    : QObject(parent)
{
}

}
