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;
};
/* eslint-disable */
import { assertExists } from '@blockeditor/global/utils';
import { WithDisposable } from '@blockeditor/lit';
import { computePosition, inline, offset, shift } from '@floating-ui/dom';
import { html, LitElement, nothing } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { BLOCK_ID_ATTR } from '../../../../../consts.js';
import { AIIcon, AISendIcon } from '../../../../../icons/ai.js';
import { createSend } from '../../../../../utils/sse/createSSE.js';
import { AIPopupStyle } from './styles.js';
import { textDealConfig } from './consts.js';
let AIPopup = class AIPopup extends WithDisposable(LitElement) {
    constructor() {
        super(...arguments);
        this.type = 'create';
        this._bodyOverflowStyle = '';
        this._aiResult = '';
        this._status = '';
    }
    connectedCallback() {
        super.connectedCallback();
        // if (this.targetInlineRange.length === 0) {
        // 	throw new Error('Cannot toggle AI popup on empty range');
        // }
        if (this.type === 'edit' || this.type === 'create') {
            // disable body scroll
            this._bodyOverflowStyle = document.body.style.overflow;
            document.body.style.overflow = 'hidden';
            this.disposables.add({
                dispose: () => {
                    document.body.style.overflow = this._bodyOverflowStyle;
                },
            });
        }
        this.inlineEditors.forEach((inlineEditor, index) => {
            const blockElement = inlineEditor.rootElement.closest(`[${BLOCK_ID_ATTR}]`);
            assertExists(blockElement);
            const parent = blockElement.host.page.getParent(blockElement.model);
            if (index === 0) {
                this.aiOptions = blockElement.host.page.aiOptions;
                // console.log(123, blockElement.host.page.aiOptions);
            }
            assertExists(parent);
            this.disposables.add(parent.childrenUpdated.on(() => {
                const children = parent.children;
                if (children.includes(blockElement.model))
                    return;
                this.remove();
            }));
        });
    }
    firstUpdated() {
        if (!this.AIInput)
            return;
        this._disposables.addFromEvent(this.AIInput, 'copy', e => {
            e.stopPropagation();
        });
        this._disposables.addFromEvent(this.AIInput, 'cut', e => {
            e.stopPropagation();
        });
        this._disposables.addFromEvent(this.AIInput, 'paste', e => {
            e.stopPropagation();
        });
    }
    updated() {
        assertExists(this.popupContainer);
        const docPageEle = document.querySelectorAll('.affine-doc-viewport')[0];
        const scrollTop = docPageEle ? docPageEle.scrollTop : 0;
        const docPageEleRects = docPageEle.getBoundingClientRect();
        this.inlineEditors.forEach((inlineEditor, index) => {
            const range = inlineEditor.toDomRange(this.targetInlineRanges[index]);
            assertExists(range);
            const domRects = range.getClientRects();
            Object.values(domRects).forEach(domRect => {
                // console.log(111, domRect, scrollTop, docPageEleRects)
                const mockSelection = document.createElement('div');
                mockSelection.classList.add('mock-selection', 'blockeditor-overlay');
                mockSelection.style.left = `${domRect.left - docPageEleRects.left}px`;
                mockSelection.style.top = `${domRect.top + scrollTop - docPageEleRects.top}px`;
                mockSelection.style.width = `${domRect.width}px`;
                mockSelection.style.height = `${domRect.height}px`;
                assertExists(this.mockSelectionContainer);
                this.mockSelectionContainer.appendChild(mockSelection);
            });
            if (index === this.inlineEditors.length - 1 && this.popupContainer) {
                const visualElement = {
                    getBoundingClientRect: () => range.getBoundingClientRect(),
                    getClientRects: () => range.getClientRects(),
                };
                computePosition(visualElement, this.popupContainer, {
                    middleware: [
                        offset(10),
                        inline(),
                        shift({
                            padding: 6,
                        }),
                    ],
                })
                    .then(({ x, y }) => {
                    if (!this.popupContainer)
                        return;
                    this.popupContainer.style.left = `${x}px`;
                    this.popupContainer.style.top = `${y}px`;
                })
                    .catch(console.error);
            }
        });
    }
    get currentText() {
        let arr = [];
        this.inlineEditors.forEach((inlineEditor, index) => {
            const targetInlineRange = this.targetInlineRanges[index];
            arr.push(inlineEditor.yTextString.slice(targetInlineRange.index, targetInlineRange.index + targetInlineRange.length));
        });
        return arr;
    }
    async _onConfirm() {
        // if (!this.inlineEditors[0].isValidInlineRange(this.targetInlineRanges[0])) return;
        assertExists(this.AIInput);
        const AIInputValue = this.AIInput?.value;
        if (!AIInputValue)
            return;
        this._statusChange('sseLoading');
        try {
            const { result } = await createSend.$sendPrompt({
                prompt: this.currentText.map(text => (`\`\`\`${text}\`\`\``)).join(' ') + ` \`\`\`${AIInputValue}\`\`\``,
                aiOptions: this.aiOptions,
            }, ({ 
            // start,
            content,
            // done
             }) => {
                // if (start) isStart.value = true;
                if (content) {
                    if (this.AIContent)
                        this.AIContent.innerText = content;
                }
            });
            // const result = 'testttttttttttttttttttttttttttttttt'
            // this.AIContent.innerText = result;
            this._aiResult = result;
            this._statusChange('receivedAIContent');
        }
        catch (e) {
            this._aiResult = this.AIContent?.innerText || '';
            this._statusChange('init');
        }
    }
    _onKeydown(e) {
        e.stopPropagation();
        if (e.key === 'Enter' && !e.isComposing && !e.shiftKey) {
            e.preventDefault();
            this._onConfirm();
        }
    }
    _inputChange() {
        assertExists(this.confirmButton);
        assertExists(this.AIMenu);
        assertExists(this.AIInput);
        this.AIInput.style.height = 'inherit';
        this.AIInput.style.height = `${this.AIInput.scrollHeight}px`;
        const value = this.AIInput?.value;
        this.confirmButton.disabled = !value;
        this.confirmButton.requestUpdate();
        if (this._status === 'receivedAIContent') {
            this.AIMenu.style.display = value ? 'none' : 'block';
        }
    }
    _statusChange(status) {
        if (status)
            this._status = status;
        switch (this._status) {
            case 'init': // 初始界面
                if (this.AIContent)
                    this.AIContent.innerText = '';
                if (this.AIInput) {
                    this.AIInput.value = '';
                    this.AIInput.style.height = '23px';
                    this.AIInput.placeholder = 'Ask AI to edit or generate...';
                }
                if (this.AIInputBox)
                    this.AIInputBox.style.display = 'flex';
                if (this.AIInputLoading)
                    this.AIInputLoading.style.display = 'none';
                if (this.AIMenu)
                    this.AIMenu.style.display = 'none';
                break;
            case 'sseLoading': // 正在发送sse请求
                if (this.AIContent)
                    this.AIContent.innerText = '';
                if (this.AIInput)
                    this.AIInput.value = '';
                if (this.AIInputBox)
                    this.AIInputBox.style.display = 'none';
                if (this.AIInputLoading)
                    this.AIInputLoading.style.display = 'flex';
                break;
            case 'receivedAIContent': // 收到AI全部返回结果，等待user交互
                if (this.AIInputBox)
                    this.AIInputBox.style.display = 'flex';
                if (this.AIInputLoading)
                    this.AIInputLoading.style.display = 'none';
                if (this.AIInput) {
                    this.AIInput.placeholder = 'Tell AI what to do next...';
                    this.AIInput.style.height = '23px';
                }
                if (this.AIMenu)
                    this.AIMenu.style.display = 'block';
                break;
            default:
                break;
        }
    }
    _confirmBtnTemplate() {
        return html `<icon-button
      class="affine-confirm-button"
      @click=${this._onConfirm}
      >${AISendIcon}<affine-tooltip>Send to AI</affine-tooltip></icon-button
    >`;
    }
    _handleClickItem(index) {
        const { action } = textDealConfig[index];
        action({
            inlineEditors: this.inlineEditors,
            targetInlineRanges: this.targetInlineRanges,
            content: this._aiResult,
        })?.catch(console.error);
        this.remove();
    }
    _createTemplate() {
        this.updateComplete
            .then(() => {
            this.AIInput?.focus();
            this._inputChange();
        })
            .catch(console.error);
        return html `<div class="affine-ai-popover">
      <div class="affine-ai-popover-chat">
        <div id="ai-content"></div>
        <div class="flex" id="ai-input-box">
          <span class="ai-pre-icon">${AIIcon}</span>
          <div class="flex flex-end flex-1">
			<div class="flex align-center flex-1" style="padding: 3px 0;">
				<textarea
				  id="ai-input"
							type="text"
							rows="1"
				  class="affine-ai-popover-input flex-1"
				  spellcheck="false"
				  placeholder="Ask AI to edit or generate..."
				  @input=${this._inputChange}
				></textarea>
			</div>
			<div class="flex align-center" style="height: 29px;">
				<span class="affine-ai-popover-dividing-line"></span>
				${this._confirmBtnTemplate()}
			</div>
		  </div>
        </div>
        <div class="flex align-center none" id="ai-input-loading">
          <span class="ai-pre-icon">${AIIcon}</span>
          <div class="affine-ai-popover-input-loading">
            <span
              >AI is writing
              <div class="loading">
                <div></div>
                <div></div>
                <div></div></div
            ></span>
          </div>
        </div>
      </div>
      <div class="affine-ai-popover-menu" id="ai-menu">
        ${textDealConfig.map(({ name, icon }, index) => html `<icon-button
              width="100%"
              height="32px"
              style="padding-left: 4px; justify-content: flex-start; gap: 8px;"
              text="${name}"
              @click=${() => {
            this._handleClickItem(index);
        }}
            >
              <span
                style="display: flex; align-items: center; width: 14px; height: 14px;"
              >
                ${icon}
              </span>
            </icon-button>`)}
      </div>
    </div>`;
    }
    // <div class="menu-panel-heading">Color</div>
    render() {
        const ele = document.querySelectorAll('.doc-editor-container')[0];
        let height = 0;
        if (ele) {
            height = (ele?.offsetTop || 0) + (ele?.offsetHeight || 0);
        }
        const mask = this.type === 'edit' || this.type === 'create'
            ? html `<div class="overlay-mask" style="height: calc(${height}px + 30vh)" @click=${() => this.remove()}></div>`
            : nothing;
        const popover = this._createTemplate();
        return html `
      <div class="overlay-root blockeditor-overlay">
        ${mask}
        <div class="popup-container" @keydown=${this._onKeydown}>
          ${popover}
        </div>
        <div class="mock-selection-container"></div>
      </div>
    `;
    }
};
AIPopup.styles = AIPopupStyle;
__decorate([
    property()
], AIPopup.prototype, "type", void 0);
__decorate([
    property()
], AIPopup.prototype, "inlineEditors", void 0);
__decorate([
    property()
], AIPopup.prototype, "targetInlineRanges", void 0);
__decorate([
    query('#text-input')
], AIPopup.prototype, "textInput", void 0);
__decorate([
    query('#ai-input')
], AIPopup.prototype, "AIInput", void 0);
__decorate([
    query('#ai-input-loading')
], AIPopup.prototype, "AIInputLoading", void 0);
__decorate([
    query('#ai-input-box')
], AIPopup.prototype, "AIInputBox", void 0);
__decorate([
    query('#ai-content')
], AIPopup.prototype, "AIContent", void 0);
__decorate([
    query('#ai-menu')
], AIPopup.prototype, "AIMenu", void 0);
__decorate([
    query('.popup-container')
], AIPopup.prototype, "popupContainer", void 0);
__decorate([
    query('.mock-selection-container')
], AIPopup.prototype, "mockSelectionContainer", void 0);
__decorate([
    query('.affine-confirm-button')
], AIPopup.prototype, "confirmButton", void 0);
AIPopup = __decorate([
    customElement('ai-popup')
], AIPopup);
export { AIPopup };
//# sourceMappingURL=ai-popup.js.map