// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../cr_auto_img/cr_auto_img.js';
import { assert } from '//resources/js/assert.js';
import { FocusOutlineManager } from '//resources/js/focus_outline_manager.js';
import { getFaviconForPageURL } from '//resources/js/icon.js';
import { CrLitElement } from '//resources/lit/v3_0/lit.rollup.js';
import { MouseHoverableMixinLit } from '../mouse_hoverable_mixin_lit.js';
import { getCss } from './cr_url_list_item.css.js';
import { getHtml } from './cr_url_list_item.html.js';
export var CrUrlListItemSize;
(function (CrUrlListItemSize) {
    CrUrlListItemSize["COMPACT"] = "compact";
    CrUrlListItemSize["MEDIUM"] = "medium";
    CrUrlListItemSize["LARGE"] = "large";
})(CrUrlListItemSize || (CrUrlListItemSize = {}));
const CrUrlListItemElementBase = MouseHoverableMixinLit(CrLitElement);
export class CrUrlListItemElement extends CrUrlListItemElementBase {
    static get is() {
        return 'cr-url-list-item';
    }
    static get styles() {
        return getCss();
    }
    render() {
        return getHtml.bind(this)();
    }
    static get properties() {
        return {
            alwaysShowSuffix: {
                type: Boolean,
                reflect: true,
            },
            itemAriaLabel: { type: String },
            itemAriaDescription: { type: String },
            count: { type: Number },
            description: { type: String },
            url: { type: String },
            title: {
                reflect: true,
                type: String,
            },
            hasBadges: {
                type: Boolean,
                reflect: true,
            },
            hasDescriptions_: {
                type: Boolean,
                reflect: true,
            },
            hasSlottedContent_: {
                type: Boolean,
                reflect: true,
            },
            reverseElideDescription: {
                type: Boolean,
                reflect: true,
            },
            isFolder_: {
                type: Boolean,
                reflect: true,
            },
            size: {
                type: String,
                reflect: true,
            },
            imageUrls: { type: Array },
            firstImageLoaded_: {
                type: Boolean,
                state: true,
            },
            forceHover: {
                reflect: true,
                type: Boolean,
            },
            descriptionMeta: { type: String },
            /**
             * Flag that determines if the element should use an anchor tag or a
             * button element as its focusable item. An anchor provides the native
             * context menu and browser interactions for links, while a button
             * provides its own unique functionality, such as pressing space to
             * activate.
             */
            asAnchor: { type: Boolean },
            asAnchorTarget: { type: String },
        };
    }
    #alwaysShowSuffix_accessor_storage = false;
    get alwaysShowSuffix() { return this.#alwaysShowSuffix_accessor_storage; }
    set alwaysShowSuffix(value) { this.#alwaysShowSuffix_accessor_storage = value; }
    #asAnchor_accessor_storage = false;
    get asAnchor() { return this.#asAnchor_accessor_storage; }
    set asAnchor(value) { this.#asAnchor_accessor_storage = value; }
    #asAnchorTarget_accessor_storage = '_self';
    get asAnchorTarget() { return this.#asAnchorTarget_accessor_storage; }
    set asAnchorTarget(value) { this.#asAnchorTarget_accessor_storage = value; }
    #itemAriaLabel_accessor_storage;
    get itemAriaLabel() { return this.#itemAriaLabel_accessor_storage; }
    set itemAriaLabel(value) { this.#itemAriaLabel_accessor_storage = value; }
    #itemAriaDescription_accessor_storage;
    get itemAriaDescription() { return this.#itemAriaDescription_accessor_storage; }
    set itemAriaDescription(value) { this.#itemAriaDescription_accessor_storage = value; }
    #count_accessor_storage;
    get count() { return this.#count_accessor_storage; }
    set count(value) { this.#count_accessor_storage = value; }
    #description_accessor_storage;
    get description() { return this.#description_accessor_storage; }
    set description(value) { this.#description_accessor_storage = value; }
    #reverseElideDescription_accessor_storage = false;
    get reverseElideDescription() { return this.#reverseElideDescription_accessor_storage; }
    set reverseElideDescription(value) { this.#reverseElideDescription_accessor_storage = value; }
    #hasBadges_accessor_storage = false;
    get hasBadges() { return this.#hasBadges_accessor_storage; }
    set hasBadges(value) { this.#hasBadges_accessor_storage = value; }
    #hasDescriptions__accessor_storage = false;
    get hasDescriptions_() { return this.#hasDescriptions__accessor_storage; }
    set hasDescriptions_(value) { this.#hasDescriptions__accessor_storage = value; }
    #hasSlottedContent__accessor_storage = false;
    get hasSlottedContent_() { return this.#hasSlottedContent__accessor_storage; }
    set hasSlottedContent_(value) { this.#hasSlottedContent__accessor_storage = value; }
    #isFolder__accessor_storage = false;
    get isFolder_() { return this.#isFolder__accessor_storage; }
    set isFolder_(value) { this.#isFolder__accessor_storage = value; }
    #size_accessor_storage = CrUrlListItemSize.MEDIUM;
    get size() { return this.#size_accessor_storage; }
    set size(value) { this.#size_accessor_storage = value; }
    #title_accessor_storage = '';
    get title() { return this.#title_accessor_storage; }
    set title(value) { this.#title_accessor_storage = value; }
    #url_accessor_storage;
    get url() { return this.#url_accessor_storage; }
    set url(value) { this.#url_accessor_storage = value; }
    #imageUrls_accessor_storage = [];
    get imageUrls() { return this.#imageUrls_accessor_storage; }
    set imageUrls(value) { this.#imageUrls_accessor_storage = value; }
    #firstImageLoaded__accessor_storage = false;
    get firstImageLoaded_() { return this.#firstImageLoaded__accessor_storage; }
    set firstImageLoaded_(value) { this.#firstImageLoaded__accessor_storage = value; }
    #forceHover_accessor_storage = false;
    get forceHover() { return this.#forceHover_accessor_storage; }
    set forceHover(value) { this.#forceHover_accessor_storage = value; }
    #descriptionMeta_accessor_storage = '';
    get descriptionMeta() { return this.#descriptionMeta_accessor_storage; }
    set descriptionMeta(value) { this.#descriptionMeta_accessor_storage = value; }
    connectedCallback() {
        super.connectedCallback();
        this.resetFirstImageLoaded_();
    }
    willUpdate(changedProperties) {
        super.willUpdate(changedProperties);
        if (changedProperties.has('hasBadges') ||
            changedProperties.has('description')) {
            this.hasDescriptions_ =
                !!this.description || this.hasBadges || !!this.descriptionMeta;
        }
        if (changedProperties.has('count')) {
            this.isFolder_ = this.count !== undefined;
        }
        if (changedProperties.has('size')) {
            assert(Object.values(CrUrlListItemSize).includes(this.size));
        }
    }
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        FocusOutlineManager.forDocument(document);
        this.addEventListener('pointerdown', () => this.setActiveState_(true));
        this.addEventListener('pointerup', () => this.setActiveState_(false));
        this.addEventListener('pointerleave', () => this.setActiveState_(false));
    }
    updated(changedProperties) {
        super.updated(changedProperties);
        if (changedProperties.has('imageUrls')) {
            this.resetFirstImageLoaded_();
        }
    }
    focus() {
        this.getFocusableElement().focus();
    }
    getFocusableElement() {
        if (this.asAnchor) {
            return this.$.anchor;
        }
        else {
            return this.$.button;
        }
    }
    resetFirstImageLoaded_() {
        this.firstImageLoaded_ = false;
        const image = this.shadowRoot.querySelector('img');
        if (!image) {
            return;
        }
        if (image.complete) {
            this.firstImageLoaded_ = true;
            return;
        }
        image.addEventListener('load', () => {
            this.firstImageLoaded_ = true;
        }, { once: true });
    }
    getItemAriaDescription_() {
        return this.itemAriaDescription || this.description;
    }
    getItemAriaLabel_() {
        return this.itemAriaLabel || this.title;
    }
    getDisplayedCount_() {
        if (this.count && this.count > 999) {
            // The square to display the count only fits 3 characters.
            return '99+';
        }
        return this.count === undefined ? '' : this.count.toString();
    }
    getFavicon_() {
        return getFaviconForPageURL(this.url || '', false);
    }
    shouldShowImageUrl_(_url, index) {
        return index <= 1;
    }
    onBadgesSlotchange_() {
        this.hasBadges = this.$.badges.assignedElements({ flatten: true }).length > 0;
    }
    onContentSlotchange_() {
        this.hasSlottedContent_ =
            this.$.content.assignedElements({ flatten: true }).length > 0;
    }
    setActiveState_(active) {
        this.classList.toggle('active', active);
    }
    shouldShowFavicon_() {
        return this.url !== undefined &&
            (this.size === CrUrlListItemSize.COMPACT ||
                this.imageUrls.length === 0);
    }
    shouldShowUrlImage_() {
        return this.url !== undefined &&
            !(this.size === CrUrlListItemSize.COMPACT ||
                this.imageUrls.length === 0) &&
            this.firstImageLoaded_;
    }
    shouldShowFolderImages_() {
        return this.size !== CrUrlListItemSize.COMPACT;
    }
    shouldShowFolderIcon_() {
        return this.size === CrUrlListItemSize.COMPACT ||
            this.imageUrls.length === 0;
    }
    shouldShowFolderCount_() {
        return this.url === undefined;
    }
}
customElements.define(CrUrlListItemElement.is, CrUrlListItemElement);
