<template>
  <div class="brush-panel" @click.stop="">
    <div class="brush-panel-wrapper">
      <div class="brush-panel-content">
        <!-- 笔刷类型选择 -->
        <div class="brush-section">
          <div class="section-header">
            <span>笔刷类型</span>
          </div>
          <div class="brush-type-grid">
            <div
              v-for="brush in brushStore.state.availableBrushes"
              :key="brush.id"
              @click="setBrushTypeWithCommand(brush.id)"
              :class="[
                'brush-type-item',
                { active: brushStore.state.type === brush.id },
              ]"
            >
              <div
                class="brush-preview"
                :style="getBrushPreviewStyle(brush)"
              ></div>
              <span class="brush-name">{{ brush.name }}</span>
            </div>
          </div>
        </div>

        <!-- 动态渲染笔刷可配置属性 -->
        <template
          v-for="(properties, category) in propertiesByCategory"
          :key="category"
        >
          <div class="brush-section">
            <div class="section-header">
              <span>{{ category }}</span>
              <!-- <div class="section-actions" v-if="category === '纹理'">
                <button class="action-btn" @click="showLibrary = !showLibrary">
                  <i class="icon-library">📚</i> 材质库
                </button>
              </div> -->
            </div>

            <!-- 针对每个属性，根据其类型渲染合适的控件 -->
            <div class="property-list">
              <div
                v-for="prop in properties"
                :key="prop.id"
                class="property-item"
              >
                <!-- 滑块控件 -->
                <template v-if="prop.type === 'slider'">
                  <div class="slider-property">
                    <div class="slider-header">
                      <span>{{ prop.name }}</span>
                      <span class="slider-value">
                        {{ formatPropertyValue(prop) }}
                      </span>
                    </div>
                    <div class="slider-container">
                      <input
                        type="range"
                        :value="prop.value"
                        @input="
                          (e) =>
                            handlePropertyChange(
                              prop.id,
                              parseFloat(e.target.value)
                            )
                        "
                        :min="prop.min || 0"
                        :max="prop.max || 100"
                        :step="prop.step || 1"
                        class="property-slider"
                      />
                    </div>
                    <!-- 预设值按钮，如果定义了预设 -->
                    <div v-if="prop.presets" class="property-presets">
                      <button
                        v-for="preset in prop.presets"
                        :key="preset"
                        @click="handlePropertyChange(prop.id, preset)"
                        :class="{ active: Math.abs(prop.value - preset) < 0.1 }"
                      >
                        {{ preset }}
                      </button>
                    </div>
                  </div>
                </template>

                <!-- 颜色选择器 -->
                <template v-else-if="prop.type === 'color'">
                  <div class="color-property">
                    <div class="color-header">
                      <span>{{ prop.name }}</span>
                      <div
                        class="color-preview"
                        :style="{ backgroundColor: prop.value }"
                      ></div>
                    </div>
                    <div class="color-row">
                      <input
                        type="color"
                        :value="prop.value"
                        @input="
                          (e) => handlePropertyChange(prop.id, e.target.value)
                        "
                        class="color-picker"
                      />
                      <!-- 如果是主颜色，显示最近使用的颜色 -->
                      <div v-if="prop.id === 'color'" class="recent-colors">
                        <div
                          v-for="(color, index) in brushStore.state
                            .recentColors"
                          :key="index"
                          class="color-item"
                          :style="{ backgroundColor: color }"
                          @click="handlePropertyChange(prop.id, color)"
                        ></div>
                      </div>
                    </div>
                  </div>
                </template>

                <!-- 复选框 -->
                <template v-else-if="prop.type === 'checkbox'">
                  <div class="checkbox-property">
                    <span>{{ prop.name }}</span>
                    <div class="toggle-switch">
                      <input
                        type="checkbox"
                        :checked="prop.value"
                        @change="
                          (e) => handlePropertyChange(prop.id, e.target.checked)
                        "
                        :id="`toggle-${prop.id}`"
                      />
                      <label :for="`toggle-${prop.id}`"></label>
                    </div>
                  </div>
                </template>

                <!-- 选择器 -->
                <template v-else-if="prop.type === 'select'">
                  <div class="select-property">
                    <span>{{ prop.name }}</span>
                    <select
                      :value="prop.value"
                      @change="
                        (e) => handlePropertyChange(prop.id, e.target.value)
                      "
                      class="property-select"
                    >
                      <option
                        v-for="option in prop.options"
                        :key="option.value"
                        :value="option.value"
                      >
                        {{ option.label }}
                      </option>
                    </select>
                  </div>
                </template>

                <!-- 文件选择器（用于材质） -->
                <!-- <template v-else-if="prop.type === 'file'">
                  <div class="file-property">
                    <div class="file-header">
                      <span>{{ prop.name }}</span>
                    </div>
                    <div
                      class="file-preview"
                      @click="handleFileSelect(prop.id)"
                    >
                      <img v-if="prop.value" :src="prop.value" alt="材质预览" />
                      <div v-else class="no-file">点击上传材质图片</div>
                    </div>
                    <div class="file-actions">
                      <button
                        class="select-file-btn"
                        @click="handleFileSelect(prop.id)"
                      >
                        上传图片
                      </button>
                      <button
                        class="clear-file-btn"
                        @click="handlePropertyChange(prop.id, '')"
                        v-if="prop.value"
                      >
                        清除
                      </button>
                    </div>
                  </div>
                </template> -->

                <!-- 材质网格选择器 -->
                <template v-else-if="prop.type === 'texture-grid'">
                  <div class="texture-grid-property">
                    <div class="texture-grid-header">
                      <span>{{ prop.name }}</span>
                    </div>
                    <div class="texture-grid">
                      <!-- 预设纹理 -->
                      <div
                        v-for="texture in prop.options"
                        :key="texture.value"
                        class="texture-item"
                        :class="{ active: prop.value === texture.value }"
                        @click="handleTextureSelect(texture.value)"
                      >
                        <img
                          :src="texture.preview || texture.value"
                          :alt="texture.label"
                          class="texture-thumbnail"
                        />
                        <!-- <span class="texture-label">{{ texture.label }}</span> -->
                      </div>
                    </div>
                    <div class="uploaded-textures-section">
                      <div class="uploaded-textures-divider">
                        <span>{{ $t("上传的纹理") }}</span>
                      </div>
                    </div>
                    <div class="texture-grid">
                      <!-- 上传的纹理缓存区域 -->

                      <!-- 自定义纹理上传按钮 -->
                      <div
                        class="texture-item upload-item"
                        @click="triggerTextureUpload"
                      >
                        <div class="upload-icon">
                          <span>+</span>
                        </div>
                        <span class="texture-label">{{ $t("上传纹理") }}</span>
                      </div>
                      <div
                        v-for="textureId in brushStore.state.uploadedTextures"
                        :key="textureId"
                        class="texture-item upload-item"
                        :class="{ active: prop.value === textureId }"
                        @click="handleTextureSelect(textureId)"
                      >
                        <img
                          :src="getUploadedTexturePreview(textureId)"
                          :alt="getUploadedTextureName(textureId)"
                          class="texture-thumbnail"
                        />
                        <!-- 删除按钮 -->
                        <div
                          class="texture-remove-btn"
                          @click.stop="removeUploadedTexture(textureId)"
                          :title="$t('删除纹理')"
                        >
                          <span>×</span>
                        </div>
                      </div>

                      <!-- 隐藏的文件输入 -->
                      <input
                        ref="textureFileInput"
                        type="file"
                        accept="image/*"
                        @change="handleTextureUpload"
                        style="display: none"
                      />
                    </div>
                  </div>
                </template>

                <!-- 其他类型的属性 -->
                <template v-else>
                  <div class="generic-property">
                    <span>{{ prop.name }}</span>
                    <input
                      type="text"
                      :value="prop.value"
                      @input="
                        (e) => handlePropertyChange(prop.id, e.target.value)
                      "
                      class="property-input"
                    />
                  </div>
                </template>

                <!-- 属性描述提示 -->
                <div v-if="prop.description" class="property-description">
                  {{ prop.description }}
                </div>
              </div>
            </div>
          </div>
        </template>

        <!-- 材质库弹窗 -->
        <!-- <div
          v-if="showLibrary"
          class="texture-library-overlay"
          @click.self="showLibrary = false"
        >
          <div class="texture-library-modal">
            <div class="modal-header">
              <h3>材质库</h3>
              <button class="close-btn" @click="showLibrary = false">
                &times;
              </button>
            </div>
            <div class="modal-content">
              <div class="texture-categories">
                <button
                  v-for="(category, index) in textureCategories"
                  :key="index"
                  :class="[
                    'category-btn',
                    { active: selectedCategory === category },
                  ]"
                  @click="selectedCategory = category"
                >
                  {{ category }}
                </button>
              </div>
              <div class="texture-list">
                <div
                  v-for="(texture, index) in filteredTextures"
                  :key="index"
                  class="library-texture-item"
                  @click="selectLibraryTexture(texture.path)"
                >
                  <img
                    :src="texture.thumbnail"
                    :alt="texture.name"
                    class="texture-thumbnail"
                  />
                  <span class="texture-name">{{ texture.name }}</span>
                </div>
              </div>
            </div>
            <div class="modal-footer">
              <button
                class="upload-btn"
                @click="handleFileSelect('texturePath')"
              >
                上传新材质
              </button>
            </div>
          </div>
        </div> -->
        <!-- 阴影设置 -->
        <div class="brush-section">
          <div class="section-header">
            <span>{{ $t("阴影设置") }}</span>
          </div>

          <div class="property-list">
            <!-- 阴影开关 -->
            <div class="property-item">
              <div class="checkbox-property">
                <span>{{ $t("启用阴影") }}</span>
                <div class="toggle-switch">
                  <input
                    type="checkbox"
                    :checked="brushStore.state.shadowEnabled"
                    @change="
                      (e) =>
                        handleShadowPropertyChange(
                          'shadowEnabled',
                          e.target.checked
                        )
                    "
                    id="shadow-enabled"
                  />
                  <label for="shadow-enabled"></label>
                </div>
              </div>
            </div>

            <!-- 阴影控制组 - 仅在启用阴影时显示 -->
            <template v-if="brushStore.state.shadowEnabled">
              <!-- 阴影颜色 -->
              <div class="property-item">
                <div class="color-property">
                  <div class="color-header">
                    <span>{{ $t("阴影颜色") }}</span>
                    <div
                      class="color-preview"
                      :style="{ backgroundColor: brushStore.state.shadowColor }"
                    ></div>
                  </div>
                  <div class="color-row">
                    <input
                      type="color"
                      :value="brushStore.state.shadowColor"
                      @input="
                        (e) =>
                          handleShadowPropertyChange(
                            'shadowColor',
                            e.target.value
                          )
                      "
                      class="color-picker"
                    />
                  </div>
                </div>
              </div>

              <!-- 阴影宽度 -->
              <div class="property-item">
                <div class="slider-property">
                  <div class="slider-header">
                    <span>{{ $t("阴影宽度") }}</span>
                    <span class="slider-value"
                      >{{ brushStore.state.shadowWidth }}px</span
                    >
                  </div>
                  <div class="slider-container">
                    <input
                      type="range"
                      :value="brushStore.state.shadowWidth"
                      @input="
                        (e) =>
                          handleShadowPropertyChange(
                            'shadowWidth',
                            parseFloat(e.target.value)
                          )
                      "
                      :min="0"
                      :max="50"
                      :step="1"
                      class="property-slider"
                    />
                  </div>
                  <div class="property-presets">
                    <button
                      v-for="preset in [0, 5, 10, 15, 20]"
                      :key="preset"
                      @click="handleShadowPropertyChange('shadowWidth', preset)"
                      :class="{
                        active:
                          Math.abs(brushStore.state.shadowWidth - preset) < 0.1,
                      }"
                    >
                      {{ preset }}
                    </button>
                  </div>
                </div>
              </div>

              <!-- 阴影X偏移 -->
              <div class="property-item">
                <div class="slider-property">
                  <div class="slider-header">
                    <span>{{ $t("阴影X偏移") }}</span>
                    <span class="slider-value"
                      >{{ brushStore.state.shadowOffsetX }}px</span
                    >
                  </div>
                  <div class="slider-container">
                    <input
                      type="range"
                      :value="brushStore.state.shadowOffsetX"
                      @input="
                        (e) =>
                          handleShadowPropertyChange(
                            'shadowOffsetX',
                            parseFloat(e.target.value)
                          )
                      "
                      :min="-50"
                      :max="50"
                      :step="1"
                      class="property-slider"
                    />
                  </div>
                  <div class="property-presets">
                    <button
                      v-for="preset in [-10, -5, 0, 5, 10]"
                      :key="preset"
                      @click="
                        handleShadowPropertyChange('shadowOffsetX', preset)
                      "
                      :class="{
                        active:
                          Math.abs(brushStore.state.shadowOffsetX - preset) <
                          0.1,
                      }"
                    >
                      {{ preset }}
                    </button>
                  </div>
                </div>
              </div>

              <!-- 阴影Y偏移 -->
              <div class="property-item">
                <div class="slider-property">
                  <div class="slider-header">
                    <span>{{ $t("阴影Y偏移") }}</span>
                    <span class="slider-value"
                      >{{ brushStore.state.shadowOffsetY }}px</span
                    >
                  </div>
                  <div class="slider-container">
                    <input
                      type="range"
                      :value="brushStore.state.shadowOffsetY"
                      @input="
                        (e) =>
                          handleShadowPropertyChange(
                            'shadowOffsetY',
                            parseFloat(e.target.value)
                          )
                      "
                      :min="-50"
                      :max="50"
                      :step="1"
                      class="property-slider"
                    />
                  </div>
                  <div class="property-presets">
                    <button
                      v-for="preset in [-10, -5, 0, 5, 10]"
                      :key="preset"
                      @click="
                        handleShadowPropertyChange('shadowOffsetY', preset)
                      "
                      :class="{
                        active:
                          Math.abs(brushStore.state.shadowOffsetY - preset) <
                          0.1,
                      }"
                    >
                      {{ preset }}
                    </button>
                  </div>
                </div>
              </div>

              <!-- 阴影预览 -->
              <div class="property-item">
                <div class="shadow-preview-container">
                  <div class="shadow-preview-title">{{ $t("阴影预览") }}</div>
                  <div class="shadow-preview-box">
                    <div
                      class="shadow-preview-element"
                      :style="{
                        backgroundColor: brushStore.state.color,
                        width: `${Math.max(
                          20,
                          Math.min(60, brushStore.state.size)
                        )}px`,
                        height: `${Math.max(
                          20,
                          Math.min(60, brushStore.state.size)
                        )}px`,
                        boxShadow: brushStore.state.shadowEnabled
                          ? `${brushStore.state.shadowOffsetX}px ${brushStore.state.shadowOffsetY}px ${brushStore.state.shadowWidth}px ${brushStore.state.shadowColor}`
                          : 'none',
                      }"
                    ></div>
                  </div>
                </div>
              </div>
            </template>
          </div>
        </div>
        <!-- 笔刷预设 -->
        <div class="brush-section">
          <div class="section-header">
            <span>笔刷预设</span>
            <button
              class="save-preset-btn"
              @click="saveCurrentAsPreset"
              title="保存当前设置为预设"
            >
              <i class="save-icon">+</i>
            </button>
          </div>

          <div class="presets-container">
            <div
              v-for="(preset, index) in brushStore.state.presets"
              :key="index"
              class="preset-item"
              @click="applyPresetWithCommand(index)"
            >
              <div
                class="preset-color"
                :style="{
                  backgroundColor: preset.color,
                  width: preset.size + 'px',
                  height: preset.size + 'px',
                  opacity: preset.opacity,
                }"
              ></div>
              <span class="preset-name">{{ preset.name }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, inject, onUnmounted, computed } from "vue";
import { BrushStore } from "../store/BrushStore";
import {
  BrushSizeCommand,
  BrushColorCommand,
  BrushOpacityCommand,
  BrushTypeCommand,
  TextureCommand,
  BrushPresetCommand,
  BrushPropertyCommand,
  TextureUploadCommand,
} from "../commands/BrushCommands";
import { debounce } from "lodash-es";

// 从工具管理器获取可用笔刷类型
const toolManager = inject("toolManager");

// 命令管理器
const commandManager = inject("commandManager");

// 注入纹理预设管理器
const texturePresetManager = inject("texturePresetManager");

// 计算属性：按分类获取当前笔刷可配置属性
const propertiesByCategory = computed(() => {
  return BrushStore.getPropertiesByCategory();
});

// 材质库状态
const showLibrary = ref(false);
const selectedCategory = ref("全部");
const textureFileInput = ref(null);
const textureCategories = ["全部", "纹理", "笔触", "图案", "特效"];

// 材质库中的材质（实际项目中可以从API获取）
const textureLibrary = [
  {
    name: "水彩1",
    path: "/textures/watercolor1.png",
    thumbnail: "/textures/watercolor1_thumb.png",
    category: "笔触",
  },
  {
    name: "水彩2",
    path: "/textures/watercolor2.png",
    thumbnail: "/textures/watercolor2_thumb.png",
    category: "笔触",
  },
  {
    name: "粉笔",
    path: "/textures/chalk.png",
    thumbnail: "/textures/chalk_thumb.png",
    category: "笔触",
  },
  {
    name: "木纹",
    path: "/textures/wood.png",
    thumbnail: "/textures/wood_thumb.png",
    category: "纹理",
  },
  {
    name: "皮革",
    path: "/textures/leather.png",
    thumbnail: "/textures/leather_thumb.png",
    category: "纹理",
  },
  {
    name: "点阵",
    path: "/textures/dots.png",
    thumbnail: "/textures/dots_thumb.png",
    category: "图案",
  },
  {
    name: "线条",
    path: "/textures/lines.png",
    thumbnail: "/textures/lines_thumb.png",
    category: "图案",
  },
  {
    name: "星星",
    path: "/textures/stars.png",
    thumbnail: "/textures/stars_thumb.png",
    category: "特效",
  },
  // 可以添加更多材质...
];

// 根据选择的类别过滤材质
const filteredTextures = computed(() => {
  if (selectedCategory.value === "全部") {
    return textureLibrary;
  }
  return textureLibrary.filter(
    (texture) => texture.category === selectedCategory.value
  );
});

// 从材质库选择材质
function selectLibraryTexture(path) {
  handlePropertyChange("texturePath", path);
  showLibrary.value = false;
}

// 处理材质选择
function handleTextureSelect(textureId) {
  handlePropertyChange("textureSelector", textureId);
}

// 触发纹理上传文件选择
function triggerTextureUpload() {
  if (textureFileInput.value.length) {
    textureFileInput.value[0].click();
    return;
  }
  textureFileInput.value.click();
}

// 处理纹理文件上传
async function handleTextureUpload(event) {
  const file = event.target.files?.[0];
  if (!file) return;

  try {
    // 验证文件类型
    if (!file.type.startsWith("image/")) {
      alert("请选择图片文件");
      return;
    }

    // 验证文件大小 (限制为 5MB)
    const maxSize = 5 * 1024 * 1024;
    if (file.size > maxSize) {
      alert("文件大小不能超过 5MB");
      return;
    }

    // 获取笔刷管理器
    const brushManager = toolManager?.brushManager;

    if (!texturePresetManager || !brushManager) {
      console.error("缺少必要的管理器实例");
      alert("系统错误：无法上传纹理");
      return;
    }

    // 创建并执行纹理上传命令
    const command = new TextureUploadCommand({
      file: file,
      name: file.name.replace(/\.[^/.]+$/, ""), // 移除文件扩展名
      category: "自定义材质",
      texturePresetManager: texturePresetManager,
      brushManager: brushManager,
    });

    const result = await commandManager.execute(command);

    // 上传成功后，将纹理ID添加到缓存列表
    if (result && result.textureId) {
      brushStore.cacheUploadedTexture(result.textureId);
      // 自动选择新上传的纹理
      handleTextureSelect(result.textureId);
    }

    // 清空文件输入，允许重复上传同一文件
    event.target.value = "";
  } catch (error) {
    console.error("纹理上传失败:", error);
    alert(`上传失败: ${error.message}`);
  }
}

// 获取上传纹理的预览图
function getUploadedTexturePreview(textureId) {
  const texture = texturePresetManager?.getTextureById?.(textureId);
  return texture?.preview || texture?.path || "/placeholder-texture.png";
}

// 获取上传纹理的名称
function getUploadedTextureName(textureId) {
  const texture = texturePresetManager?.getTextureById?.(textureId);
  return texture?.name || "未知纹理";
}

// 删除上传的纹理
function removeUploadedTexture(textureId) {
  try {
    // 从缓存中移除
    brushStore.removeCachedTexture(textureId);

    // 从纹理预设管理器中删除
    if (texturePresetManager?.removeCustomTexture) {
      texturePresetManager.removeCustomTexture(textureId);
    }

    // 如果当前选中的是被删除的纹理，清空选择
    const currentProperty = propertiesByCategory.value?.["纹理"]?.find(
      (p) => p.id === "textureSelector"
    );
    if (currentProperty?.value === textureId) {
      handlePropertyChange("textureSelector", null);
    }
  } catch (error) {
    console.error("删除纹理失败:", error);
    alert(`删除失败: ${error.message}`);
  }
}

// 格式化属性值显示
function formatPropertyValue(prop) {
  if (prop.type === "slider") {
    // 如果是透明度，显示为百分比
    if (prop.id === "opacity" || prop.id === "textureOpacity") {
      return `${Math.round(prop.value * 100)}%`;
    }

    // 如果有单位，添加单位
    if (prop.unit) {
      return `${prop.value}${prop.unit}`;
    }

    // 根据step确定小数位数
    const decimalPlaces = prop.step.toString().includes(".")
      ? prop.step.toString().split(".")[1].length
      : 0;
    return prop.value.toFixed(decimalPlaces);
  }

  return prop.value;
}

// 防抖处理函数，优化性能
const debouncedPropertyCommand = debounce((propId, value) => {
  // 创建并执行属性更新命令
  const command = new BrushPropertyCommand({
    propertyId: propId,
    value: value,
  });
  commandManager.execute(command, { nonUndoable: true });
}, 200);

// 处理阴影属性变化的防抖函数
const debouncedShadowCommand = debounce((propId, value) => {
  // 通知工具管理器更新阴影
  if (toolManager?.brushManager) {
    toolManager.brushManager.updateShadow();
  }
}, 100);

// 处理属性变化
function handlePropertyChange(propId, value) {
  // 直接更新UI，通过防抖函数延迟创建命令
  BrushStore.updatePropertyValue(propId, value);
  debouncedPropertyCommand(propId, value);
}

// 处理阴影属性变化
function handleShadowPropertyChange(propId, value) {
  // 更新BrushStore中的阴影属性
  if (propId === "shadowEnabled") {
    BrushStore.setShadowEnabled(value);
  } else if (propId === "shadowColor") {
    BrushStore.setShadowColor(value);
  } else if (propId === "shadowWidth") {
    BrushStore.setShadowWidth(value);
  } else if (propId === "shadowOffsetX") {
    BrushStore.setShadowOffsetX(value);
  } else if (propId === "shadowOffsetY") {
    BrushStore.setShadowOffsetY(value);
  }

  // 通知笔刷管理器更新阴影设置
  debouncedShadowCommand(propId, value);
}

// 使用命令设置笔刷类型
function setBrushTypeWithCommand(type) {
  const command = new BrushTypeCommand({
    brushType: type,
    brushManager: toolManager?.brushManager,
  });
  commandManager.execute(command, { nonUndoable: true }); // 不需要撤销
}

// 获取笔刷预览样式
function getBrushPreviewStyle(brush) {
  const baseStyle = {
    backgroundColor: brush.id === "eraser" ? "#ffffff" : brushStore.state.color,
  };

  // 根据不同笔刷类型设置不同样式
  switch (brush.id) {
    case "pencil":
      return {
        ...baseStyle,
        // height: "2px",
        borderRadius: "1px",
      };
    case "marker":
      return {
        ...baseStyle,
        // height: "4px",
        opacity: 0.7,
        borderRadius: "2px",
      };
    case "spray":
      return {
        ...baseStyle,
        backgroundImage:
          "radial-gradient(circle, currentColor 1px, transparent 1px)",
        backgroundSize: "4px 4px",
        backgroundPosition: "center",
        opacity: 0.8,
      };
    case "eraser":
      return {
        ...baseStyle,
        border: "1px dashed #999",
        backgroundColor: "transparent",
      };
    case "neon":
      return {
        ...baseStyle,
        // height: "3px",
        borderRadius: "1px",
        boxShadow: `0 0 5px 2px ${baseStyle.backgroundColor}`,
      };
    case "rainbow":
      return {
        ...baseStyle,
        background:
          "linear-gradient(90deg, red, orange, yellow, green, blue, indigo, violet)",
        height: "3px",
      };
    case "texture":
      return {
        ...baseStyle,
        backgroundImage:
          "url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4IiBoZWlnaHQ9IjgiPjxyZWN0IHdpZHRoPSI4IiBoZWlnaHQ9IjgiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMCAwTDggOFpNOCAwTDAgOFoiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlPSIjMDAwIj48L3BhdGg+PC9zdmc+')",
        backgroundSize: "8px 8px",
        // height: "12px",
      };
    default:
      return baseStyle;
  }
}

// 应用预设
function applyPresetWithCommand(presetIndex) {
  const command = new BrushPresetCommand({ preset: presetIndex });
  commandManager.execute(command, { nonUndoable: true });
}

// 保存当前设置为预设
function saveCurrentAsPreset() {
  // 简单实现，可以后续优化为弹窗输入名称
  const name = prompt(
    "请输入预设名称:",
    `预设 ${BrushStore.state.presets.length + 1}`
  );
  if (name) {
    const presetIndex = BrushStore.saveCurrentAsPreset(name);
    // 应用新创建的预设（可选）
    // applyPresetWithCommand(presetIndex);
  }
}

// 初始化可用笔刷类型
onMounted(() => {
  if (toolManager?.brushManager) {
    const availableBrushes = toolManager.brushManager
      .getBrushTypes()
      ?.filter((brush) => brush.id !== "eraser");
    BrushStore.setAvailableBrushes(availableBrushes);
  }
});

// 导出笔刷存储供模板使用
const brushStore = BrushStore;
</script>

<style scoped lang="less">
.brush-panel {
  position: absolute;
  right: 20px;
  top: 62px;
  padding: 0;
  width: 30%;
  /* overflow-y: auto; */
  min-width: 280px;
  border-left: 1px solid rgba(0, 0, 0, 0.05); /* 更柔和的边框 */
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  animation: panelFadeIn 0.3s ease;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
  backdrop-filter: blur(2px); /* 添加模糊效果 */
  -webkit-backdrop-filter: blur(2px);
  background-color: rgba(255, 255, 255, 0.95); /* 改为白色背景 */
  z-index: 1000; /* 确保面板在最上层 */

  .brush-panel-wrapper {
    overflow-y: auto;
    height: 100%;
    max-height: 85vh; /* 限制最大高度 */
    /*优化ios上的滚动效果*/
    -webkit-overflow-scrolling: touch;
    .brush-panel-content {
      display: flex;
      flex-direction: column;
      margin: 0;
    }
  }
}

/* 添加指向整个面板的倒三角 */
.brush-panel::before {
  content: "";
  position: absolute;
  top: -9px;
  right: 58px;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-bottom: 10px solid rgba(255, 255, 255, 0.95); /* 与面板背景色一致 */
  filter: drop-shadow(0 -1px 1px rgba(0, 0, 0, 0.05));
  z-index: 1;
}

@keyframes panelFadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.brush-section {
  padding: 0;
  background-color: transparent;
  border: none;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05); /* 更柔和的边框 */
  box-shadow: none;
  transition: all 0.25s ease;
  margin-bottom: 1px;
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.8); /* 略微透明的白色背景 */
  padding: 10px 16px;
  font-weight: 600;
  font-size: 15px;
  color: #333; /* 更深的文字颜色 */
  cursor: pointer;
  user-select: none;
  position: relative;
  transition: background-color 0.2s ease;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05); /* 更柔和的边框 */
}

/* .section-header::after {
  content: "";
  position: absolute;
  right: 16px;
  top: 50%;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid #999;
  transform: translateY(-50%);
  transition: transform 0.25s ease;
} */

/* .section-header:hover {
  background-color: rgba(248, 249, 250, 1);
}

.section-header:hover::after {
  border-top-color: #666;
} */

.section-actions {
  display: flex;
  gap: 8px;
  margin-right: 28px; /* 为三角形留出空间 */
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  background-color: rgba(66, 133, 244, 0.1); /* 淡蓝色背景 */
  border: 1px solid rgba(66, 133, 244, 0.2);
  border-radius: 4px;
  color: #4285f4; /* 蓝色文字 */
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s;
}

.action-btn:hover {
  background-color: rgba(66, 133, 244, 0.15);
  transform: translateY(-1px);
}

.property-list {
  display: flex;
  flex-direction: column;
  padding: 14px 16px;
  gap: 16px;
  background-color: #fff; /* 纯白色背景 */
}

.property-item {
  margin-bottom: 5px;
}

/* 滑块控件样式 */
.slider-property {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.slider-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.slider-header span:first-child {
  font-weight: 500;
  color: #333; /* 更深的文字颜色 */
  font-size: 14px;
}

.slider-value {
  font-size: 14px;
  color: #666; /* 更深的文字颜色 */
  min-width: 45px;
  text-align: right;
  background-color: rgba(0, 0, 0, 0.05);
  padding: 3px 7px;
  border-radius: 4px;
  font-family: "Consolas", monospace;
}

.slider-container {
  width: 100%;
  padding: 0;
}

.property-slider {
  width: 100%;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.1); /* 更柔和的颜色 */
  outline: none;
}

.property-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #4285f4; /* 蓝色滑块 */
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.property-slider::-webkit-slider-thumb:hover {
  background: #3b77db;
  transform: scale(1.1);
}

.property-presets {
  display: flex;
  justify-content: flex-start;
  margin-top: 10px;
  flex-wrap: wrap;
  gap: 7px;
}

.property-presets button {
  min-width: 32px;
  height: 22px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  background: #fff;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  padding: 0 7px;
  transition: all 0.2s;
}

.property-presets button.active {
  background-color: rgba(66, 133, 244, 0.1);
  border-color: rgba(66, 133, 244, 0.2);
  color: #4285f4;
  font-weight: 500;
}

.property-presets button:hover:not(.active) {
  background-color: rgba(0, 0, 0, 0.03);
  transform: translateY(-1px);
}

/* 笔刷类型网格 */
.brush-type-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(75px, 1fr));
  padding: 14px 16px;
  gap: 10px;
  background-color: #fff; /* 纯白色背景 */
}

.brush-type-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px;
  border-radius: 4px;
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0.05);
  transition: all 0.2s;
  background-color: #fff;
  justify-content: center;
}

.brush-type-item:hover {
  background-color: rgba(0, 0, 0, 0.02);
  border-color: rgba(66, 133, 244, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03);
}

.brush-type-item.active {
  background-color: rgba(66, 133, 244, 0.1);
  border-color: rgba(66, 133, 244, 0.2);
}

/* 统一笔刷预览大小 */
.brush-preview {
  width: 45px;
  height: 45px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8px;
  border-radius: 4px;
  background-color: rgba(0, 0, 0, 0.02);
}

/* 保持笔刷预览内容样式一致 */
.brush-preview::before {
  content: "";
  width: 75%;
  height: 3px;
  background-color: currentColor;
}

.brush-name {
  font-size: 14px;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  color: #333; /* 更深的文字颜色 */
}

/* 颜色选择器样式 */
.color-property .color-header,
.file-property .file-header,
.texture-grid-property .texture-grid-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.color-property .color-header span,
.file-property .file-header span,
.texture-grid-property .texture-grid-header span {
  font-weight: 500;
  color: #333; /* 更深的文字颜色 */
  font-size: 14px;
}

.color-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.color-preview {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4);
}

.color-picker {
  width: 40px;
  height: 40px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  padding: 0;
  background: none;
  cursor: pointer;
  border-radius: 4px;
  overflow: hidden;
}

.recent-colors {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.color-item {
  width: 22px;
  height: 22px;
  border-radius: 4px;
  cursor: pointer;
  border: 1px solid rgba(0, 0, 0, 0.05);
  transition: all 0.2s;
}

.color-item:hover {
  transform: scale(1.08);
  border-color: rgba(66, 133, 244, 0.2);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

/* 复选框样式 */
.checkbox-property,
.select-property,
.generic-property {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 32px;
}

.checkbox-property span,
.select-property span,
.generic-property span {
  font-weight: 500;
  color: #333; /* 更深的文字颜色 */
  font-size: 14px;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 22px;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-switch label {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.1); /* 更柔和的颜色 */
  border-radius: 22px;
  transition: 0.25s;
}

.toggle-switch label:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  border-radius: 50%;
  transition: 0.25s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.toggle-switch input:checked + label {
  background-color: #4285f4; /* 蓝色 */
}

.toggle-switch input:checked + label:before {
  transform: translateX(22px);
}

/* 选择框样式 */
.property-select {
  width: 150px;
  padding: 6px 10px;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  background-color: #fff;
  color: #333; /* 更深的文字颜色 */
  font-size: 14px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5' viewBox='0 0 8 5'%3E%3Cpath fill='%23666' d='M0 0h8L4 5z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  -webkit-appearance: none;
  appearance: none;
  padding-right: 30px;
  height: 34px;
}

@media screen and (max-width: 1024px) {
  .property-select {
    width: 120px;
  }
}

.property-select:focus {
  border-color: #4285f4;
  outline: none;
  box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.1);
}

/* 文件选择器样式 */
.file-property {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.file-preview {
  width: 100%;
  height: 110px;
  border: 1px dashed rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background-color: rgba(0, 0, 0, 0.02);
  cursor: pointer;
  transition: all 0.2s;
}

.file-preview:hover {
  border-color: rgba(66, 133, 244, 0.2);
  background-color: rgba(66, 133, 244, 0.05);
  transform: translateY(-1px);
}

.file-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.no-file {
  font-size: 14px;
  color: #666; /* 更深的文字颜色 */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.no-file:before {
  content: "📁";
  font-size: 22px;
}

.file-actions {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

.select-file-btn,
.clear-file-btn {
  padding: 7px 14px;
  font-size: 14px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  flex: 1;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.select-file-btn {
  background-color: rgba(66, 133, 244, 0.1);
  border: 1px solid rgba(66, 133, 244, 0.2);
  color: #4285f4;
}

.select-file-btn:hover {
  background-color: rgba(66, 133, 244, 0.15);
  transform: translateY(-1px);
}

.clear-file-btn {
  background-color: rgba(244, 67, 54, 0.1);
  border: 1px solid rgba(244, 67, 54, 0.2);
  color: #f44336;
}

.clear-file-btn:hover {
  background-color: rgba(244, 67, 54, 0.15);
  transform: translateY(-1px);
}

.property-description {
  font-size: 13px;
  color: #666; /* 更深的文字颜色 */
  margin-top: 5px;
  line-height: 1.4;
  font-style: italic;
}

/* 文本输入框样式 */
.property-input {
  width: 150px;
  padding: 6px 10px;
  border-radius: 4px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  font-size: 14px;
  color: #333; /* 更深的文字颜色 */
  height: 34px;
}

/* 预设容器样式 */
.presets-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(75px, 1fr));
  padding: 14px 16px;
  gap: 10px;
  background-color: #fff; /* 纯白色背景 */
}

.preset-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 6px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  cursor: pointer;
  background-color: white;
  transition: all 0.2s;
  height: 90px;
  justify-content: center;
}

.preset-item:hover {
  border-color: rgba(66, 133, 244, 0.2);
  background-color: rgba(0, 0, 0, 0.02);
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03);
}

.preset-color {
  border-radius: 50%;
  margin-bottom: 10px;
  min-width: 18px;
  min-height: 18px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

.preset-name {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
  color: #333; /* 更深的文字颜色 */
}

.save-preset-btn {
  width: 24px;
  height: 24px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(66, 133, 244, 0.2);
  border-radius: 4px;
  background-color: rgba(66, 133, 244, 0.1);
  color: #4285f4;
  cursor: pointer;
  padding: 0;
  line-height: 0;
  transition: all 0.2s;
}

.save-preset-btn:hover {
  background-color: rgba(66, 133, 244, 0.15);
  transform: translateY(-1px);
}

.save-icon {
  font-style: normal;
}

/* 材质网格样式 */
.texture-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(75px, 1fr));
  gap: 10px;
  margin-top: 10px;
}

.texture-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  background-color: #fff;
  height: 90px;
  justify-content: center;
}

.texture-item:hover {
  border-color: rgba(66, 133, 244, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.03);
}

.texture-item.active {
  background-color: rgba(66, 133, 244, 0.1);
  border-color: rgba(66, 133, 244, 0.2);
}

.texture-thumbnail {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
  margin-bottom: 8px;
}

.texture-label {
  font-size: 14px;
  color: #333; /* 更深的文字颜色 */
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 100%;
}

/* 上传纹理按钮样式 */
.texture-item.upload-item {
  border: 2px dashed rgba(66, 133, 244, 0.3);
  background-color: rgba(66, 133, 244, 0.05);
}

.texture-item.upload-item:hover {
  border-color: rgba(66, 133, 244, 0.5);
  background-color: rgba(66, 133, 244, 0.1);
}

.upload-icon {
  width: 100%;
  height: 45px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 8px;
  border-radius: 4px;
  background-color: rgba(66, 133, 244, 0.1);
}

.upload-icon span {
  font-size: 24px;
  color: #4285f4;
  font-weight: bold;
}

/* 材质库样式 */
.texture-library-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.5); /* 白色半透明背景 */
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.texture-library-modal {
  background-color: #fff; /* 白色背景 */
  border-radius: 12px;
  width: 80%;
  max-width: 700px;
  max-height: 80vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.05);
  animation: modalSlideUp 0.3s ease;
}

@keyframes modalSlideUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.modal-header {
  padding: 14px 18px;
  background-color: rgba(255, 255, 255, 0.8); /* 略微透明的白色背景 */
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-header h3 {
  margin: 0;
  font-size: 17px;
  color: #333; /* 更深的文字颜色 */
  font-weight: 600;
}

.close-btn {
  background: none;
  border: none;
  font-size: 22px;
  cursor: pointer;
  color: #666; /* 更深的文字颜色 */
  padding: 0;
  line-height: 1;
  opacity: 0.7;
  transition: all 0.2s;
}

.close-btn:hover {
  opacity: 1;
  color: #333; /* 更深的文字颜色 */
  transform: scale(1.1);
}

.modal-content {
  padding: 18px;
  overflow-y: auto;
  max-height: calc(80vh - 110px);
  display: flex;
  flex-direction: column;
  gap: 18px;
  background-color: #fff; /* 纯白色背景 */
}

.texture-categories {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 10px;
  flex-wrap: wrap;
  scrollbar-width: thin;
}

.texture-categories::-webkit-scrollbar {
  height: 4px;
}

.texture-categories::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.1); /* 更柔和的颜色 */
  border-radius: 4px;
}

.category-btn {
  padding: 6px 12px;
  border-radius: 4px;
  background-color: rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.05);
  color: #333; /* 更深的文字颜色 */
  cursor: pointer;
  font-size: 14px;
  white-space: nowrap;
  transition: all 0.2s;
  height: 34px;
  display: flex;
  align-items: center;
}

.category-btn.active {
  background-color: rgba(66, 133, 244, 0.1);
  border-color: rgba(66, 133, 244, 0.2);
  color: #4285f4;
}

.category-btn:hover:not(.active) {
  background-color: rgba(0, 0, 0, 0.05);
  transform: translateY(-1px);
}

.texture-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 12px;
}

.library-texture-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.2s;
  background-color: #fff;
  height: 110px;
  justify-content: center;
}

.library-texture-item:hover {
  border-color: rgba(66, 133, 244, 0.2);
  background-color: rgba(0, 0, 0, 0.02);
  transform: translateY(-2px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}

.library-texture-item img {
  width: 100%;
  height: 65px;
  object-fit: cover;
  border-radius: 4px;
  margin-bottom: 8px;
}

.texture-name {
  font-size: 14px;
  color: #333; /* 更深的文字颜色 */
  text-align: center;
}

.modal-footer {
  padding: 14px 18px;
  background-color: rgba(255, 255, 255, 0.8); /* 略微透明的白色背景 */
  border-top: 1px solid rgba(0, 0, 0, 0.05);
  display: flex;
  justify-content: flex-end;
}

.upload-btn {
  padding: 7px 16px;
  background-color: #4285f4; /* 蓝色 */
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 15px;
  transition: all 0.2s;
  height: 36px;
  display: flex;
  align-items: center;
}

.upload-btn:hover {
  background-color: #3b77db;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* 上传纹理缓存区域样式 */
.uploaded-textures-section {
  width: 100%;
  margin-top: 15px;
}

.uploaded-textures-divider {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  padding: 0 4px;
}

.uploaded-textures-divider::before,
.uploaded-textures-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    rgba(0, 0, 0, 0.08),
    transparent
  );
}

.uploaded-textures-divider span {
  padding: 0 12px;
  font-size: 13px;
  color: #666;
  background-color: #fff;
  white-space: nowrap;
  font-weight: 500;
}

.uploaded-textures-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(75px, 1fr));
  gap: 10px;
  margin-bottom: 15px;
}

.uploaded-texture-item {
  position: relative;
  border: 1px solid rgba(108, 117, 125, 0.2);
  background-color: rgba(248, 249, 250, 0.8);
}

.uploaded-texture-item:hover {
  border-color: rgba(66, 133, 244, 0.3);
  background-color: rgba(66, 133, 244, 0.05);
}

.uploaded-texture-item.active {
  background-color: rgba(66, 133, 244, 0.15);
  border-color: rgba(66, 133, 244, 0.4);
}

.texture-remove-btn {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 18px;
  height: 18px;
  background-color: rgba(244, 67, 54, 0.9);
  border: 1px solid #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: all 0.2s ease;
  z-index: 10;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.texture-remove-btn span {
  color: #fff;
  font-size: 12px;
  font-weight: bold;
  line-height: 1;
}

.uploaded-texture-item:hover .texture-remove-btn {
  opacity: 1;
  transform: scale(1.1);
}

.texture-remove-btn:hover {
  background-color: rgba(244, 67, 54, 1);
  transform: scale(1.2) !important;
}

/* 阴影设置样式 */
.shadow-preview-container {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}

.shadow-preview-title {
  font-weight: 500;
  color: #333;
  font-size: 14px;
  text-align: center;
}

.shadow-preview-box {
  background: repeating-conic-gradient(#f5f5f5 0% 25%, #ffffff 0% 50%) 50% /
    10px 10px;
  border-radius: 8px;
  padding: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  border: 1px solid rgba(0, 0, 0, 0.05);
  position: relative;
  overflow: hidden;
}

.shadow-preview-element {
  border-radius: 50%;
  transition: all 0.3s ease;
  position: relative;
  z-index: 1;
  background-clip: padding-box;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .brush-panel {
    width: 95%;
    right: 2.5%;
    max-height: 75vh;
  }

  .shadow-preview-box {
    min-height: 100px;
    padding: 20px;
  }

  .property-presets {
    justify-content: center;
  }

  .brush-type-grid,
  .presets-container,
  .texture-grid {
    grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
  }
}
</style>
