<template>
  <div class="map-game-container">
    <!-- 标题栏 -->
    <div class="title-box">
      <div class="box-icon" @click="navigateBack">
        <el-icon class="left-icon"><ArrowLeftBold /></el-icon>
        {{ gameTitle }}
      </div>
    </div>

    <div class="content">
      <!-- 地图显示区域 -->
      <div class="map-section">
        <h2>游戏地图</h2>
        <div class="map-container">
          <!-- 地图背景 -->
          <div class="map-background">
            <img :src="mapBackground" alt="地图背景" class="map-image" />

            <!-- 可行走区域标记 -->
            <div
                v-for="(point, index) in walkablePoints"
                :key="index"
                class="walkable-point"
                :style="getPointStyle(point)"
            ></div>

            <!-- 玩家角色 -->
            <div
                class="player"
                :style="playerStyle"
                :class="{ 'collision': isColliding, 'success': hasReachedEnd }"
            ></div>
          </div>

          <!-- 游戏状态提示 -->
          <div v-if="gameMessage" :class="['game-message', messageType]">
            {{ gameMessage }}
          </div>
        </div>
      </div>

      <!-- Blockly工作区 -->
      <div class="blockly-section">
        <div class="toolbox-section" style="display: none;">
          <h2>工具箱</h2>
          <div id="toolbox">
            <!-- 移动控制积木 -->
            <category name="移动控制" colour="%{BKY_MOTION_HUE}">
              <block type="move_forward"></block>
              <block type="move_backward"></block>
              <block type="turn_left"></block>
              <block type="turn_right"></block>
              <block type="turn_around"></block>
            </category>

            <!-- 逻辑控制积木 -->
            <category name="逻辑" colour="%{BKY_LOGIC_HUE}">
              <block type="controls_if"></block>
              <block type="logic_compare"></block>
              <block type="logic_operation"></block>
              <block type="logic_negate"></block>
              <block type="logic_boolean"></block>
            </category>

            <!-- 循环控制积木 -->
            <category name="循环" colour="%{BKY_LOOPS_HUE}">
              <block type="controls_repeat_ext">
                <value name="TIMES">
                  <shadow type="math_number">
                    <field name="NUM"></field>
                  </shadow>
                </value>
              </block>
              <block type="controls_whileUntil"></block>
            </category>

            <!-- 数学运算积木 -->
            <category name="数学" colour="%{BKY_MATH_HUE}">
              <block type="math_number"></block>
              <block type="math_arithmetic"></block>
            </category>
          </div>
        </div>

        <div class="workspace-section">
          <h2>工作区</h2>
          <div class="controls">
            <button id="runCode" @click="runCode">运行代码</button>
            <button @click="clearWorkspace">清空工作区</button>
            <button @click="resetPlayer">重置玩家</button>
          </div>

          <div id="blocklyDiv"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, reactive, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { ArrowLeftBold } from '@element-plus/icons-vue';
import * as Blockly from "blockly";
import 'blockly/msg/zh-hans';
import { javascriptGenerator } from "blockly/javascript";
import mapBackgroundImage from '@/assets/images/blockly/mapGame2.png';
import playerImage from '@/assets/images/blockly/user.png';

// 游戏接口数据
import { getMapGameById } from '@/api/blockly/game.js';


const router = useRouter();
const route = useRoute();
const gameTitle = ref('地图游戏编程'); // 默认标题
const currentGameData = ref(null);
//人物初始朝向
const playerInitialDirection = ref(0);

onMounted(async () => {
  //数据
  await fetchGameData();

  // 初始化可行走点集合
  initWalkablePointsSet();
  // 注册自定义积木
  registerCustomBlocks();
  // 注册JavaScript生成器
  registerJavaScriptGenerators();
  // 初始化Blockly工作区
  initBlockly();
  // 重置玩家位置
  resetPlayer();

  // 获取路由参数中的gameName
  const nameFromRoute = route.query.gameName;
  if (nameFromRoute) {
    gameTitle.value = nameFromRoute;
  }
})

// 获取游戏数据
const fetchGameData = async () => {
  try {
    const gameId = route.query.gameId;
    const nameFromRoute = route.query.gameName;

    if (nameFromRoute) {
      gameTitle.value = nameFromRoute;
    }

    let mapGameData = await getMapGameById(gameId);
    if (mapGameData.code === 0) {

      currentGameData.value = mapGameData?.data;
      await updateGameStateFromData(currentGameData.value);
    }
  } catch (error) {
    console.error('获取游戏数据失败:', error);
  }
};

// 根据获取到的数据更新游戏状态
const updateGameStateFromData = (gameData) => {
  try {
    // 更新地图配置
    gameState.mapConfig.background = gameData.mapBackground ? gameData.mapBackground.trim() : mapBackgroundImage;
    gameState.mapConfig.tileSize = gameData.mapTileSize;

    // 更新玩家位置和方向
    if (gameData.userDirection) {
      playerInitialDirection.value = gameData.userDirection;
    }

    // 更新地图数据
    // 地图起点
    if (gameData.mapStartPoint) {
      const startPoint = JSON.parse(gameData.mapStartPoint);
      gameState.mapData.startPoint = { x: startPoint.x, y: startPoint.y };
      gameState.player.position = { x: startPoint.x, y: startPoint.y };
    }
    // 地图终点
    if (gameData.mapEndPoint) {
      const endPoint = JSON.parse(gameData.mapEndPoint);
      gameState.mapData.endPoint = { x: endPoint.x, y: endPoint.y };
    }
    if (gameData.mapWalkablePoints) {
      gameState.mapData.walkablePoints = JSON.parse(gameData.mapWalkablePoints);
    }
    // 重新初始化可行走点集合
    initWalkablePointsSet();
  } catch (error) {
    console.error('更新游戏状态失败:', error);
  }
};



// 创建游戏状态的响应式对象
const gameState = reactive({
  // 地图配置信息
  mapConfig: {
    // 地图背景图片路径
    background: mapBackgroundImage,
    // 每个瓦片的尺寸（像素）
    tileSize: 110,
  },

  // 玩家相关状态
  player: {
    // 玩家当前位置坐标
    position: { x: 1, y: 1 },
    // 玩家当前朝向：0=上, 1=右, 2=下, 3=左
    direction: 1,
    // 是否正在发生碰撞
    isColliding: false,
    // 是否已到达终点
    hasReachedEnd: false,
    // 是否正在冰块上滑行
    isSliding: false,
  },

  // 游戏状态信息
  status: {
    // 当前显示的游戏消息
    message: '',
    // 消息类型（如success、error、info等）
    messageType: ''
  },

  // 地图数据信息
  mapData: {
    // 游戏起点位置
    startPoint: { x: 1, y: 1 },
    // 游戏终点位置
    endPoint: { x: 4, y: 3 },
    // 地图上所有可行走的点坐标集合，添加type属性区分普通点和冰块
    walkablePoints: [
      { x: 1, y: 1, type: 'ice' }, { x: 2, y: 1, type: 'ice' }, { x: 3, y: 1 }, { x: 4, y: 1 },
      { x: 1, y: 2 }, { x: 2, y: 2 }, { x: 3, y: 2, type: 'ice' }, { x: 4, y: 2 },
      { x: 1, y: 3 }, { x: 2, y: 3 }, { x: 3, y: 3 }, { x: 4, y: 3 },
      { x: 4, y: 3 },
    ],
  }
});

// 计算属性 - 提高性能和可读性
const mapBackground = computed(() => gameState.mapConfig.background);
const tileSize = computed(() => gameState.mapConfig.tileSize);
const walkablePoints = computed(() => gameState.mapData.walkablePoints);
const startPoint = computed(() => gameState.mapData.startPoint);
const endPoint = computed(() => gameState.mapData.endPoint);
const playerPosition = computed(() => gameState.player.position);
const playerDirection = computed(() => gameState.player.direction);
const isColliding = computed(() => gameState.player.isColliding);
const hasReachedEnd = computed(() => gameState.player.hasReachedEnd);
const gameMessage = computed(() => gameState.status.message);
const messageType = computed(() => gameState.status.messageType);

// 计算玩家图片路径，优先使用接口数据
const playerImageSrc = computed(() => {
  if (currentGameData.value && currentGameData.value.userImage) {
    return currentGameData.value.userImage.trim();
  }
  return playerImage;
});
const isSliding = computed(() => gameState.player.isSliding);


// Blockly相关状态
let workspace = null;

// 使用 Map 存储可行走点及其类型，提高查询效率
let walkablePointsMap = new Map();

// 初始化可行走点映射
function initWalkablePointsSet() {
  walkablePointsMap.clear();
  gameState.mapData.walkablePoints.forEach(point => {
    walkablePointsMap.set(`${point.x},${point.y}`, point.type);
  });
}

// 可行走检查函数
function isWalkable(x, y) {
  return walkablePointsMap.has(`${x},${y}`);
}

// 检查是否是冰块点 - 基于walkablePoints中的type属性
function isIce(x, y) {
  return walkablePointsMap.get(`${x},${y}`) === 'ice';
}

// 计算点的样式
function getPointStyle(point) {
  // 检查是否是冰块点，添加不同的样式
  const isIcePoint = isIce(point.x, point.y);
  return {
    left: point.x * tileSize.value - tileSize.value + 'px',
    top: point.y * tileSize.value - tileSize.value + 'px',
    width: tileSize.value + 'px',
    height: tileSize.value + 'px',
    backgroundColor: isIcePoint ? 'rgba(144, 202, 249, 0.5)' : 'rgba(52, 152, 219, 0.2)',
    border: isIcePoint ? '1px solid rgba(33, 150, 243, 0.8)' : '1px solid rgba(52, 152, 219, 0.5)',
    boxShadow: isIcePoint ? '0 0 10px rgba(33, 150, 243, 0.5)' : 'none',
  };
}

// 计算玩家样式
const playerStyle = computed(() => ({
  left: playerPosition.value.x * tileSize.value - tileSize.value + 'px',
  top: playerPosition.value.y * tileSize.value - tileSize.value + 'px',
  transform: `rotate(${playerDirection.value * 90}deg)`,
  '--player-rotation': `${playerDirection.value * 90}deg`,
  '--player-image': `url(${playerImageSrc.value})`,
  width: (tileSize.value * 0.8) + 'px',
  height: (tileSize.value * 0.8) + 'px',
  margin: (tileSize.value * 0.1) + 'px',
}));

// 显示游戏消息
function showGameMessage(message, type = 'info') {
  gameState.status.message = message;
  gameState.status.messageType = type;

  // 3秒后自动清除消息
  setTimeout(() => {
    gameState.status.message = '';
  }, 3000);
}

// 导航返回
function navigateBack() {
  router.back();
}

// 注册自定义积木
function registerCustomBlocks() {
  // 向前移动积木
  Blockly.Blocks['move_forward'] = {
    init: function() {
      this.jsonInit({
        "type": "move_forward",
        "message0": "向前移动",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 230,
        "tooltip": "控制角色向前移动一格",
        "helpUrl": ""
      });
    }
  };

  // 向后移动积木
  Blockly.Blocks['move_backward'] = {
    init: function() {
      this.jsonInit({
        "type": "move_backward",
        "message0": "向后移动",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 230,
        "tooltip": "控制角色向后移动一格",
        "helpUrl": ""
      });
    }
  };

  // 向左转积木
  Blockly.Blocks['turn_left'] = {
    init: function() {
      this.jsonInit({
        "type": "turn_left",
        "message0": "向左转",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 230,
        "tooltip": "控制角色向左转",
        "helpUrl": ""
      });
    }
  };

  // 向右转积木
  Blockly.Blocks['turn_right'] = {
    init: function() {
      this.jsonInit({
        "type": "turn_right",
        "message0": "向右转",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 230,
        "tooltip": "控制角色向右转",
        "helpUrl": ""
      });
    }
  };

  // 向后转积木
  Blockly.Blocks['turn_around'] = {
    init: function() {
      this.jsonInit({
        "type": "turn_around",
        "message0": "向后转",
        "previousStatement": null,
        "nextStatement": null,
        "colour": 230,
        "tooltip": "控制角色向后转",
        "helpUrl": ""
      });
    }
  };
}

// 注册JavaScript生成器
function registerJavaScriptGenerators() {
  // 向前移动生成器
  javascriptGenerator.forBlock['move_forward'] = function(block) {
    return 'await moveForward();\n';
  };

  // 向后移动生成器
  javascriptGenerator.forBlock['move_backward'] = function(block) {
    return 'await moveBackward();\n';
  };

  // 向左转生成器
  javascriptGenerator.forBlock['turn_left'] = function(block) {
    return 'await turnLeft();\n';
  };

  // 向右转生成器
  javascriptGenerator.forBlock['turn_right'] = function(block) {
    return 'await turnRight();\n';
  };

  // 向后转生成器
  javascriptGenerator.forBlock['turn_around'] = function(block) {
    return 'await turnAround();\n';
  };

  // 为重复循环块注册自定义生成器，确保支持异步操作
  javascriptGenerator.forBlock['controls_repeat_ext'] = function(block) {
    const repeats = javascriptGenerator.valueToCode(block, 'TIMES', javascriptGenerator.ORDER_ATOMIC) || '0';

    // 确保获取到的是数字类型，如果是字符串需要转换
    const safeRepeats = `(function() {
      const num = Number(${repeats});
      return isNaN(num) ? 0 : Math.max(0, Math.floor(num));
    })()`;

    // 获取循环体代码
    const branch = javascriptGenerator.statementToCode(block, 'DO');

    // 生成支持异步的循环代码
    let code = `for (let i = 0; i < ${safeRepeats}; i++) {\n`;
    code += javascriptGenerator.prefixLines(branch, javascriptGenerator.INDENT);
    code += '}\n';

    return code;
  };

  // 为while/until循环块注册自定义生成器
  javascriptGenerator.forBlock['controls_whileUntil'] = function(block) {
    const until = block.getFieldValue('MODE') === 'UNTIL';
    const condition = javascriptGenerator.valueToCode(block, 'CONDITION',
        javascriptGenerator.ORDER_NONE) || 'false';
    const branch = javascriptGenerator.statementToCode(block, 'DO');

    // 修复变量作用域问题，使用IIFE包装循环
    let code = '(async function() {\n';
    code += '  let loopCount = 0;\n';
    code += until ? '  while (!((' + condition + ')) && loopCount < 100) {\n' :
        '  while (((' + condition + ')) && loopCount < 100) {\n';
    code += javascriptGenerator.prefixLines(branch, javascriptGenerator.INDENT + '  ');
    code += '    loopCount++';
    code += '    await new Promise(resolve => setTimeout(resolve, 10));\n'; // 防止UI阻塞
    code += '  }\n';
    code += '})();\n';

    return code;
  };

  // 为text_print块添加生成器，用于调试
  javascriptGenerator.forBlock['text_print'] = function(block) {
    const msg = javascriptGenerator.valueToCode(block, 'TEXT', javascriptGenerator.ORDER_NONE) || '';
    return msg;
  };
}

// 初始化Blockly工作区
function initBlockly() {
  const toolbox = document.getElementById('toolbox');
  workspace = Blockly.inject('blocklyDiv', {
    toolbox: toolbox,
    collapse: true,
    comments: true,
    disable: false, // 设为false以允许编辑
    maxBlocks: Infinity,
    trashcan: true,
    horizontalLayout: false,
    toolboxPosition: 'start',
    css: true,
    media: 'https://unpkg.com/blockly/media/',
    rtl: false,
    scrollbars: true,
    sounds: false, // 禁用声音以提高性能
    oneBasedIndex: true,
    grid: {
      spacing: 20,
      length: 3,
      colour: "#ccc",
      snap: true
    },
    zoom: {
      controls: true,
      wheel: true,
      startScale: 1.0,
      maxScale: 3,
      minScale: 0.3,
      scaleSpeed: 1.2
    }
  });
}

// 平滑移动函数
async function smoothMoveTo(targetX, targetY) {
  const startX = playerPosition.value.x;
  const startY = playerPosition.value.y;
  const duration = 500; // 移动动画持续时间（毫秒）
  const startTime = performance.now();

  // 使用 requestAnimationFrame 实现平滑动画
  return new Promise(resolve => {
    function animate(currentTime) {
      const elapsedTime = currentTime - startTime;

      // 计算进度，确保不会超过1
      const progress = Math.min(elapsedTime / duration, 1);

      // 使用缓动函数使动画更自然
      const easedProgress = progress * (2 - progress); // easeOutQuad 缓动

      // 计算当前位置
      const currentX = startX + (targetX - startX) * easedProgress;
      const currentY = startY + (targetY - startY) * easedProgress;

      // 更新玩家位置
      gameState.player.position = { x: currentX, y: currentY };

      // 如果动画未完成，继续下一帧
      if (progress < 1) {
        requestAnimationFrame(animate);
      } else {
        // 动画完成后解析Promise
        resolve();
      }
    }

    // 开始动画
    requestAnimationFrame(animate);
  });
}

// 创建通用的移动函数
async function move(direction) {
  if (isColliding.value || isSliding.value) {
    return;
  }

  let newX = playerPosition.value.x;
  let newY = playerPosition.value.y;

  // 根据当前方向和移动类型计算新位置
  if (direction === 1) {
    // 向前移动
    switch(playerDirection.value) {
      case 0: newY--; break;
      case 1: newX++; break;
      case 2: newY++; break;
      case 3: newX--; break;
    }
  } else {
    // 向后移动
    switch(playerDirection.value) {
      case 0: newY++; break;
      case 1: newX--; break;
      case 2: newY--; break;
      case 3: newX++; break;
    }
  }

  // 检查是否可以移动
  if (isWalkable(newX, newY)) {
    // 使用平滑移动动画
    await smoothMoveTo(newX, newY);

    // 检查新位置是否是冰块，如果是则触发滑行
    if (isIce(newX, newY)) {
      await handleIceSliding();
    }
  } else {
    // 发生碰撞
    gameState.player.isColliding = true;
    showGameMessage('哎呀，撞到墙了！', 'error');

    // 立即中止整个代码执行
    if (executionAbortController) {
      executionAbortController.abort();
    }

    // 1秒后取消碰撞状态
    setTimeout(() => {
      gameState.player.isColliding = false;
    }, 1000);

    // 添加碰撞延迟
    await new Promise(resolve => setTimeout(resolve, 500));
  }
}

// 处理冰块滑行逻辑
async function handleIceSliding() {
  gameState.player.isSliding = true;

  try {
    // 循环检查是否可以继续滑行
    while (true) {
      // 计算下一个位置
      let nextX = playerPosition.value.x;
      let nextY = playerPosition.value.y;

      // 根据当前方向计算下一个位置
      switch(playerDirection.value) {
        case 0: nextY--; break;
        case 1: nextX++; break;
        case 2: nextY++; break;
        case 3: nextX--; break;
      }

      // 检查下一个位置是否可行走
      if (isWalkable(nextX, nextY)) {
        // 执行平滑移动到下一个位置
        await smoothMoveTo(nextX, nextY);

        // 检查下一个位置是否还是冰块
        if (!isIce(nextX, nextY)) {
          // 如果不是冰块，结束滑行
          break;
        }

        // 添加滑行间隔时间
        await new Promise(resolve => setTimeout(resolve, 500));
      } else {
        // 下一个位置不可行走，检查是否是墙体
        gameState.player.isColliding = true;
        showGameMessage('哎呀，撞到墙了！', 'error');

        // 立即中止整个代码执行
        if (executionAbortController) {
          executionAbortController.abort();
        }

        // 1秒后取消碰撞状态
        setTimeout(() => {
          gameState.player.isColliding = false;
        }, 1000);

        // 添加碰撞延迟
        await new Promise(resolve => setTimeout(resolve, 500));

        break;
      }
    }
  } catch (error) {
    console.error('滑行过程中发生错误:', error);
  } finally {
    // 无论如何都要确保滑行状态被重置
    gameState.player.isSliding = false;
  }
}

// 保留原有的API接口
window.moveForward = async function() {
  await move(1);
};

window.moveBackward = async function() {
  await move(-1);
};

//向左转（逆时针旋转90度）
window.turnLeft = async function() {
  // 如果已经发生过碰撞，不再执行任何旋转
  if (isColliding.value) {
    return;
  }

  // 向左转（逆时针旋转90度）
  gameState.player.direction = (playerDirection.value - 1 + 4) % 4;

  // 添加旋转延迟
  await new Promise(resolve => setTimeout(resolve, 500));
};

//向右转（顺时针旋转90度）
window.turnRight = async function() {
  // 如果已经发生过碰撞，不再执行任何旋转
  if (isColliding.value) {
    return;
  }

  // 向右转（顺时针旋转90度）
  gameState.player.direction = (playerDirection.value + 1) % 4;

  // 添加旋转延迟
  await new Promise(resolve => setTimeout(resolve, 500));
};

// 向后转（旋转180度）
window.turnAround = async function() {
  // 如果已经发生过碰撞，不再执行任何旋转
  if (isColliding.value) {
    return;
  }

  // 向后转（旋转180度）
  gameState.player.direction = (playerDirection.value + 2) % 4;

  // 添加旋转延迟
  await new Promise(resolve => setTimeout(resolve, 500));
};

//校验是否到达终点
window.isFinish = async function() {
  // 如果已经发生过碰撞，不再执行任何旋转
  if (isColliding.value) {
    return;
  }

  if (gameState.player.position.x === endPoint.value.x && gameState.player.position.y === endPoint.value.y) {
    gameState.player.hasReachedEnd = true;
    showGameMessage('恭喜你到达终点！', 'success' );
  }
};

// 添加一个变量来跟踪当前执行的代码
let currentExecutionPromise = null;
let executionAbortController = null;
// 运行代码
const runCode = async () => {
  try {
    await resetPlayer();
    await new Promise(resolve => setTimeout(resolve, 500));

    // 创建新的AbortController用于取消执行
    executionAbortController = new AbortController();
    const signal = executionAbortController.signal;

    // 确保生成器和工作区都存在
    if (!javascriptGenerator || !workspace) {
      throw new Error('生成器或工作区未正确初始化');
    }

    // 生成JavaScript代码
    const code = javascriptGenerator.workspaceToCode(workspace) + "await isFinish();";

    try {
      // 增强的安全检查
      const unsafePatterns = [
        'eval(', 'Function(', 'document.write', 'window.location',
        'document.createElement', 'XMLHttpRequest', 'fetch',
        'setInterval', 'setTimeout', 'window.',
        'alert(', 'confirm(', 'prompt(',
        'document.cookie', 'localStorage', 'sessionStorage'
      ];

      const hasUnsafeCode = unsafePatterns.some(pattern => code.includes(pattern));

      if (hasUnsafeCode) {
        throw new Error('代码包含不安全的操作');
      }

      // 包装代码为异步函数执行，并设置超时保护
      currentExecutionPromise = new Promise(async (resolve, reject) => {
        try {
          // 检查信号是否已中止
          if (signal.aborted) {
            throw new Error('执行已取消');
          }

          // 添加信号监听
          signal.addEventListener('abort', () => {
            reject(new Error('执行已取消'));
          });

          const wrappedCode = `(async () => { ${code} })()`;
          await new Function(wrappedCode)();
          resolve();
        } catch (error) {
          reject(error);
        }
      });

    } catch (error) {
      // 捕获并显示执行错误
      if (error.message !== '执行已取消') {
        const errorMsg = error.message || '未知错误';
        showGameMessage(`代码执行错误: ${errorMsg}`, 'error');
        console.error('代码执行错误:', error);
      }
    } finally {
      // 清除当前执行的Promise引用
      currentExecutionPromise = null;
    }
  } catch (error) {
    showGameMessage(`运行时错误: ${error.message || '未知错误'}`, 'error');
    console.error('运行时错误:', error);
  }
};

// 清空工作区
const clearWorkspace = () => {
  workspace.clear();
  showGameMessage('工作区已清空', 'info');
};

// 重置玩家位置和状态
const resetPlayer = () => {
  // 取消任何正在执行的代码
  if (executionAbortController) {
    executionAbortController.abort();
    executionAbortController = null;
  }

  if (currentExecutionPromise) {
    currentExecutionPromise = null;
  }

  gameState.player.position = { ...startPoint.value };
  gameState.player.direction = playerInitialDirection.value; // 重置为向上方向
  gameState.player.isColliding = false; //碰撞标志
  gameState.player.hasReachedEnd = false;
  gameState.player.isSliding = false; // 重置滑行状态
};

// 组件卸载时清理
onUnmounted(() => {
  if (workspace) {
    workspace.dispose();
  }
});
</script>

<style scoped lang="scss">
@use "sass:math";

@function rpx($px) {
  @return math.div($px, 750) * 100vw;
}

//将tileSize属性绑定到CSS变量上
:root {
  --tile-size: v-bind('tileSize + "px"');
}

.map-game-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: transparent;
  overflow-y: auto;
}

/* 自定义滚动条样式 */
.map-game-container::-webkit-scrollbar {
  width: rpx(2); /* 滚动条宽度 */
}

.map-game-container::-webkit-scrollbar-track {
  background: #f1effd; /* 滚动条轨道背景色 */
  border-radius: rpx(4);
}

.map-game-container::-webkit-scrollbar-thumb {
  background: #e2ddfc; /* 滚动条滑块颜色 */
  border-radius: rpx(4);
}

.map-game-container::-webkit-scrollbar-thumb:hover {
  background: #e2ddfc; /* 滚动条滑块 hover 状态颜色 */
}

.title-box {
  position: relative;
  top: 10px;
  padding-left: 15px;
  margin-bottom: 20px;
  z-index: 10;
}

.box-icon {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 20px;
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 30px;
  backdrop-filter: blur(10px);
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 16px;
  color: #333;
  font-weight: 500;
  width: fit-content;
}

.box-icon:hover {
  background-color: rgba(255, 255, 255, 0.9);
  transform: translate(-3px);
}

.left-icon {
  font-size: 18px;
}

.content {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 20px;
}

/* 地图区域样式 */
.map-section {
  flex: 1;
  min-width: 500px;
  background: rgba(248, 249, 250, 0.82);
  padding: 15px;
  border-radius: 15px;
}

.map-section h2 {
  margin-bottom: 15px;
  color: #2c3e50;
  border-bottom: 2px solid #3498db;
  padding-bottom: 8px;
}

.map-container {
  //position: relative;
  //width: 100%;
  //height: 100%  ;
  //display: flex;
  //justify-content: center;
  //align-items: center;
}

.map-background {
  position: relative;
  width: 100%;
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  //margin: 0 auto;
  //border: 2px solid #ddd;
  //border-radius: 8px;
  //overflow: hidden;
  //background-color: #f0f0f0;

}

.map-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 可行走区域样式 */
.walkable-point {
  position: absolute;
  background-color: rgba(52, 152, 219, 0.2);
  border: 1px solid rgba(52, 152, 219, 0.5);
  box-sizing: border-box;
  //是否显示可行路线
  opacity: 0;
}

/* 玩家样式 */
.player {
  position: absolute;
  background-image: var(--player-image);
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  border-radius: 5px;
  transition: all 0.3s ease;
  z-index: 10;
}

/* 碰撞动画 */
.player.collision {
  animation: collision 0.5s ease-in-out;
}

@keyframes collision {
  0% { transform: rotate(var(--player-rotation)) translateX(0) translateY(0) scale(1); }
  25% { transform: rotate(var(--player-rotation)) translateX(-3px) translateY(-2px) scale(1.2); }
  50% { transform: rotate(var(--player-rotation)) translateX(3px) translateY(2px) scale(1.2); }
  75% { transform: rotate(var(--player-rotation)) translateX(-3px) translateY(-2px) scale(1.2); }
  100% { transform: rotate(var(--player-rotation)) translateX(0) translateY(0) scale(1); }
}

/* 滑行动画 */
@keyframes sliding {
  0% { transform: rotate(var(--player-rotation)) translateX(0) translateY(0); }
  25% { transform: rotate(var(--player-rotation)) translateX(2px) translateY(0); }
  75% { transform: rotate(var(--player-rotation)) translateX(-2px) translateY(0); }
  100% { transform: rotate(var(--player-rotation)) translateX(0) translateY(0); }
}

/* 成功到达终点动画 */
.player.success {
  animation: success 1s ease-in-out;
}

@keyframes success {
  0% { transform: rotate(var(--player-rotation)) scale(1); }
  10% { transform: rotate(var(--player-rotation)) scale(1.2) translateX(-5px) translateY(-5px); }
  20% { transform: rotate(var(--player-rotation)) scale(1.3) translateX(5px) translateY(5px); }
  30% { transform: rotate(var(--player-rotation)) scale(1.2) translateX(-5px) translateY(-5px); }
  40% { transform: rotate(var(--player-rotation)) scale(1.3) translateX(5px) translateY(5px); }
  50% { transform: rotate(var(--player-rotation)) scale(1.4) translateX(0) translateY(0); }
  60% { transform: rotate(var(--player-rotation)) scale(1.3) translateX(-3px) translateY(-3px); }
  70% { transform: rotate(var(--player-rotation)) scale(1.2) translateX(3px) translateY(3px); }
  80% { transform: rotate(var(--player-rotation)) scale(1.3) translateX(-3px) translateY(-3px); }
  90% { transform: rotate(var(--player-rotation)) scale(1.2) translateX(3px) translateY(3px); }
  100% { transform: rotate(var(--player-rotation)) scale(1); }
}

/* 游戏消息样式 */
.game-message {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  border-radius: 5px;
  font-weight: bold;
  z-index: 20;
  min-width: 200px;
  text-align: center;
}

.game-message.success {
  background-color: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

.game-message.error {
  background-color: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.game-message.info {
  background-color: #d1ecf1;
  color: #0c5460;
  border: 1px solid #bee5eb;
}

/* Blockly区域样式 */
.blockly-section {
  flex: 1;
  min-width: 600px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.toolbox-section {
  background: rgba(248, 249, 250, 0.82);
  padding: 15px;
  border-radius: 15px;
}

// 合并重复的区块标题样式
.map-section h2,
.toolbox-section h2,
.workspace-section h2 {
  margin-bottom: 15px;
  color: #2c3e50;
  border-bottom: 2px solid #3498db;
  padding-bottom: 8px;
}

// 合并重复的区块背景样式
.map-section,
.toolbox-section,
.workspace-section {
  background: rgba(248, 249, 250, 0.82);
  padding: 15px;
  border-radius: 15px;
  height: 100%;
}

.workspace-section h2 {
  margin-bottom: 15px;
  color: #2c3e50;
  border-bottom: 2px solid #3498db;
  padding-bottom: 8px;
}

#blocklyDiv {
  height: 80%;
  min-height: 500px;
  width: 100%;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 8px;
}

.controls {
  display: flex;
  gap: 10px;
  margin: 15px 0px;
  flex-wrap: wrap;
}

button {
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  background: #3498db;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.3s ease;
}

button:hover {
  background: #2980b9;
  transform: translateY(-2px);
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
}

#runCode {
  background: #e74c3c;
}

#runCode:hover {
  background: #c0392b;
}

/* 响应式布局 */
@media (max-width: 1200px) {
  .content {
    flex-direction: column;
  }

  .map-section,
  .blockly-section {
    min-width: 100%;
  }

  .map-background {
    width: 100%;
    height: 400px;
  }
}
</style>