import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from './vue.esm-browser.js';

export default {
    props: ['source', 'executionCount', 'isActive', 'isLocked',
            'codeValid', 'outputValid', 'executed', 'hasError', 'asRead'],
    emits: ['save', 'update:source', 'activate'],
    setup(props, { emit }) {
        const isCollapsed = ref(true);
        const isEditing = ref(false);
        const localSource = ref((Array.isArray(props.source) ? props.source.join('') : props.source) || '');
        const originalSource = ref(localSource.value);
        const textareaEl = ref(null);
        const localIsLocked = ref(props.isLocked);

        watch(() => props.isActive, (newVal) => {
            if (!newVal && isEditing.value) {
                saveCode();
            }
        });

        watch(() => props.source, (val) => {
            localSource.value = (Array.isArray(val) ? val.join('') : val) || '';
            nextTick(autoResize);
        });

        watch(() => props.isLocked, (newVal) => {
            console.log("Lock status changed:", newVal);
            localIsLocked.value = newVal;
            if (newVal) {
                cancelEdit();
            }
        });
        
        const autoResize = () => {
            const el = textareaEl.value;
            if (!el) return;
            el.style.boxSizing = 'border-box';
            el.style.overflow = 'hidden';
            el.style.resize = 'none';
            el.style.height = 'auto';
            el.style.height = `${el.scrollHeight}px`;
        };
       
        const highlightedCode = computed(() => {
            const code = localSource.value || '';
            if (!window.Prism || !window.Prism.languages || !window.Prism.languages.python) {
                // HTML escape if Prism not available
                return code.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            }
            try {
                const highlighted = window.Prism.highlight(
                    code, 
                    window.Prism.languages.python, 
                    'python'
                );
                return highlighted;
            } catch (e) {
                console.error('Prism highlighting error:', e);
                // HTML escape on error
                return code.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            }
        });

        const handleTabKey = (e) => {
            if (e.key === 'Tab') {
                e.preventDefault();
                const textarea = textareaEl.value;
                if (!textarea) return;
                
                const start = textarea.selectionStart;
                const end = textarea.selectionEnd;
                const text = localSource.value;
                const spaces = '    '; // 4 spaces
                
                if (start === end) {
                    // No selection - just insert 4 spaces
                    localSource.value = text.substring(0, start) + spaces + text.substring(end);
                    nextTick(() => {
                        textarea.selectionStart = textarea.selectionEnd = start + spaces.length;
                        autoResize();
                    });
                } else {
                    // Selection - indent all selected lines
                    const lines = text.split('\n');
                    const startLine = text.substring(0, start).split('\n').length - 1;
                    const endLine = text.substring(0, end).split('\n').length - 1;
                    
                    for (let i = startLine; i <= endLine; i++) {
                        if (lines[i] !== undefined) {
                            lines[i] = spaces + lines[i];
                        }
                    }
                    
                    const newText = lines.join('\n');
                    localSource.value = newText;
                    
                    nextTick(() => {
                        const newStart = start + spaces.length;
                        const newEnd = end + (endLine - startLine + 1) * spaces.length;
                        textarea.selectionStart = newStart;
                        textarea.selectionEnd = newEnd;
                        autoResize();
                    });
                }
            }
        };

        const enterEditMode = () => {
            if (localIsLocked.value) return;
            isEditing.value = true;
            nextTick(() => {
                autoResize();
                if (textareaEl.value) textareaEl.value.scrollTop = 0;
            });
        };

        const saveCode = () => {
            if (!isEditing.value) return;
            isEditing.value = false;
            emit('save', localSource.value);
        };

        const handleFlushEdits = () => {
            if (isEditing.value) {
                saveCode();
            }
        };

        const onBlur = () => {
            window.dispatchEvent(new Event('plainbook:flush-edits'));
        };

        onMounted(() => {
            window.addEventListener('plainbook:flush-edits', handleFlushEdits);
        });
        onBeforeUnmount(() => {
            window.removeEventListener('plainbook:flush-edits', handleFlushEdits);
        });

        const cancelEdit = () => {
            localSource.value = originalSource.value;
            isEditing.value = false;
        };

        const toggleCollapse = () => {
            isCollapsed.value = !isCollapsed.value;
            if (!isCollapsed.value && isEditing.value) nextTick(autoResize);
        };

        return { isCollapsed, toggleCollapse, isEditing, cancelEdit, localSource,
            localIsLocked, highlightedCode, enterEditMode, saveCode, textareaEl,
            autoResize, handleTabKey, onBlur };
    },
    template: /* html */ `
        <div class="code-cell-wrapper">
            <div style="display: flex; gap: 0.25rem; align-items: center;">
                <button class="button is-small is-white px-2 mt-1"
                        @click="toggleCollapse">
                    {{ isCollapsed ? '▶ &nbsp;Show code' : '▼ &nbsp;Hide code' }}
                </button>
                <button v-if="!isActive && isCollapsed" class="button is-small"
                    style="opacity: 0.6; padding: 0.1rem 0.5rem;"
                    @click.stop="$emit('activate')">
                    <span>Output:&nbsp;</span>
                    <span v-if="!codeValid">Stale</span>
                    <span v-else-if="!outputValid">Stale</span>
                    <span v-else-if="asRead">Unmodified</span>
                    <span v-else>Up to date</span>
                </button>
                <span style="flex: 1;"></span>
                <button v-if="!isCollapsed && !isEditing && !localIsLocked"
                    class="button is-small is-info mt-1 mr-3"
                    @click="enterEditMode">
                    <span class="icon"><i class="bx bx-pencil"></i></span>
                    <span>Edit Code</span>
                </button>
            </div>
            <div v-if="!isCollapsed" style="padding-left: 2.25rem;">
                <div v-if="!isEditing" class="p-2 overflow-x-auto is-size-7" @dblclick="enterEditMode">
                    <pre class="language-python"><code class="language-python" v-html="highlightedCode"></code></pre>
                </div>

                <div v-else class="p-2">
                    <textarea 
                        ref="textareaEl"
                        placeholder="Write the code for this action..."
                        v-model="localSource" 
                        class="textarea is-family-monospace is-size-7 mb-2" 
                        rows="1"
                        style="overflow: hidden; resize: none; height: 0;"
                        @input="autoResize"
                        @keydown.tab.prevent="handleTabKey"
                        @blur="onBlur"
                        @keydown.enter.shift.prevent="saveCode">
                    </textarea>
                    <div style="display: flex; justify-content: flex-end; gap: 0.5rem;">
                        <button class="button is-small" @mousedown.prevent @click.stop="cancelEdit">
                            Cancel
                        </button>
                        <button class="button is-small is-primary" :disabled="localIsLocked" @mousedown.prevent @click.stop="saveCode">
                            Save
                        </button>
                    </div>
                </div>
            </div>
        </div>
    `
};
