import { isBlock, isLine, isRawBlock } from "../../block";
import { getCellTypeBadge } from "../types/notebook";
export default class NotebookCell {
    constructor(cell, config = {}) {
        this.childCells = [];
        this.editTextarea = null;
        this.cell = cell;
        this.config = config;
        this.element = document.createElement("div");
        this.element.className = this.buildRootClassName();
        this.element.dataset.cellId = cell.state.id;
        this.element.dataset.depth = String(cell.state.depth);
        this.render();
    }
    buildRootClassName() {
        var _a;
        const classes = [
            "notebook-cell",
            `notebook-cell-${this.cell.state.type}`,
            `notebook-cell-depth-${this.cell.state.depth}`,
        ];
        if (this.cell.state.isEditing) {
            classes.push("notebook-cell-editing");
        }
        if (this.cell.state.hasError) {
            classes.push("notebook-cell-error");
        }
        if (!this.cell.state.isExpanded && this.cell.children.length > 0) {
            classes.push("notebook-cell-collapsed");
        }
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.cell) {
            classes.push(this.config.cssClasses.cell);
        }
        return classes.join(" ");
    }
    render() {
        this.element.innerHTML = "";
        this.renderHeader();
        if (this.cell.state.hasError && this.cell.state.errorMessage) {
            this.renderError();
        }
        this.renderContent();
        if (this.cell.state.isExpanded && this.cell.children.length > 0) {
            this.renderChildren();
        }
    }
    renderHeader() {
        var _a;
        const header = document.createElement("div");
        header.className = "notebook-cell-header";
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.cellHeader) {
            header.className += " " + this.config.cssClasses.cellHeader;
        }
        const leftSide = document.createElement("div");
        leftSide.className = "notebook-cell-header-left";
        const badge = this.createBadge();
        leftSide.appendChild(badge);
        if (isBlock(this.cell.blockItem)) {
            const block = this.cell.blockItem;
            if (block.name) {
                const nameSpan = document.createElement("span");
                nameSpan.className = "notebook-cell-name";
                nameSpan.textContent = block.name;
                leftSide.appendChild(nameSpan);
            }
        }
        if (this.cell.children.length > 0) {
            const expandBtn = document.createElement("button");
            expandBtn.className = "notebook-btn notebook-expand-btn";
            expandBtn.innerHTML = this.cell.state.isExpanded
                ? '<svg width="12" height="12" viewBox="0 0 12 12"><path d="M2 4l4 4 4-4" stroke="currentColor" fill="none"/></svg>'
                : '<svg width="12" height="12" viewBox="0 0 12 12"><path d="M4 2l4 4-4 4" stroke="currentColor" fill="none"/></svg>';
            expandBtn.title = this.cell.state.isExpanded ? "Collapse" : "Expand";
            expandBtn.addEventListener("click", () => this.handleToggleExpanded());
            leftSide.appendChild(expandBtn);
            const countSpan = document.createElement("span");
            countSpan.className = "notebook-cell-child-count";
            countSpan.textContent = `(${this.cell.children.length})`;
            leftSide.appendChild(countSpan);
        }
        header.appendChild(leftSide);
        const controls = this.createControls();
        header.appendChild(controls);
        this.element.appendChild(header);
    }
    createBadge() {
        const badgeInfo = getCellTypeBadge(this.cell.state.type);
        const badge = document.createElement("span");
        badge.className = `notebook-cell-badge ${badgeInfo.cssClass}`;
        badge.textContent = badgeInfo.label;
        return badge;
    }
    createControls() {
        var _a;
        const controls = document.createElement("div");
        controls.className = "notebook-cell-controls";
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.cellControls) {
            controls.className += " " + this.config.cssClasses.cellControls;
        }
        if (this.config.showMoveButtons && !this.cell.state.isEditing) {
            const moveUpBtn = document.createElement("button");
            moveUpBtn.className = "notebook-btn notebook-move-btn";
            moveUpBtn.innerHTML = "↑";
            moveUpBtn.title = "Move up";
            moveUpBtn.addEventListener("click", () => { var _a, _b; return (_b = (_a = this.config).onMoveUp) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id); });
            controls.appendChild(moveUpBtn);
            const moveDownBtn = document.createElement("button");
            moveDownBtn.className = "notebook-btn notebook-move-btn";
            moveDownBtn.innerHTML = "↓";
            moveDownBtn.title = "Move down";
            moveDownBtn.addEventListener("click", () => { var _a, _b; return (_b = (_a = this.config).onMoveDown) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id); });
            controls.appendChild(moveDownBtn);
        }
        const editBtn = document.createElement("button");
        editBtn.className = "notebook-btn notebook-edit-btn";
        if (this.cell.state.isEditing) {
            editBtn.textContent = "Cancel";
            editBtn.addEventListener("click", () => this.handleCancelEdit());
        }
        else {
            editBtn.textContent = "Edit";
            editBtn.addEventListener("click", () => this.handleStartEdit());
        }
        controls.appendChild(editBtn);
        if (this.config.showDeleteButton && !this.cell.state.isEditing) {
            const deleteBtn = document.createElement("button");
            deleteBtn.className = "notebook-btn notebook-delete-btn";
            deleteBtn.textContent = "Delete";
            deleteBtn.addEventListener("click", () => this.handleDelete());
            controls.appendChild(deleteBtn);
        }
        return controls;
    }
    renderError() {
        var _a;
        const errorDiv = document.createElement("div");
        errorDiv.className = "notebook-cell-error-message";
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.errorMessage) {
            errorDiv.className += " " + this.config.cssClasses.errorMessage;
        }
        errorDiv.textContent = this.cell.state.errorMessage || "Error";
        this.element.appendChild(errorDiv);
    }
    renderContent() {
        var _a;
        const content = document.createElement("div");
        content.className = "notebook-cell-content";
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.cellContent) {
            content.className += " " + this.config.cssClasses.cellContent;
        }
        if (this.cell.state.isEditing) {
            this.renderEditMode(content);
        }
        else {
            this.renderPreviewMode(content);
        }
        this.element.appendChild(content);
    }
    renderPreviewMode(container) {
        if (isRawBlock(this.cell.blockItem)) {
            const rawBlock = this.cell.blockItem;
            const contentDiv = document.createElement("div");
            contentDiv.className = "notebook-rawblock-content";
            if (this.config.markdownParser && rawBlock.contentType === "md") {
                contentDiv.innerHTML = this.config.markdownParser(rawBlock.content);
            }
            else {
                contentDiv.textContent = rawBlock.content;
            }
            container.appendChild(contentDiv);
        }
        else {
            const preview = document.createElement("div");
            preview.className = "notebook-notation-preview";
            if (isLine(this.cell.blockItem)) {
                preview.textContent = "[Line content]";
            }
            else if (isBlock(this.cell.blockItem)) {
                const block = this.cell.blockItem;
                const itemCount = block.blockItems.length;
                preview.textContent = `[${block.blockType}: ${itemCount} item${itemCount !== 1 ? "s" : ""}]`;
            }
            container.appendChild(preview);
        }
    }
    renderEditMode(container) {
        var _a;
        this.editTextarea = document.createElement("textarea");
        this.editTextarea.className = "notebook-edit-textarea";
        if ((_a = this.config.cssClasses) === null || _a === void 0 ? void 0 : _a.editTextarea) {
            this.editTextarea.className += " " + this.config.cssClasses.editTextarea;
        }
        this.editTextarea.value = this.cell.source;
        this.editTextarea.rows = Math.max(3, this.cell.source.split("\n").length + 1);
        container.appendChild(this.editTextarea);
        const actions = document.createElement("div");
        actions.className = "notebook-edit-actions";
        const applyBtn = document.createElement("button");
        applyBtn.className = "notebook-btn notebook-apply-btn";
        applyBtn.textContent = "Apply";
        applyBtn.addEventListener("click", () => this.handleApplyEdit());
        actions.appendChild(applyBtn);
        const cancelBtn = document.createElement("button");
        cancelBtn.className = "notebook-btn notebook-cancel-btn";
        cancelBtn.textContent = "Cancel";
        cancelBtn.addEventListener("click", () => this.handleCancelEdit());
        actions.appendChild(cancelBtn);
        container.appendChild(actions);
        setTimeout(() => { var _a; return (_a = this.editTextarea) === null || _a === void 0 ? void 0 : _a.focus(); }, 0);
    }
    renderChildren() {
        const childrenContainer = document.createElement("div");
        childrenContainer.className = "notebook-cell-children";
        this.element.appendChild(childrenContainer);
        this.childCells = [];
        for (const childModel of this.cell.children) {
            if (this.config.createChildCell) {
                const childCell = this.config.createChildCell(childModel, childrenContainer);
                this.childCells.push(childCell);
            }
            else {
                const childCell = new NotebookCell(childModel, this.config);
                childrenContainer.appendChild(childCell.element);
                this.childCells.push(childCell);
            }
        }
    }
    handleStartEdit() {
        var _a, _b;
        (_b = (_a = this.config).onStartEdit) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id);
    }
    handleApplyEdit() {
        var _a, _b, _c;
        const newSource = ((_a = this.editTextarea) === null || _a === void 0 ? void 0 : _a.value) || "";
        (_c = (_b = this.config).onApplyEdit) === null || _c === void 0 ? void 0 : _c.call(_b, this.cell.state.id, newSource);
    }
    handleCancelEdit() {
        var _a, _b;
        (_b = (_a = this.config).onCancelEdit) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id);
    }
    handleDelete() {
        var _a, _b;
        (_b = (_a = this.config).onDelete) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id);
    }
    handleToggleExpanded() {
        var _a, _b;
        (_b = (_a = this.config).onToggleExpanded) === null || _b === void 0 ? void 0 : _b.call(_a, this.cell.state.id);
    }
    getEditSource() {
        var _a;
        return ((_a = this.editTextarea) === null || _a === void 0 ? void 0 : _a.value) || this.cell.source;
    }
    update(newCell) {
        this.cell = newCell;
        this.element.className = this.buildRootClassName();
        this.render();
    }
    destroy() {
        for (const child of this.childCells) {
            child.destroy();
        }
        this.childCells = [];
        this.element.remove();
    }
}
//# sourceMappingURL=NotebookCell.js.map