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 '../../../../_common/components/loader.js';
import { WithDisposable } from '@blockeditor/lit';
import {} from '@blockeditor/store';
import { Job } from '@blockeditor/store';
import JSZip from 'jszip';
import { html, LitElement } from 'lit';
import { customElement, query, state } from 'lit/decorators.js';
import { MarkdownAdapter } from '../../../../_common/adapters/markdown.js';
import { NotionHtmlAdapter } from '../../../../_common/adapters/notion-html.js';
import { CloseIcon, ExportToHTMLIcon, ExportToMarkdownIcon, HelpIcon, NewIcon, NotionIcon, } from '../../../../_common/icons/index.js';
import { defaultImageProxyMiddleware } from '../../../../_common/transformers/middlewares.js';
import { openFileOrFiles } from '../../../../_common/utils/index.js';
import { styles } from './styles.js';
const SHOW_LOADING_SIZE = 1024 * 200;
export async function importMarkDown(workspace, text) {
    const job = new Job({
        workspace: workspace,
        middlewares: [defaultImageProxyMiddleware],
    });
    const mdAdapter = new MarkdownAdapter();
    mdAdapter.applyConfigs(job.adapterConfigs);
    const snapshot = await mdAdapter.toPageSnapshot({ file: text });
    const page = await job.snapshotToPage(snapshot);
    return [page.id];
}
export async function importHtml(workspace, text) {
    const job = new Job({
        workspace: workspace,
        middlewares: [defaultImageProxyMiddleware],
    });
    const htmlAdapter = new NotionHtmlAdapter();
    htmlAdapter.applyConfigs(job.adapterConfigs);
    const snapshot = await htmlAdapter.toPageSnapshot({ file: text });
    const page = await job.snapshotToPage(snapshot);
    return [page.id];
}
export async function importNotion(workspace, file) {
    const pageIds = [];
    let isWorkspaceFile = false;
    const parseZipFile = async (file) => {
        const zip = new JSZip();
        const zipFile = await zip.loadAsync(file);
        const pageMap = new Map();
        const files = Object.keys(zipFile.files);
        const promises = [];
        for (let i = 0; i < files.length; i++) {
            const file = files[i];
            if (file.startsWith('__MACOSX/'))
                continue;
            const lastSplitIndex = file.lastIndexOf('/');
            const fileName = file.substring(lastSplitIndex + 1);
            if (fileName.endsWith('.html') || fileName.endsWith('.md')) {
                if (file.endsWith('/index.html')) {
                    isWorkspaceFile = true;
                    continue;
                }
                if (lastSplitIndex !== -1) {
                    const text = await zipFile.files[file].async('text');
                    const doc = new DOMParser().parseFromString(text, 'text/html');
                    const pageBody = doc.querySelector('.page-body');
                    if (pageBody && pageBody.children.length == 0) {
                        // Skip empty pages
                        continue;
                    }
                }
                pageMap.set(file, workspace.idGenerator('page'));
            }
            if (i === 0 && fileName.endsWith('.csv')) {
                window.open('https://affine.pro/blog/import-your-data-from-notion-into-affine', '_blank');
            }
            if (fileName.endsWith('.zip')) {
                const innerZipFile = await zipFile.file(fileName)?.async('blob');
                if (innerZipFile) {
                    promises.push(...(await parseZipFile(innerZipFile)));
                }
            }
        }
        const pagePromises = Array.from(pageMap.keys()).map(async (file) => {
            const job = new Job({
                workspace: workspace,
                middlewares: [defaultImageProxyMiddleware],
            });
            const htmlAdapter = new NotionHtmlAdapter();
            htmlAdapter.applyConfigs(job.adapterConfigs);
            const snapshot = await htmlAdapter.toPageSnapshot({
                file: await zipFile.files[file].async('text'),
                pageId: pageMap.get(file),
                pageMap,
            });
            const page = await job.snapshotToPage(snapshot);
            pageIds.push(page.id);
        });
        promises.push(...pagePromises);
        return promises;
    };
    const allPromises = await parseZipFile(file);
    await Promise.all(allPromises.flat());
    return { pageIds, isWorkspaceFile };
}
/**
 * @deprecated Waiting for migration
 * See https://github.com/toeverything/blockeditor/issues/3316
 */
let ImportDoc = class ImportDoc extends WithDisposable(LitElement) {
    constructor(workspace, onSuccess, abortController = new AbortController()) {
        super();
        this.workspace = workspace;
        this.onSuccess = onSuccess;
        this.abortController = abortController;
        this._loading = false;
        this.x = 0;
        this.y = 0;
        this._startX = 0;
        this._startY = 0;
        this._loading = false;
        this.x = 0;
        this.y = 0;
        this._startX = 0;
        this._startY = 0;
        this._onMouseMove = this._onMouseMove.bind(this);
    }
    updated(changedProps) {
        if (changedProps.has('x') || changedProps.has('y')) {
            this.containerEl.style.transform = `translate(${this.x}px, ${this.y}px)`;
        }
    }
    _onMouseDown(event) {
        this._startX = event.clientX - this.x;
        this._startY = event.clientY - this.y;
        window.addEventListener('mousemove', this._onMouseMove);
    }
    _onMouseUp() {
        window.removeEventListener('mousemove', this._onMouseMove);
    }
    _onMouseMove(event) {
        this.x = event.clientX - this._startX;
        this.y = event.clientY - this._startY;
    }
    _onCloseClick(event) {
        event.stopPropagation();
        this.abortController.abort();
    }
    _onImportSuccess(pageIds, isWorkspaceFile = false) {
        this.onSuccess?.(pageIds, isWorkspaceFile);
    }
    async _importMarkDown() {
        const file = await openFileOrFiles({ acceptType: 'Markdown' });
        if (!file)
            return;
        const text = await file.text();
        const needLoading = file.size > SHOW_LOADING_SIZE;
        if (needLoading) {
            this.hidden = false;
            this._loading = true;
        }
        else {
            this.abortController.abort();
        }
        const pageIds = await importMarkDown(this.workspace, text);
        needLoading && this.abortController.abort();
        this._onImportSuccess(pageIds);
    }
    async _importHtml() {
        const file = await openFileOrFiles({ acceptType: 'Html' });
        if (!file)
            return;
        const text = await file.text();
        const needLoading = file.size > SHOW_LOADING_SIZE;
        if (needLoading) {
            this.hidden = false;
            this._loading = true;
        }
        else {
            this.abortController.abort();
        }
        const pageIds = await importHtml(this.workspace, text);
        needLoading && this.abortController.abort();
        this._onImportSuccess(pageIds);
    }
    async _importNotion() {
        const file = await openFileOrFiles({ acceptType: 'Zip' });
        if (!file)
            return;
        // Calc size
        let totalSize = 0;
        const zip = new JSZip();
        const zipFile = await zip.loadAsync(file);
        const fileArray = Object.values(zipFile.files);
        for (const file of fileArray) {
            if (file.dir)
                continue;
            const fileContent = await file.async('uint8array');
            totalSize += fileContent.length;
        }
        const needLoading = totalSize > SHOW_LOADING_SIZE;
        if (needLoading) {
            this.hidden = false;
            this._loading = true;
        }
        else {
            this.abortController.abort();
        }
        const { pageIds, isWorkspaceFile } = await importNotion(this.workspace, file);
        needLoading && this.abortController.abort();
        this._onImportSuccess(pageIds, isWorkspaceFile);
    }
    _openLearnImportLink(event) {
        event.stopPropagation();
        window.open('https://affine.pro/blog/import-your-data-from-notion-into-affine', '_blank');
    }
    render() {
        if (this._loading) {
            return html `
        <div class="overlay-mask blockeditor-overlay"></div>
        <div class="container">
          <header
            class="loading-header"
            @mousedown="${this._onMouseDown}"
            @mouseup="${this._onMouseUp}"
          >
            <div>Import</div>
            <loader-element .width=${'50px'}></loader-element>
          </header>
          <div>
            Importing the file may take some time. It depends on document size
            and complexity.
          </div>
        </div>
      `;
        }
        return html `
      <div
        class="overlay-mask blockeditor-overlay"
        @click="${() => this.abortController.abort()}"
      ></div>
      <div class="container">
        <header @mousedown="${this._onMouseDown}" @mouseup="${this._onMouseUp}">
          <icon-button height="28px" @click="${this._onCloseClick}">
            ${CloseIcon}
          </icon-button>
          <div>Import</div>
        </header>
        <div>
          AFFiNE will gradually support more file formats for import.
          <a
            href="https://community.affine.pro/c/feature-requests/import-export"
            target="_blank"
            >Provide feedback.</a
          >
        </div>
        <div class="button-container">
          <icon-button
            class="button-item"
            text="Markdown"
            @click="${this._importMarkDown}"
          >
            ${ExportToMarkdownIcon}
          </icon-button>
          <icon-button
            class="button-item"
            text="HTML"
            @click="${this._importHtml}"
          >
            ${ExportToHTMLIcon}
          </icon-button>
        </div>
        <div class="button-container">
          <icon-button
            class="button-item"
            text="Notion"
            @click="${this._importNotion}"
          >
            ${NotionIcon}
            <div
              slot="suffix"
              class="button-suffix"
              @click="${this._openLearnImportLink}"
            >
              ${HelpIcon}
              <affine-tooltip>
                Learn how to Import your Notion pages into AFFiNE.
              </affine-tooltip>
            </div>
          </icon-button>
          <icon-button class="button-item" text="Coming soon..." disabled>
            ${NewIcon}
          </icon-button>
        </div>
        <!-- <div class="footer">
        <div>Migrate from other versions of AFFiNE?</div>
      </div> -->
      </div>
    `;
    }
};
ImportDoc.styles = styles;
__decorate([
    state()
], ImportDoc.prototype, "_loading", void 0);
__decorate([
    state()
], ImportDoc.prototype, "x", void 0);
__decorate([
    state()
], ImportDoc.prototype, "y", void 0);
__decorate([
    state()
], ImportDoc.prototype, "_startX", void 0);
__decorate([
    state()
], ImportDoc.prototype, "_startY", void 0);
__decorate([
    query('.container')
], ImportDoc.prototype, "containerEl", void 0);
ImportDoc = __decorate([
    customElement('import-doc')
], ImportDoc);
export { ImportDoc };
//# sourceMappingURL=import-doc.js.map