// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '//resources/cr_components/searchbox/searchbox_dropdown.js';
import '//resources/cr_components/searchbox/searchbox_input.js';
import '//resources/cr_components/searchbox/searchbox_compose_button.js';
import '//resources/cr_components/search/animated_glow.js';
import '//resources/cr_components/composebox/composebox_file_inputs.js';
import '//resources/cr_components/composebox/contextual_entrypoint_and_menu.js';
import { GlifAnimationState, TabSuggestionsState } from '//resources/cr_components/composebox/common.js';
import { GlowAnimationState } from '//resources/cr_components/search/constants.js';
import { SearchboxBrowserProxy } from '//resources/cr_components/searchbox/searchbox_browser_proxy.js';
import { SearchboxMixin } from '//resources/cr_components/searchbox/searchbox_mixin.js';
import { I18nMixinLit } from '//resources/cr_elements/i18n_mixin_lit.js';
import { WebUiListenerMixinLit } from '//resources/cr_elements/web_ui_listener_mixin_lit.js';
import { loadTimeData } from '//resources/js/load_time_data.js';
import { CrLitElement } from '//resources/lit/v3_0/lit.rollup.js';
import { ModelMode, ToolMode } from '//resources/mojo/components/omnibox/composebox/composebox_query.mojom-webui.js';
import { getCss } from './omnibox.css.js';
import { getHtml } from './omnibox.html.js';
// Note: Copied from omnibox_popup_searchbox.ts.
//       I18nMixinLit may eventually be moved to SearchboxMixin.
const OmniboxEverywhereOmniboxElementBase = SearchboxMixin(I18nMixinLit(WebUiListenerMixinLit(CrLitElement)));
export class OmniboxEverywhereOmniboxElement extends OmniboxEverywhereOmniboxElementBase {
    static get is() {
        return 'omnibox-everywhere-omnibox';
    }
    static get styles() {
        return getCss();
    }
    render() {
        return getHtml.bind(this)();
    }
    static get properties() {
        return {
            placeholderText: {
                type: String,
                reflect: true,
                notify: true,
            },
            searchboxChromeRefreshTheming: {
                type: Boolean,
                reflect: true,
            },
            searchboxSteadyStateShadow: {
                type: Boolean,
                reflect: true,
            },
            searchboxIcon_: { type: String },
            searchboxVoiceSearchEnabled_: {
                type: Boolean,
                reflect: true,
            },
            searchboxLensSearchEnabled_: {
                type: Boolean,
                reflect: true,
            },
            useWebkitSearchIcons_: {
                type: Boolean,
                reflect: true,
            },
            animationState_: { type: String },
            composeButtonEnabled: { type: Boolean, reflect: true },
            ntpRealboxNextEnabled: { type: Boolean, reflect: true },
            contextMenuGlifAnimationState: {
                type: String,
                reflect: true,
            },
            inputState_: { type: Object },
            tabSuggestions_: { type: Array },
            searchboxLayoutMode: { type: String },
            tabSuggestionsState_: { type: Number },
            contextManagementInComposeboxEnabled: { type: Boolean },
        };
    }
    #placeholderText_accessor_storage = '';
    get placeholderText() { return this.#placeholderText_accessor_storage; }
    set placeholderText(value) { this.#placeholderText_accessor_storage = value; }
    #searchboxChromeRefreshTheming_accessor_storage = loadTimeData.getBoolean('searchboxCr23Theming');
    get searchboxChromeRefreshTheming() { return this.#searchboxChromeRefreshTheming_accessor_storage; }
    set searchboxChromeRefreshTheming(value) { this.#searchboxChromeRefreshTheming_accessor_storage = value; }
    #searchboxSteadyStateShadow_accessor_storage = loadTimeData.getBoolean('searchboxCr23SteadyStateShadow');
    get searchboxSteadyStateShadow() { return this.#searchboxSteadyStateShadow_accessor_storage; }
    set searchboxSteadyStateShadow(value) { this.#searchboxSteadyStateShadow_accessor_storage = value; }
    #contextManagementInComposeboxEnabled_accessor_storage = false;
    get contextManagementInComposeboxEnabled() { return this.#contextManagementInComposeboxEnabled_accessor_storage; }
    set contextManagementInComposeboxEnabled(value) { this.#contextManagementInComposeboxEnabled_accessor_storage = value; }
    #searchboxIcon__accessor_storage = loadTimeData.getString('searchboxDefaultIcon');
    get searchboxIcon_() { return this.#searchboxIcon__accessor_storage; }
    set searchboxIcon_(value) { this.#searchboxIcon__accessor_storage = value; }
    #searchboxVoiceSearchEnabled__accessor_storage = loadTimeData.getBoolean('searchboxVoiceSearch');
    get searchboxVoiceSearchEnabled_() { return this.#searchboxVoiceSearchEnabled__accessor_storage; }
    set searchboxVoiceSearchEnabled_(value) { this.#searchboxVoiceSearchEnabled__accessor_storage = value; }
    #searchboxLensSearchEnabled__accessor_storage = loadTimeData.getBoolean('searchboxLensSearch');
    get searchboxLensSearchEnabled_() { return this.#searchboxLensSearchEnabled__accessor_storage; }
    set searchboxLensSearchEnabled_(value) { this.#searchboxLensSearchEnabled__accessor_storage = value; }
    #useWebkitSearchIcons__accessor_storage = true;
    get useWebkitSearchIcons_() { return this.#useWebkitSearchIcons__accessor_storage; }
    set useWebkitSearchIcons_(value) { this.#useWebkitSearchIcons__accessor_storage = value; }
    #animationState__accessor_storage = GlowAnimationState.NONE;
    get animationState_() { return this.#animationState__accessor_storage; }
    set animationState_(value) { this.#animationState__accessor_storage = value; }
    #composeButtonEnabled_accessor_storage = loadTimeData.getBoolean('searchboxShowComposeEntrypoint');
    get composeButtonEnabled() { return this.#composeButtonEnabled_accessor_storage; }
    set composeButtonEnabled(value) { this.#composeButtonEnabled_accessor_storage = value; }
    #ntpRealboxNextEnabled_accessor_storage = loadTimeData.getBoolean('ntpRealboxNextEnabled');
    get ntpRealboxNextEnabled() { return this.#ntpRealboxNextEnabled_accessor_storage; }
    set ntpRealboxNextEnabled(value) { this.#ntpRealboxNextEnabled_accessor_storage = value; }
    #contextMenuGlifAnimationState_accessor_storage = GlifAnimationState.STARTED;
    get contextMenuGlifAnimationState() { return this.#contextMenuGlifAnimationState_accessor_storage; }
    set contextMenuGlifAnimationState(value) { this.#contextMenuGlifAnimationState_accessor_storage = value; }
    #inputState__accessor_storage = null;
    get inputState_() { return this.#inputState__accessor_storage; }
    set inputState_(value) { this.#inputState__accessor_storage = value; }
    #tabSuggestions__accessor_storage = [];
    get tabSuggestions_() { return this.#tabSuggestions__accessor_storage; }
    set tabSuggestions_(value) { this.#tabSuggestions__accessor_storage = value; }
    #searchboxLayoutMode_accessor_storage = loadTimeData.getString('searchboxLayoutMode');
    get searchboxLayoutMode() { return this.#searchboxLayoutMode_accessor_storage; }
    set searchboxLayoutMode(value) { this.#searchboxLayoutMode_accessor_storage = value; }
    #tabSuggestionsState__accessor_storage = TabSuggestionsState.NOT_STARTED;
    get tabSuggestionsState_() { return this.#tabSuggestionsState__accessor_storage; }
    set tabSuggestionsState_(value) { this.#tabSuggestionsState__accessor_storage = value; }
    pageHandler_;
    callbackRouter_;
    autocompleteResultChangedListenerId_ = null;
    inputStateListenerId_ = null;
    constructor() {
        super();
        const browserProxy = SearchboxBrowserProxy.getInstance();
        this.pageHandler_ = browserProxy.handler;
        this.callbackRouter_ = browserProxy.callbackRouter;
    }
    connectedCallback() {
        super.connectedCallback();
        this.autocompleteResultChangedListenerId_ =
            this.callbackRouter_.autocompleteResultChanged.addListener(this.onAutocompleteResultChanged.bind(this));
        this.inputStateListenerId_ =
            this.callbackRouter_.onInputStateChanged.addListener((inputState) => {
                this.inputState_ = inputState;
            });
        this.pageHandler_.getInputState().then((response) => {
            this.inputState_ = response.state;
        });
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        if (this.autocompleteResultChangedListenerId_ !== null) {
            this.callbackRouter_.removeListener(this.autocompleteResultChangedListenerId_);
            this.autocompleteResultChangedListenerId_ = null;
        }
        if (this.inputStateListenerId_ !== null) {
            this.callbackRouter_.removeListener(this.inputStateListenerId_);
            this.inputStateListenerId_ = null;
        }
    }
    willUpdate(changedProperties) {
        super.willUpdate(changedProperties);
        if (changedProperties.has('searchboxChromeRefreshTheming')) {
            this.useWebkitSearchIcons_ = this.searchboxChromeRefreshTheming;
        }
    }
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        this.initialInputScrollHeight = this.$.input.scrollHeight;
    }
    focusInput() {
        this.$.input.focus();
    }
    //========================================================================
    // SearchboxMixin abstract method implementations
    //========================================================================
    getInputElement() {
        return this.$.input;
    }
    getDropdownElement() {
        return this.$.matches;
    }
    getWrapperElement() {
        return this.$.inputWrapper;
    }
    pageHandler() {
        return this.pageHandler_;
    }
    isInputEmpty() {
        // If this is called before first render, the input element will not exist.
        if (!this.shadowRoot?.querySelector('#input') || !this.$.input ||
            !this.$.input.lastInput()) {
            return true;
        }
        return !this.$.input.lastInput().text.trim();
    }
    shouldShowVoiceLens_(isEnabled) {
        if (!isEnabled) {
            return false;
        }
        if (!this.isInputEmpty()) {
            return false;
        }
        return true;
    }
    //========================================================================
    // Event handlers
    //========================================================================
    onInputFocusin_() {
        this.pageHandler_.onFocusChanged(true);
    }
    computePlaceholderText_() {
        if (this.placeholderText) {
            return this.placeholderText;
        }
        if (this.ntpRealboxNextEnabled) {
            return 'Ask Google';
        }
        return this.i18n('searchBoxHint');
    }
    onSearchboxInputTextUpdated_(e) {
        this.onSearchboxInputTextUpdated(e, /*forceAutocomplete=*/ false);
    }
    onVoiceSearchClick_() {
        this.dispatchEvent(new Event('open-voice-search'));
    }
    onLensSearchClick_() {
        this.dropdownIsVisible = false;
        this.dispatchEvent(new Event('open-lens-search'));
    }
    async openComposeboxWithMode_(mode = ToolMode.kUnspecified, model = ModelMode.kUnspecified) {
        this.animationState_ = GlowAnimationState.NONE;
        await this.updateComplete;
        this.animationState_ = GlowAnimationState.LISTENING;
        setTimeout(() => {
            this.fire('open-composebox', {
                text: this.$.input.inputElement.value,
                mode: mode,
                model: model,
                smartTabSharingActive: false,
            });
        }, 300);
    }
    onComposeClick_() {
        this.openComposeboxWithMode_();
    }
    onContextMenuEntrypointClick_() {
        this.pageHandler().activateMetricsFunnel('PlusButton');
    }
    async refreshTabSuggestions_(forceRefresh = false) {
        if (this.tabSuggestionsState_ === TabSuggestionsState.LOADING ||
            (this.tabSuggestionsState_ === TabSuggestionsState.LOADED &&
                !forceRefresh)) {
            return;
        }
        this.tabSuggestionsState_ = TabSuggestionsState.LOADING;
        try {
            const { tabs } = await this.pageHandler_.getRecentTabs();
            this.tabSuggestions_ = [...tabs];
            this.tabSuggestionsState_ = TabSuggestionsState.LOADED;
        }
        finally {
            if (this.tabSuggestionsState_ === TabSuggestionsState.LOADING) {
                this.tabSuggestionsState_ = TabSuggestionsState.NOT_STARTED;
            }
        }
    }
    onContextMenuOpened_() {
        this.refreshTabSuggestions_(/*forceRefresh=*/ true);
    }
    onContextMenuClosed_() {
        this.tabSuggestionsState_ = TabSuggestionsState.NOT_STARTED;
    }
    onRequestTabSuggestionsLoad() {
        this.refreshTabSuggestions_(/*forceRefresh=*/ true);
    }
    onToolClick_(e) {
        this.openComposeboxWithMode_(e.detail.toolMode);
    }
    onDeepSearchClick_() {
        this.openComposeboxWithMode_(ToolMode.kDeepSearch);
    }
    onCreateImageClick_() {
        this.openComposeboxWithMode_(ToolMode.kImageGen);
    }
    onModelClick_(e) {
        this.openComposeboxWithMode_(ToolMode.kUnspecified, e.detail.model);
    }
}
customElements.define(OmniboxEverywhereOmniboxElement.is, OmniboxEverywhereOmniboxElement);
