var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import './doc-image-block.js';
import './edgeless-image-block.js';
import './components/image-card.js';
import { BlockElement } from '@blockeditor/lit';
import { html, render } from 'lit';
import { customElement, query, state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { getEdgelessPageByElement, matchFlavours, } from '../_common/utils/index.js';
import { AFFINE_DRAG_HANDLE_WIDGET, AffineDragHandleWidget, } from '../page-block/widgets/drag-handle/drag-handle.js';
import { captureEventTarget, convertDragPreviewDocToEdgeless, convertDragPreviewEdgelessToDoc, } from '../page-block/widgets/drag-handle/utils.js';
import { ImageState } from './components/image-card.js';
import { ImageBlockSchema } from './image-model.js';
import { isImageLoading } from './utils.js';
const MAX_RETRY_COUNT = 3;
let ImageBlockComponent = class ImageBlockComponent extends BlockElement {
    constructor() {
        super(...arguments);
        this._imageState = ImageState.Loading;
        this._isInSurface = false;
        this._lastSourceId = '';
        this._source = '';
        this._retryCount = 0;
        this._fetchImage = () => {
            if (isImageLoading(this.model.id)) {
                this._retryCount = 0;
                return;
            }
            if (!this.model.sourceId) {
                this._imageState = ImageState.Failed;
                return;
            }
            if (this._imageState === ImageState.Ready &&
                this._lastSourceId &&
                this._lastSourceId === this.model.sourceId) {
                return;
            }
            this._imageState = ImageState.Loading;
            const storage = this.model.page.blob;
            const sourceId = this.model.sourceId;
            storage
                .get(sourceId)
                .then(blob => {
                if (blob) {
                    this.blob = blob;
                    this._source = URL.createObjectURL(blob);
                    this._lastSourceId = sourceId;
                    this._imageState = ImageState.Ready;
                }
                else {
                    throw new Error('Cannot find blob');
                }
            })
                .catch(e => {
                this._retryCount++;
                console.warn('Cannot find blob, retrying', this._retryCount);
                if (this._retryCount < MAX_RETRY_COUNT) {
                    setTimeout(() => {
                        this._fetchImage();
                        // 1s, 2s, 3s
                    }, 1000 * this._retryCount);
                }
                else {
                    console.error(e);
                    this._imageState = ImageState.Failed;
                }
            });
        };
        this._dragHandleOption = {
            flavour: ImageBlockSchema.model.flavour,
            edgeless: true,
            onDragStart: ({ state, startDragging, anchorBlockPath }) => {
                const element = captureEventTarget(state.raw.target);
                if (element?.classList.contains('resize'))
                    return false;
                if (!anchorBlockPath)
                    return false;
                const anchorComponent = this.std.view.viewFromPath('block', anchorBlockPath);
                if (!anchorComponent ||
                    !matchFlavours(anchorComponent.model, [ImageBlockSchema.model.flavour]))
                    return false;
                const blockComponent = anchorComponent;
                const isDraggingByDragHandle = !!element?.closest(AFFINE_DRAG_HANDLE_WIDGET);
                const isDraggingByComponent = blockComponent.contains(element);
                const isInSurface = blockComponent.isInSurface;
                if (!isInSurface && (isDraggingByDragHandle || isDraggingByComponent)) {
                    this.std.selection.setGroup('note', [
                        this.std.selection.create('block', {
                            path: blockComponent.path,
                        }),
                    ]);
                    startDragging([blockComponent], state);
                    return true;
                }
                else if (isInSurface && isDraggingByDragHandle) {
                    const edgelessPage = getEdgelessPageByElement(blockComponent);
                    const scale = edgelessPage ? edgelessPage.surface.viewport.zoom : 1;
                    const width = blockComponent.getBoundingClientRect().width;
                    const dragPreviewEl = document.createElement('div');
                    dragPreviewEl.classList.add('affine-block-element');
                    dragPreviewEl.style.border = '2px solid var(--affine-border-color)';
                    dragPreviewEl.style.borderRadius = '4px';
                    dragPreviewEl.style.overflow = 'hidden';
                    dragPreviewEl.style.width = `${width / scale}px`;
                    render(blockComponent.renderModel(blockComponent.model), dragPreviewEl);
                    startDragging([blockComponent], state, dragPreviewEl);
                    return true;
                }
                return false;
            },
            onDragEnd: props => {
                const { state, draggingElements } = props;
                if (draggingElements.length !== 1 ||
                    !matchFlavours(draggingElements[0].model, [
                        ImageBlockSchema.model.flavour,
                    ]))
                    return false;
                const blockComponent = draggingElements[0];
                const isInSurface = blockComponent.isInSurface;
                const target = captureEventTarget(state.raw.target);
                const isTargetEdgelessContainer = target?.classList.contains('edgeless') &&
                    target?.classList.contains('affine-block-children-container');
                if (isInSurface) {
                    return convertDragPreviewEdgelessToDoc({
                        blockComponent,
                        ...props,
                    });
                }
                else if (isTargetEdgelessContainer) {
                    return convertDragPreviewDocToEdgeless({
                        blockComponent,
                        cssSelector: 'img',
                        ...props,
                    });
                }
                return false;
            },
        };
    }
    get isInSurface() {
        return this._isInSurface;
    }
    get resizeImg() {
        return this._pageImage.resizeImg;
    }
    _onCardClick(e) {
        e.stopPropagation();
        const selection = this.host.selection;
        selection.setGroup('note', [
            selection.create('block', { path: this.path }),
        ]);
    }
    connectedCallback() {
        super.connectedCallback();
        this.disposables.add(AffineDragHandleWidget.registerOption(this._dragHandleOption));
        const parent = this.host.page.getParent(this.model);
        this._isInSurface = parent?.flavour === 'affine:surface';
        this._fetchImage();
        this.model.propsUpdated.on(({ key }) => {
            if (key === 'sourceId') {
                if (this._source) {
                    URL.revokeObjectURL(this._source);
                    this._source = '';
                }
                this._retryCount = 0;
                this._fetchImage();
            }
        });
    }
    disconnectedCallback() {
        if (this._source)
            URL.revokeObjectURL(this._source);
        super.disconnectedCallback();
    }
    render() {
        const imageState = isImageLoading(this.model.id)
            ? ImageState.Loading
            : this._imageState;
        if (imageState !== ImageState.Ready) {
            return html `<affine-image-block-card
        imageState=${imageState}
        ?isinsurface=${this.isInSurface}
        imageSize=${ifDefined(this.model.size)}
        @click=${this._onCardClick}
      ></affine-image-block-card>`;
        }
        if (this.isInSurface) {
            return html `<affine-edgeless-image
        .model=${this.model}
        .page=${this.page}
        .host=${this.host}
        .widgets=${this.widgets}
        source=${this._source}
      ></affine-edgeless-image>`;
        }
        else {
            return html `<affine-page-image
        .model=${this.model}
        .page=${this.page}
        .host=${this.host}
        .widgets=${this.widgets}
        source=${this._source}
      ></affine-page-image>`;
        }
    }
};
__decorate([
    query('affine-page-image')
], ImageBlockComponent.prototype, "_pageImage", void 0);
__decorate([
    query('affine-edgeless-image')
], ImageBlockComponent.prototype, "_edgelessImage", void 0);
__decorate([
    state()
], ImageBlockComponent.prototype, "_imageState", void 0);
ImageBlockComponent = __decorate([
    customElement('affine-image')
], ImageBlockComponent);
export { ImageBlockComponent };
//# sourceMappingURL=image-block.js.map