{{:ModuleInclude('public/header')}}

<style>
    .venue-editor {
        background: #fff;
        padding: 30px;
        border-radius: 8px;
        box-shadow: 0 2px 12px rgba(0,0,0,0.05);
    }
    .section-title {
        font-size: 18px;
        font-weight: bold;
        margin: 30px 0 20px 0;
        padding-left: 10px;
        border-left: 4px solid #1677ff;
    }
    .room-tabs {
        margin-bottom: 20px;
    }
    .room-tabs button {
        margin-right: 10px;
        margin-bottom: 10px;
    }
    .seat-preview {
        background: #fdfdfd;
        border: 2px dashed #eee;
        padding: 120px 20px 40px 20px; /* 增加顶部留白 120px 解决气泡遮挡 */
        min-height: 400px;
        position: relative;
        overflow: auto;
    }
    .seat-row {
        display: flex;
        justify-content: center;
        margin-bottom: 5px;
        white-space: nowrap;
    }
    .seat-col {
        width: 30px;
        height: 30px;
        margin: 2px;
        border-radius: 4px;
        background: #eee;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 10px;
        color: #fff;
        cursor: pointer;
        position: relative;
        transition: transform 0.2s;
    }
    .seat-col:hover {
        transform: scale(1.2);
        z-index: 10;
    }
    .seat-empty {
        width: 30px;
        height: 30px;
        margin: 2px;
        background: transparent;
    }
    .seat-tooltip {
        position: absolute;
        bottom: 100%;
        left: 50%;
        transform: translateX(-50%);
        background: rgba(0,0,0,0.8);
        color: #fff;
        padding: 5px 10px;
        border-radius: 4px;
        font-size: 12px;
        white-space: nowrap;
        display: none;
        pointer-events: none;
        z-index: 100;
        margin-bottom: 10px;
    }
    .seat-col:hover .seat-tooltip {
        display: block;
    }
    .img-preview-box {
        display: inline-block;
        width: 120px;
        margin: 10px;
        position: relative;
    }
    .img-preview-box img {
        width: 100%;
        height: 80px;
        object-fit: cover;
        border-radius: 4px;
        border: 1px solid #ddd;
    }
    .img-preview-box .rm-img {
        position: absolute;
        top: -8px;
        right: -8px;
        background: #ff4d4f;
        color: #fff;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        text-align: center;
        line-height: 18px;
        cursor: pointer;
        font-size: 14px;
    }
    [v-cloak] { display: none; }
</style>

<!-- 加大左右间距，提供更好的工业级视觉呼吸感 -->
<div class="right-content" style="padding: 0 60px;">
    <div class="content-nav">
        <a href="{{:PluginsAdminUrl('vr_ticket', 'admin', 'index')}}" class="am-btn am-btn-secondary am-btn-xs">
            <i class="am-icon-angle-left"></i> 返回
        </a>
        <span>{{if !empty($info['id'])}}编辑{{else}}添加{{/if}}场馆</span>
    </div>

    <div class="content-body" id="app" v-cloak>
        <form class="am-form form-validation" action="{{:PluginsAdminUrl('vr_ticket', 'admin', 'venuesave')}}" method="POST" request-type="ajax-url" request-value="{{:PluginsAdminUrl('vr_ticket', 'admin', 'index')}}">
            <input type="hidden" name="id" value="{{if !empty($info['id'])}}{{$info.id}}{{/if}}" />
            
            <div class="venue-editor">
                <!-- 场馆基础信息 -->
                <div class="section-title">场馆基础信息</div>
                <div class="am-form-group">
                    <label>场馆名称 (简短名称，用于搜索和标题)</label>
                    <input type="text" name="name" value="{{if !empty($info['name'])}}{{$info.name}}{{/if}}" placeholder="如: 北京万达影城" required />
                </div>

                <div class="am-form-group">
                    <label>完整场馆名称 (场馆完整的全称，用户可见)</label>
                    <input type="text" v-model="venue.name" placeholder="请输入完整场馆名称" class="am-radius" />
                </div>

                <div class="am-form-group">
                    <label>详细地址</label>
                    <div class="am-input-group">
                        <input type="text" v-model="venue.address" placeholder="请输入场馆地址" class="am-radius" />
                        <span class="am-input-group-btn">
                            <button class="am-btn am-btn-default am-radius" type="button" @click="openAmap"><i class="am-icon-map-marker"></i> 解析坐标</button>
                            <a href="{{:PluginsAdminUrl('vr_ticket', 'admin', 'Setup')}}" target="_blank" class="am-btn am-btn-default am-radius" title="配置高德 API"><i class="am-icon-cog"></i></a>
                        </span>
                    </div>
                    <div class="am-margin-top-sm" v-if="venue.location.lng">
                        <div class="am-text-xs am-text-grey am-margin-bottom-xs">
                            <i class="am-icon-check-circle am-text-success"></i> 已确立坐标: 经度 [[ venue.location.lng ]], 纬度 [[ venue.location.lat ]]
                        </div>
                        <div class="am-padding-xs am-radius" style="border: 1px solid #e0e0e0; display: inline-block; background: #fafafa;" v-if="staticMapUrl">
                            <img :src="staticMapUrl" alt="地图定位预览" style="width: 500px; height: 250px; object-fit: cover; border-radius: 2px; display: block;" />
                        </div>
                    </div>
                </div>

                <div class="am-form-group">
                    <label>场馆图片组</label>
                    <div>
                        <div class="img-preview-box" v-for="(img, idx) in venue.images" :key="idx">
                            <img :src="img || '/static/common/images/default-image.png'" />
                            <span class="rm-img" @click="venue.images.splice(idx, 1)">&times;</span>
                        </div>
                        <button type="button" class="am-btn am-btn-sm am-btn-success" @click="addImage">
                            <i class="am-icon-plus"></i> 添加外部图片
                        </button>
                    </div>
                </div>

                <!-- 放映室/展厅管理器 -->
                <div class="section-title">放映室/展厅配置</div>
                <div class="room-tabs">
                    <button type="button" 
                            class="am-btn am-btn-sm am-radius" 
                            v-for="(rm, rIdx) in rooms" 
                            :key="rIdx"
                            :class="{'am-btn-primary': currentRoomIdx === rIdx, 'am-btn-default': currentRoomIdx !== rIdx}"
                            @click="currentRoomIdx = rIdx">
                        [[ rm.name ]]
                    </button>
                    <button type="button" class="am-btn am-btn-sm am-btn-success am-btn-hollow am-radius " @click="addRoom">
                        <i class="am-icon-plus"></i> 新增放映室
                    </button>
                </div>

                <div class="am-panel am-panel-default" v-if="currentRoom">
                    <div class="am-panel-hd am-cf">
                        当前放映室：<input type="text" v-model="currentRoom.name" style="width:200px; display:inline-block;" class="am-form-field am-input-sm" />
                        <button type="button" class="am-btn am-btn-xs am-btn-danger am-fr" @click="removeRoom(currentRoomIdx)" v-if="rooms.length > 1">删除此放映室</button>
                    </div>
                    <div class="am-panel-bd">
                        <!-- 分区配置 -->
                        <div style="font-weight:bold; margin-bottom:10px;">分区及价格配置</div>
                        <table class="am-table am-table-bordered am-table-compact">
                            <thead>
                                <tr>
                                    <th>分区标识(排布用)</th>
                                    <th>分区名称</th>
                                    <th>价格(元)</th>
                                    <th>显示颜色</th>
                                    <th>操作</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr v-for="(zone, index) in currentRoom.sections" :key="index">
                                    <td><input type="text" v-model="zone.char" class="am-form-field am-input-sm" style="text-transform: uppercase;" maxlength="1" @input="zone.char = zone.char.toUpperCase()" /></td>
                                    <td><input type="text" v-model="zone.name" class="am-form-field am-input-sm" /></td>
                                    <td><input type="number" v-model="zone.price" class="am-form-field am-input-sm" step="0.01" /></td>
                                    <td><input type="color" v-model="zone.color" style="height: 32px;" class="am-form-field am-input-sm" /></td>
                                    <td>
                                        <button type="button" class="am-btn am-btn-danger am-btn-xs" @click="removeZone(index)">删除</button>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <button type="button" class="am-btn am-btn-secondary am-btn-xs" @click="addZone">添加分区</button>

                        <hr>

                        <!-- 文本排布编辑器 -->
                        <div style="font-weight:bold; margin-bottom:10px;">文本排布设计器</div>
                        <div class="am-alert am-alert-secondary am-text-sm">
                            <p>请按行输入字符矩阵，每个字符代表一个座位。字符必须在上面的**分区配置**中定义。</p>
                            <p><strong>特殊符号：</strong>使用 <code>_</code> (下划线) 或 <code>-</code> (减号) 代表通道或空白墙壁。</p>
                        </div>
                        <textarea 
                            :value="currentMapText" 
                            @input="handleMapInput"
                            placeholder="每行代表一排，字符代表分区：&#10;AAAAA&#10;BBBBB&#10;CCCCC&#10;使用 - 或 _ 表示过道/空位" 
                            rows="12" 
                            class="am-radius am-margin-top-xs"
                            style="font-family: monospace; letter-spacing: 2px; line-height: 1.5;"
                        ></textarea>

                        <hr>

                        <!-- 座位预览 -->
                        <div style="font-weight:bold; margin-bottom:10px;">座位实时预览 (放映室：[[ currentRoom.name ]])</div>
                        <div class="am-margin-bottom-sm">
                            <span class="am-margin-right">总座位数：<strong>[[ currentTotalSeats ]]</strong></span>
                            <span>分区数：<strong>[[ Object.keys(currentActiveZones).length ]]</strong></span>
                        </div>
                        <div class="seat-preview am-scrollable-horizontal">
                            <div class="seat-row" v-for="(row, rIdx) in currentSeatRows" :key="rIdx">
                                <div v-for="(char, cIdx) in row" :key="cIdx" 
                                     :class="char === '_' || char === '-' ? 'seat-empty' : 'seat-col'"
                                     :style="{ backgroundColor: getSeatColor(char) }">
                                     <template v-if="char !== '_' && char !== '-'">
                                        [[ char ]]
                                        <div class="seat-tooltip">
                                            [[ getSeatTooltip(char, rIdx, cIdx) ]]
                                        </div>
                                     </template>
                                </div>
                            </div>
                        </div>

                    </div>
                </div>

                <div class="am-form-group am-margin-top-lg">
                    <button type="submit" class="am-btn am-btn-primary am-btn-block am-radius">保存配置</button>
                </div>
            </div>
            
            <!-- 序列化数据存储 (Base64编码传输) -->
            <input type="hidden" name="seat_map_raw" id="seatMapRawInput" :value="compiledJsonRaw" />
        </form>
    </div>
</div>

<!-- 初始数据注入 -->
<script type="text/json" id="venueInitialData">
{{if !empty($info['seat_map'])}}{{$info['seat_map']|raw}}{{else}}{}{{/if}}
</script>

<!-- 注入插件全局配置数据 -->
<script type="text/json" id="vrPluginConfig">
{{if !empty($vr_config)}}{{$vr_config|json_encode|raw}}{{else}}{}{{/if}}
</script>

<!-- 引入 Vue3 库 (通过稳定国内 CDN 解决卡顿/无限加载问题) -->
<script src="https://cdn.staticfile.net/vue/3.3.4/vue.global.prod.min.js"></script>
<script>
    const { createApp, ref, computed, watch, onMounted } = Vue;

    let initialMap = {};
    let vrConfig = {};
    try {
        const rawData = document.getElementById('venueInitialData').textContent.trim();
        initialMap = JSON.parse(rawData || "{}");
        
        const configData = document.getElementById('vrPluginConfig').textContent.trim();
        vrConfig = JSON.parse(configData || "{}");
    } catch(e) {
        console.error("解析配置失败", e);
    }

    createApp({
        delimiters: ['[[', ']]'],
        setup() {
            // 基础状态
            const venue = ref({
                name: initialMap.venue?.name || '',
                address: initialMap.venue?.address || '',
                location: initialMap.venue?.location || { lng: '', lat: '' },
                images: initialMap.venue?.images || []
            });

            // 放映室数组
            const rooms = ref(initialMap.rooms || [
                {
                    name: '主要展厅',
                    map: ['AAAAA', 'AAAAA', 'BBBBB'],
                    sections: [
                        { char: 'A', name: 'VIP区', price: 999, color: '#ff4d4f' },
                        { char: 'B', name: '普通区', price: 299, color: '#1677ff' }
                    ],
                    seats: {}
                }
            ]);

            const currentRoomIdx = ref(0);

            const currentRoom = computed(() => {
                return rooms.value[currentRoomIdx.value] || null;
            });

            // 解决多行文本编辑时被吞车车的 Bug：保持单向数据流
            const currentMapText = ref('');
            
            // 切换房间时更新本地文本框
            watch(() => currentRoom.value, (newRoom) => {
                if (newRoom) {
                    currentMapText.value = newRoom.map.join('\n');
                } else {
                    currentMapText.value = '';
                }
            }, { immediate: true });

            // 处理输入变化：实时同步到底层数据对象以触发预览刷新
            const handleMapInput = (e) => {
                const val = e.target.value;
                currentMapText.value = val;
                if (currentRoom.value) {
                    // 同步到数组格式，供渲染预览使用
                    // 我们保留空行在内存中以便打字流畅，但在保存时后端会做过滤
                    currentRoom.value.map = val.split('\n').map(r => r.trim().toUpperCase());
                }
            };

            const currentSeatRows = computed(() => {
                return currentRoom.value ? currentRoom.value.map.map(row => row.split('')) : [];
            });

            const currentActiveZones = computed(() => {
                if (!currentRoom.value) return {};
                const zones = {};
                currentRoom.value.sections.forEach(z => {
                    zones[z.char.toUpperCase()] = z;
                });
                return zones;
            });

            const currentTotalSeats = computed(() => {
                let total = 0;
                currentSeatRows.value.forEach(row => {
                    row.forEach(char => {
                        if (char !== '_' && char !== '-') total++;
                    });
                });
                return total;
            });

            // 方法
            const addRoom = () => {
                rooms.value.push({
                    name: '新放映室 ' + (rooms.value.length + 1),
                    map: ['AAAAA'],
                    sections: [{ char: 'A', name: '默认分区', price: 0, color: '#1677ff' }],
                    seats: {}
                });
                currentRoomIdx.value = rooms.value.length - 1;
            };

            const removeRoom = (idx) => {
                if (confirm('确定删除此放映室吗？')) {
                    rooms.value.splice(idx, 1);
                    if (currentRoomIdx.value >= rooms.value.length) {
                        currentRoomIdx.value = Math.max(0, rooms.value.length - 1);
                    }
                }
            };

            const addZone = () => {
                currentRoom.value.sections.push({ char: '', name: '', price: 0, color: '#1677ff' });
            };

            const removeZone = (idx) => {
                currentRoom.value.sections.splice(idx, 1);
            };

            const getSeatColor = (char) => {
                const charUpper = char.toUpperCase();
                return currentActiveZones.value[charUpper]?.color || '#ddd';
            };

            const getSeatTooltip = (char, rIdx, cIdx) => {
                const charUpper = char.toUpperCase();
                const zone = currentActiveZones.value[charUpper];
                if (!zone) return '未定义分区';
                return `${zone.name} | 第${rIdx+1}排 ${cIdx+1}座 | ￥${zone.price}`;
            };

            const addImage = () => {
                const url = prompt('请输入外部图片 URL 地址:');
                if (url && url.trim() !== '') {
                    venue.value.images.push(url.trim());
                }
            };

            // 高德地图功能 (基于配置中的 API Key)
            const openAmap = () => {
                const apiKey = vrConfig.amap_api_key;
                if (!apiKey) {
                    alert('请先在 [插件设置] 中配置高德 Web 端 API Key，即可开启地图选点功能。');
                    return;
                }
                const addr = venue.value.address;
                if (!addr || addr.trim() === '') {
                    alert('请先在左侧输入场馆详细地址，再进行坐标智能解析。');
                    return;
                }
                
                fetch(`https://restapi.amap.com/v3/geocode/geo?address=${encodeURIComponent(addr.trim())}&key=${apiKey}`)
                    .then(response => response.json())
                    .then(data => {
                        if (data.status === '1' && data.geocodes && data.geocodes.length > 0) {
                            const loc = data.geocodes[0].location; 
                            if (loc) {
                                const parts = loc.split(',');
                                venue.value.location = {
                                    lng: parts[0],
                                    lat: parts[1]
                                };
                                alert(`解析成功！\n标准地址: ${data.geocodes[0].formatted_address}\n经度: ${parts[0]}, 纬度: ${parts[1]}`);
                            } else {
                                alert('未能解析到准确的坐标，请尝试细化地址。');
                            }
                        } else {
                            alert('地址解析失败：' + (data.info || '未知错误，请检查 API Key 权限或地址格式。'));
                        }
                    })
                    .catch(err => {
                        console.error('高德API请求错误:', err);
                        alert('网络请求异常，无法访问高德 API，请检查网络设置或稍后重试。');
                    });
            };

            // 高德静态地图 URL
            const staticMapUrl = computed(() => {
                const apiKey = vrConfig.amap_api_key;
                if (!apiKey || !venue.value.location.lng || !venue.value.location.lat) {
                    return '';
                }
                const lng = venue.value.location.lng;
                const lat = venue.value.location.lat;
                // zoom=15，尺寸 500x250，中心点 location，标点 markers
                return `https://restapi.amap.com/v3/staticmap?location=${lng},${lat}&zoom=15&size=500*250&markers=mid,0xFF0000,A:${lng},${lat}&key=${apiKey}`;
            });

            // 序列化
            const compiledJsonRaw = computed(() => {
                // 过滤掉空的房间名称等逻辑可以在此执行
                const resultRooms = rooms.value.map(rm => {
                    // 后端会过滤空行，这里保持数据纯净
                    return rm;
                });
                const payload = {
                    venue: venue.value,
                    rooms: resultRooms
                };
                const jsonStr = JSON.stringify(payload);
                // 使用 Base64 编码绕过 ShopXO 框架对 URL 的自动截断/净化逻辑
                try {
                    return btoa(unescape(encodeURIComponent(jsonStr)));
                } catch(e) {
                    console.error("Base64 编码失败", e);
                    return jsonStr; // 回退到原始 JSON
                }
            });

            return {
                venue,
                rooms,
                currentRoom,
                currentRoomIdx,
                currentMapText,
                handleMapInput,
                currentSeatRows,
                currentActiveZones,
                currentTotalSeats,
                addRoom,
                removeRoom,
                addZone,
                removeZone,
                getSeatColor,
                getSeatTooltip,
                addImage,
                openAmap,
                staticMapUrl,
                compiledJsonRaw
            };
        }
    }).mount('#app');
</script>

{{:ModuleInclude('public/footer')}}