@extends('layouts.app')

@section('title', $isCreate ? '양식 디자이너 - 새 양식' : '양식 디자이너 - ' . $template->name)

@push('styles')
<style>
    .block-builder { height: calc(100vh - 120px); }
    .block-palette { width: 220px; }
    .block-properties { width: 300px; }
    .block-canvas { flex: 1; }

    /* 블록 아이템 */
    .block-item { transition: all 0.15s ease; }
    .block-item:hover { box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); }
    .block-item.selected { box-shadow: 0 0 0 2px rgb(59, 130, 246); background-color: rgba(59, 130, 246, 0.03); }

    /* 드래그 고스트 */
    .sortable-ghost { opacity: 0.4; background: #dbeafe !important; }
    .sortable-drag { box-shadow: 0 8px 25px rgba(0,0,0,0.15); }

    /* 팔레트 드래그 아이템 */
    .palette-item { cursor: grab; }
    .palette-item:active { cursor: grabbing; }

    /* 블록 핸들 */
    .block-handle { cursor: grab; opacity: 0.3; transition: opacity 0.15s; }
    .block-item:hover .block-handle { opacity: 1; }

    /* 빈 캔버스 */
    .canvas-empty { border: 2px dashed #d1d5db; min-height: 400px; }
    .canvas-empty.sortable-drag-over { border-color: #3b82f6; background: #eff6ff; }

    /* 속성 패널 입력 */
    .prop-input { font-size: 0.8125rem; }

    /* 테이블 블록 에디터 */
    .table-cell-input { border: 1px solid transparent; padding: 2px 4px; min-width: 40px; }
    .table-cell-input:focus { border-color: #3b82f6; outline: none; background: #fff; }

    /* columns 블록 */
    .column-drop-zone { min-height: 60px; border: 1px dashed #d1d5db; border-radius: 4px; }
    .column-drop-zone.sortable-drag-over { border-color: #3b82f6; background: #eff6ff; }
</style>
@endpush

@section('content')
<div x-data="blockEditor({{ json_encode($initialSchema) }}, {{ $templateId }})"
     x-init="init()"
     @keydown.ctrl.z.prevent="undo()"
     @keydown.ctrl.shift.z.prevent="redo()"
     @keydown.meta.z.prevent="undo()"
     @keydown.meta.shift.z.prevent="redo()"
     @keydown.ctrl.s.prevent="save()"
     @keydown.meta.s.prevent="save()"
     class="block-builder flex flex-col">

    <!-- 상단 툴바 -->
    <div class="flex items-center justify-between bg-white border-b border-gray-200 px-4 py-2 shrink-0">
        <div class="flex items-center gap-3">
            <a href="{{ route('document-templates.index') }}" class="text-gray-500 hover:text-gray-700">
                <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
                </svg>
            </a>
            <div>
                <input type="text" x-model="templateName" placeholder="양식 이름"
                       class="text-lg font-bold border-0 border-b border-transparent hover:border-gray-300 focus:border-blue-500 focus:ring-0 px-1 py-0 bg-transparent">
                <span x-show="isDirty" class="text-xs text-orange-500 ml-2">저장 안됨</span>
            </div>
        </div>
        <div class="flex items-center gap-2">
            <!-- Undo/Redo -->
            <div class="flex items-center border border-gray-200 rounded-lg overflow-hidden">
                <button @click="undo()" :disabled="historyIndex <= 0"
                        class="px-2 py-1.5 text-gray-600 hover:bg-gray-100 disabled:opacity-30 disabled:cursor-not-allowed" title="되돌리기 (Ctrl+Z)">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a5 5 0 015 5v2M3 10l4-4m-4 4l4 4"/>
                    </svg>
                </button>
                <button @click="redo()" :disabled="historyIndex >= history.length - 1"
                        class="px-2 py-1.5 text-gray-600 hover:bg-gray-100 disabled:opacity-30 disabled:cursor-not-allowed border-l border-gray-200" title="다시 실행 (Ctrl+Shift+Z)">
                    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 10H11a5 5 0 00-5 5v2m15-7l-4-4m4 4l-4 4"/>
                    </svg>
                </button>
            </div>

            <!-- 페이지 설정 -->
            <div class="flex items-center gap-1 border border-gray-200 rounded-lg px-2 py-1">
                <select x-model="pageConfig.size" @change="markDirty()" class="text-xs border-0 focus:ring-0 bg-transparent py-0">
                    <option value="A4">A4</option>
                    <option value="A3">A3</option>
                    <option value="B5">B5</option>
                    <option value="Letter">Letter</option>
                </select>
                <select x-model="pageConfig.orientation" @change="markDirty()" class="text-xs border-0 focus:ring-0 bg-transparent py-0">
                    <option value="portrait">세로</option>
                    <option value="landscape">가로</option>
                </select>
            </div>

            <!-- 분류 -->
            <select x-model="category" @change="markDirty()" class="text-xs border border-gray-200 rounded-lg px-2 py-1.5 focus:ring-1 focus:ring-blue-500">
                <option value="">분류 없음</option>
                @foreach($categories as $cat)
                    <option value="{{ $cat['code'] }}">{{ $cat['name'] }}</option>
                @endforeach
            </select>

            <!-- 저장 -->
            <button @click="save()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded-lg text-sm font-medium transition flex items-center gap-1.5">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
                </svg>
                저장
            </button>
        </div>
    </div>

    <!-- 메인 영역 (3패널) -->
    <div class="flex flex-1 overflow-hidden">

        @include('document-templates.partials.block-palette')

        @include('document-templates.partials.block-canvas')

        @include('document-templates.partials.block-properties')

    </div>
</div>
@endsection

@push('scripts')
<script>
function blockEditor(initialSchema, templateId) {
    return {
        // ===== 상태 =====
        blocks: initialSchema?.blocks ?? [],
        selectedBlockId: null,
        history: [],
        historyIndex: -1,
        isDirty: false,
        saving: false,
        templateId: templateId,
        templateName: initialSchema?._name ?? '새 문서양식',
        category: initialSchema?._category ?? '',
        pageConfig: initialSchema?.page ?? {
            size: 'A4',
            orientation: 'portrait',
            margin: [20, 15, 20, 15]
        },

        // ===== Block 타입 레지스트리 =====
        blockTypes: {
            heading:       { icon: 'H',  label: '제목',     category: 'basic', defaultProps: { level: 2, text: '제목을 입력하세요', align: 'left' } },
            paragraph:     { icon: 'T',  label: '텍스트',   category: 'basic', defaultProps: { text: '텍스트를 입력하세요', align: 'left' } },
            table:         { icon: '⊞',  label: '테이블',   category: 'basic', defaultProps: { headers: ['항목', '내용'], rows: [['', '']], showHeader: true } },
            columns:       { icon: '▥',  label: '다단',     category: 'basic', defaultProps: { count: 2, children: [[], []] } },
            divider:       { icon: '─',  label: '구분선',   category: 'basic', defaultProps: { style: 'solid' } },
            spacer:        { icon: '↕',  label: '여백',     category: 'basic', defaultProps: { height: 20 } },
            text_field:    { icon: '▤',  label: '텍스트 입력', category: 'form', defaultProps: { label: '필드명', placeholder: '', required: false, binding: '' } },
            number_field:  { icon: '#',  label: '숫자 입력',  category: 'form', defaultProps: { label: '숫자', min: null, max: null, unit: '', decimal: 0 } },
            date_field:    { icon: '📅', label: '날짜',     category: 'form', defaultProps: { label: '날짜', format: 'Y-m-d' } },
            select_field:  { icon: '▾',  label: '선택',     category: 'form', defaultProps: { label: '선택', options: ['옵션1', '옵션2'], multiple: false } },
            checkbox_field:{ icon: '☑',  label: '체크박스',  category: 'form', defaultProps: { label: '체크', options: ['항목1'] } },
            textarea_field:{ icon: '¶',  label: '장문 입력', category: 'form', defaultProps: { label: '내용', rows: 3 } },
            signature_field:{ icon: '✍', label: '서명란',   category: 'form', defaultProps: { label: '서명', signer: '' } },
        },

        // ===== 초기화 =====
        init() {
            // blocks에 id가 없는 경우 생성
            this.blocks = this.blocks.map(b => ({
                ...b,
                id: b.id || this.generateId()
            }));
            this.pushHistory();
            this.$nextTick(() => this.initSortable());
        },

        // ===== ID 생성 =====
        generateId() {
            return 'b_' + Date.now().toString(36) + '_' + Math.random().toString(36).substr(2, 5);
        },

        // ===== Block CRUD =====
        addBlock(type, afterIndex = null) {
            const def = this.blockTypes[type];
            if (!def) return;

            const newBlock = {
                id: this.generateId(),
                type: type,
                props: JSON.parse(JSON.stringify(def.defaultProps))
            };

            if (afterIndex !== null && afterIndex >= 0) {
                this.blocks.splice(afterIndex + 1, 0, newBlock);
            } else {
                this.blocks.push(newBlock);
            }

            this.selectedBlockId = newBlock.id;
            this.pushHistory();
            this.markDirty();
            this.$nextTick(() => this.reinitSortable());
        },

        removeBlock(id) {
            const idx = this.blocks.findIndex(b => b.id === id);
            if (idx === -1) return;
            this.blocks.splice(idx, 1);
            if (this.selectedBlockId === id) {
                this.selectedBlockId = null;
            }
            this.pushHistory();
            this.markDirty();
        },

        moveBlock(oldIndex, newIndex) {
            if (oldIndex === newIndex) return;
            const [moved] = this.blocks.splice(oldIndex, 1);
            this.blocks.splice(newIndex, 0, moved);
            this.pushHistory();
            this.markDirty();
        },

        duplicateBlock(id) {
            const idx = this.blocks.findIndex(b => b.id === id);
            if (idx === -1) return;
            const original = this.blocks[idx];
            const clone = JSON.parse(JSON.stringify(original));
            clone.id = this.generateId();
            // columns 블록 내 자식도 id 재생성
            if (clone.props.children) {
                clone.props.children = clone.props.children.map(col =>
                    col.map(child => ({ ...child, id: this.generateId() }))
                );
            }
            this.blocks.splice(idx + 1, 0, clone);
            this.selectedBlockId = clone.id;
            this.pushHistory();
            this.markDirty();
            this.$nextTick(() => this.reinitSortable());
        },

        selectBlock(id) {
            this.selectedBlockId = this.selectedBlockId === id ? null : id;
        },

        // ===== 선택된 블록 =====
        getSelectedBlock() {
            if (!this.selectedBlockId) return null;
            return this.blocks.find(b => b.id === this.selectedBlockId) || null;
        },

        updateBlockProp(key, value) {
            const block = this.getSelectedBlock();
            if (!block) return;
            block.props[key] = value;
            this.markDirty();
        },

        // ===== Undo/Redo =====
        pushHistory() {
            // 현재 위치 이후의 히스토리 삭제
            this.history = this.history.slice(0, this.historyIndex + 1);
            this.history.push(JSON.stringify(this.blocks));
            this.historyIndex = this.history.length - 1;
            // 최대 50단계
            if (this.history.length > 50) {
                this.history.shift();
                this.historyIndex--;
            }
        },

        undo() {
            if (this.historyIndex <= 0) return;
            this.historyIndex--;
            this.blocks = JSON.parse(this.history[this.historyIndex]);
            this.markDirty();
            this.$nextTick(() => this.reinitSortable());
        },

        redo() {
            if (this.historyIndex >= this.history.length - 1) return;
            this.historyIndex++;
            this.blocks = JSON.parse(this.history[this.historyIndex]);
            this.markDirty();
            this.$nextTick(() => this.reinitSortable());
        },

        // ===== Dirty 상태 =====
        markDirty() {
            this.isDirty = true;
        },

        // ===== 테이블 블록 헬퍼 =====
        addTableRow(block) {
            const colCount = block.props.headers.length;
            block.props.rows.push(new Array(colCount).fill(''));
            this.pushHistory();
            this.markDirty();
        },

        removeTableRow(block, rowIdx) {
            if (block.props.rows.length <= 1) return;
            block.props.rows.splice(rowIdx, 1);
            this.pushHistory();
            this.markDirty();
        },

        addTableColumn(block) {
            block.props.headers.push('새 열');
            block.props.rows.forEach(row => row.push(''));
            this.pushHistory();
            this.markDirty();
        },

        removeTableColumn(block, colIdx) {
            if (block.props.headers.length <= 1) return;
            block.props.headers.splice(colIdx, 1);
            block.props.rows.forEach(row => row.splice(colIdx, 1));
            this.pushHistory();
            this.markDirty();
        },

        // ===== 저장 =====
        async save() {
            if (this.saving) return;
            this.saving = true;

            const schema = {
                version: '1.0',
                page: this.pageConfig,
                blocks: this.blocks
            };

            const payload = {
                name: this.templateName,
                category: this.category,
                builder_type: 'block',
                schema: schema,
                page_config: this.pageConfig,
                is_active: true,
            };

            try {
                const isCreate = !this.templateId;
                const url = isCreate
                    ? '/api/admin/document-templates'
                    : '/api/admin/document-templates/' + this.templateId;
                const method = isCreate ? 'POST' : 'PUT';

                const response = await fetch(url, {
                    method: method,
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
                    },
                    body: JSON.stringify(payload),
                });

                const result = await response.json();

                if (result.success) {
                    this.isDirty = false;
                    if (isCreate && result.data?.id) {
                        this.templateId = result.data.id;
                        // URL 업데이트 (새로 생성된 경우)
                        window.history.replaceState({}, '',
                            '/document-templates/' + this.templateId + '/block-edit');
                    }
                    if (typeof showToast === 'function') {
                        showToast('저장되었습니다.', 'success');
                    }
                } else {
                    if (typeof showToast === 'function') {
                        showToast(result.message || '저장에 실패했습니다.', 'error');
                    }
                }
            } catch (e) {
                console.error('Save error:', e);
                if (typeof showToast === 'function') {
                    showToast('저장 중 오류가 발생했습니다.', 'error');
                }
            } finally {
                this.saving = false;
            }
        },

        // ===== SortableJS =====
        sortableInstance: null,

        initSortable() {
            const canvas = this.$refs.canvas;
            if (!canvas) return;

            this.sortableInstance = new Sortable(canvas, {
                animation: 150,
                handle: '.block-handle',
                ghostClass: 'sortable-ghost',
                dragClass: 'sortable-drag',
                onEnd: (evt) => {
                    this.moveBlock(evt.oldIndex, evt.newIndex);
                },
            });
        },

        reinitSortable() {
            if (this.sortableInstance) {
                this.sortableInstance.destroy();
            }
            this.initSortable();
        },

        // ===== 팔레트 드래그 추가 =====
        handlePaletteDrop(type) {
            this.addBlock(type);
        },
    };
}
</script>
@endpush
