/**
 * 材质预设管理器
 * 负责管理所有材质预设，包括内置预设和用户自定义预设
 */
export class TexturePresetManager {
  constructor() {
    // 内置材质预设
    this.builtInTextures = [];

    // 用户自定义材质
    this.customTextures = [];

    // 材质分类
    this.categories = new Map();

    // 材质缓存
    this.textureCache = new Map();

    // 事件监听器
    this.listeners = {
      textureAdded: [],
      textureRemoved: [],
      textureUpdated: [],
    };

    // 初始化内置材质
    this._initBuiltInTextures();
  }

  /**
   * 初始化内置材质预设
   * @private
   */
  _initBuiltInTextures() {
    // 基于项目中的texture文件夹内容创建预设
    const textureList = [
      // 基础纹理
      {
        id: "texture0",
        name: "纸质纹理",
        category: "基础纹理",
        path: "/src/assets/texture/texture0.webp",
      },
      {
        id: "texture1",
        name: "粗糙表面",
        category: "基础纹理",
        path: "/src/assets/texture/texture1.webp",
      },
      {
        id: "texture2",
        name: "细腻纹理",
        category: "基础纹理",
        path: "/src/assets/texture/texture2.webp",
      },
      {
        id: "texture3",
        name: "颗粒质感",
        category: "基础纹理",
        path: "/src/assets/texture/texture3.webp",
      },
      {
        id: "texture4",
        name: "布料纹理",
        category: "基础纹理",
        path: "/src/assets/texture/texture4.webp",
      },
      {
        id: "texture5",
        name: "木质纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture5.webp",
      },
      {
        id: "texture6",
        name: "石材纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture6.webp",
      },
      {
        id: "texture7",
        name: "金属质感",
        category: "金属纹理",
        path: "/src/assets/texture/texture7.webp",
      },
      {
        id: "texture8",
        name: "皮革纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture8.webp",
      },
      {
        id: "texture9",
        name: "水彩纸质",
        category: "艺术纹理",
        path: "/src/assets/texture/texture9.webp",
      },
      {
        id: "texture10",
        name: "画布纹理",
        category: "艺术纹理",
        path: "/src/assets/texture/texture10.webp",
      },
      {
        id: "texture11",
        name: "沙砾质感",
        category: "自然纹理",
        path: "/src/assets/texture/texture11.webp",
      },
      {
        id: "texture12",
        name: "水波纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture12.webp",
      },
      {
        id: "texture13",
        name: "云朵纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture13.webp",
      },
      {
        id: "texture14",
        name: "火焰纹理",
        category: "特效纹理",
        path: "/src/assets/texture/texture14.webp",
      },
      {
        id: "texture15",
        name: "烟雾效果",
        category: "特效纹理",
        path: "/src/assets/texture/texture15.webp",
      },
      {
        id: "texture16",
        name: "星空纹理",
        category: "特效纹理",
        path: "/src/assets/texture/texture16.webp",
      },
      {
        id: "texture17",
        name: "大理石纹",
        category: "石材纹理",
        path: "/src/assets/texture/texture17.webp",
      },
      {
        id: "texture18",
        name: "花岗岩纹",
        category: "石材纹理",
        path: "/src/assets/texture/texture18.webp",
      },
      {
        id: "texture19",
        name: "竹纹理",
        category: "自然纹理",
        path: "/src/assets/texture/texture19.webp",
      },
      {
        id: "texture20",
        name: "抽象图案",
        category: "艺术纹理",
        path: "/src/assets/texture/texture20.webp",
      },
    ];

    // 添加内置材质
    textureList.forEach((texture) => {
      this.builtInTextures.push({
        id: texture.id,
        name: texture.name,
        category: texture.category,
        path: texture.path,
        type: "builtin",
        preview: texture.path, // 使用原图作为预览
        description: `内置${texture.category} - ${texture.name}`,
        tags: [texture.category.replace("纹理", ""), "内置"],
        created: new Date().toISOString(),
        // 默认属性
        defaultSettings: {
          scale: 1,
          opacity: 1,
          repeat: "repeat",
          angle: 0,
        },
      });

      // 添加到分类
      if (!this.categories.has(texture.category)) {
        this.categories.set(texture.category, []);
      }
      this.categories.get(texture.category).push(texture.id);
    });
  }

  /**
   * 获取所有材质（内置 + 自定义）
   * @returns {Array} 材质数组
   */
  getAllTextures() {
    return [...this.builtInTextures, ...this.customTextures];
  }

  /**
   * 根据ID获取材质
   * @param {String} textureId 材质ID
   * @returns {Object|null} 材质对象
   */
  getTextureById(textureId) {
    return this.getAllTextures().find((texture) => texture.id === textureId) || null;
  }

  /**
   * 根据分类获取材质
   * @param {String} category 分类名称
   * @returns {Array} 材质数组
   */
  getTexturesByCategory(category) {
    return this.getAllTextures().filter((texture) => texture.category === category);
  }

  /**
   * 获取所有分类
   * @returns {Array} 分类名称数组
   */
  getCategories() {
    const categories = new Set();
    this.getAllTextures().forEach((texture) => {
      categories.add(texture.category);
    });
    return Array.from(categories);
  }

  /**
   * 添加自定义材质
   * @param {Object} textureData 材质数据
   * @returns {String} 材质ID
   */
  addCustomTexture(textureData) {
    const textureId =
      textureData.id || `custom_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    const texture = {
      id: textureId,
      name: textureData.name || "自定义材质",
      category: textureData.category || "自定义材质",
      path: textureData.path || textureData.dataUrl,
      type: "custom",
      preview: textureData.preview || textureData.path || textureData.dataUrl,
      description: textureData.description || "用户自定义材质",
      tags: textureData.tags || ["自定义"],
      created: new Date().toISOString(),
      defaultSettings: {
        scale: textureData.scale || 1,
        opacity: textureData.opacity || 1,
        repeat: textureData.repeat || "repeat",
        angle: textureData.angle || 0,
        ...textureData.defaultSettings,
      },
      // 保存原始文件信息
      file: textureData.file || null,
      dataUrl: textureData.dataUrl || null,
    };

    this.customTextures.push(texture);

    // 添加到分类
    if (!this.categories.has(texture.category)) {
      this.categories.set(texture.category, []);
    }
    this.categories.get(texture.category).push(textureId);

    // 触发事件
    this._triggerEvent("textureAdded", texture);

    return textureId;
  }

  /**
   * 删除自定义材质
   * @param {String} textureId 材质ID
   * @returns {Boolean} 是否删除成功
   */
  removeCustomTexture(textureId) {
    const index = this.customTextures.findIndex((texture) => texture.id === textureId);
    if (index === -1) {
      return false;
    }

    const texture = this.customTextures[index];

    // 只能删除自定义材质
    if (texture.type !== "custom") {
      console.warn("不能删除内置材质");
      return false;
    }

    this.customTextures.splice(index, 1);

    // 从分类中移除
    if (this.categories.has(texture.category)) {
      const categoryTextures = this.categories.get(texture.category);
      const categoryIndex = categoryTextures.indexOf(textureId);
      if (categoryIndex !== -1) {
        categoryTextures.splice(categoryIndex, 1);
      }

      // 如果分类为空且不是内置分类，删除分类
      if (categoryTextures.length === 0 && texture.category === "自定义材质") {
        this.categories.delete(texture.category);
      }
    }

    // 清除缓存
    this.textureCache.delete(textureId);

    // 触发事件
    this._triggerEvent("textureRemoved", texture);

    return true;
  }

  /**
   * 更新材质信息
   * @param {String} textureId 材质ID
   * @param {Object} updates 更新数据
   * @returns {Boolean} 是否更新成功
   */
  updateTexture(textureId, updates) {
    const texture = this.getTextureById(textureId);
    if (!texture || texture.type === "builtin") {
      return false;
    }

    // 更新材质属性
    Object.assign(texture, updates);

    // 触发事件
    this._triggerEvent("textureUpdated", texture);

    return true;
  }

  /**
   * 获取材质预览URL
   * @param {Object} texture 材质对象
   * @returns {String} 预览URL
   */
  getTexturePreviewUrl(texture) {
    if (!texture) return null;

    // 如果有预览图，使用预览图
    if (texture.preview) {
      return texture.preview;
    }

    // 否则使用原图
    return texture.path || texture.dataUrl;
  }

  /**
   * 加载材质图像
   * @param {String} textureId 材质ID
   * @returns {Promise<HTMLImageElement>} 图像对象
   */
  loadTextureImage(textureId) {
    return new Promise((resolve, reject) => {
      // 检查缓存
      if (this.textureCache.has(textureId)) {
        resolve(this.textureCache.get(textureId));
        return;
      }

      const texture = this.getTextureById(textureId);
      if (!texture) {
        reject(new Error(`材质 ${textureId} 不存在`));
        return;
      }

      const img = new Image();
      img.crossOrigin = "anonymous";

      img.onload = () => {
        // 缓存图像
        this.textureCache.set(textureId, img);
        resolve(img);
      };

      img.onerror = () => {
        reject(new Error(`材质 ${textureId} 加载失败`));
      };

      img.src = texture.path || texture.dataUrl;
    });
  }

  /**
   * 搜索材质
   * @param {String} query 搜索关键词
   * @returns {Array} 匹配的材质数组
   */
  searchTextures(query) {
    if (!query) return this.getAllTextures();

    const searchTerm = query.toLowerCase();
    return this.getAllTextures().filter((texture) => {
      return (
        texture.name.toLowerCase().includes(searchTerm) ||
        texture.category.toLowerCase().includes(searchTerm) ||
        texture.description.toLowerCase().includes(searchTerm) ||
        texture.tags.some((tag) => tag.toLowerCase().includes(searchTerm))
      );
    });
  }

  /**
   * 保存自定义材质到本地存储
   */
  saveCustomTexturesToStorage() {
    try {
      const customTexturesData = this.customTextures.map((texture) => ({
        ...texture,
        // 不保存file对象到localStorage
        file: null,
      }));

      localStorage.setItem("canvasEditor_customTextures", JSON.stringify(customTexturesData));
    } catch (error) {
      console.error("保存自定义材质失败:", error);
    }
  }

  /**
   * 从本地存储加载自定义材质
   */
  loadCustomTexturesFromStorage() {
    try {
      const stored = localStorage.getItem("canvasEditor_customTextures");
      if (stored) {
        const customTexturesData = JSON.parse(stored);
        this.customTextures = customTexturesData;

        // 重建分类索引
        this.customTextures.forEach((texture) => {
          if (!this.categories.has(texture.category)) {
            this.categories.set(texture.category, []);
          }
          if (!this.categories.get(texture.category).includes(texture.id)) {
            this.categories.get(texture.category).push(texture.id);
          }
        });
      }
    } catch (error) {
      console.error("加载自定义材质失败:", error);
      this.customTextures = [];
    }
  }

  /**
   * 创建材质预设
   * @param {String} name 预设名称
   * @param {Object} settings 材质设置
   * @returns {String} 预设ID
   */
  createTexturePreset(name, settings) {
    const presetId = `preset_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    const preset = {
      id: presetId,
      name: name,
      type: "preset",
      category: "材质预设",
      created: new Date().toISOString(),
      settings: {
        textureId: settings.textureId,
        scale: settings.scale || 1,
        opacity: settings.opacity || 1,
        repeat: settings.repeat || "repeat",
        angle: settings.angle || 0,
        brushSize: settings.brushSize || 5,
        brushOpacity: settings.brushOpacity || 1,
        brushColor: settings.brushColor || "#000000",
      },
    };

    this.customTextures.push(preset);
    this._triggerEvent("textureAdded", preset);

    return presetId;
  }

  /**
   * 应用材质预设
   * @param {String} presetId 预设ID
   * @returns {Object|null} 预设设置
   */
  applyTexturePreset(presetId) {
    const preset = this.getTextureById(presetId);
    if (!preset || preset.type !== "preset") {
      return null;
    }

    return preset.settings;
  }

  /**
   * 添加事件监听器
   * @param {String} event 事件名称
   * @param {Function} callback 回调函数
   */
  addEventListener(event, callback) {
    if (this.listeners[event]) {
      this.listeners[event].push(callback);
    }
  }

  /**
   * 移除事件监听器
   * @param {String} event 事件名称
   * @param {Function} callback 回调函数
   */
  removeEventListener(event, callback) {
    if (this.listeners[event]) {
      const index = this.listeners[event].indexOf(callback);
      if (index !== -1) {
        this.listeners[event].splice(index, 1);
      }
    }
  }

  /**
   * 触发事件
   * @param {String} event 事件名称
   * @param {*} data 事件数据
   * @private
   */
  _triggerEvent(event, data) {
    if (this.listeners[event]) {
      this.listeners[event].forEach((callback) => {
        try {
          callback(data);
        } catch (error) {
          console.error(`执行 ${event} 事件监听器出错:`, error);
        }
      });
    }
  }

  /**
   * 清除所有缓存
   */
  clearCache() {
    this.textureCache.clear();
  }

  /**
   * 获取统计信息
   * @returns {Object} 统计信息
   */
  getStats() {
    return {
      builtInCount: this.builtInTextures.length,
      customCount: this.customTextures.length,
      totalCount: this.getAllTextures().length,
      categoriesCount: this.getCategories().length,
      cacheSize: this.textureCache.size,
    };
  }

  /**
   * 验证纹理文件
   * @param {File} file 要验证的文件
   * @returns {Boolean} 是否为有效的纹理文件
   */
  validateTextureFile(file) {
    if (!file) {
      console.warn("文件不存在");
      return false;
    }

    // 检查文件类型
    if (!file.type.startsWith("image/")) {
      console.warn("文件类型无效，必须是图片文件");
      return false;
    }

    // 检查文件大小（限制为 10MB）
    const maxSize = 10 * 1024 * 1024; // 10MB
    if (file.size > maxSize) {
      console.warn("文件大小超过限制（10MB）");
      return false;
    }

    // 检查支持的图片格式
    const supportedTypes = [
      "image/jpeg",
      "image/jpg",
      "image/png",
      "image/webp",
      "image/svg+xml",
      "image/bmp",
      "image/gif",
    ];

    if (!supportedTypes.includes(file.type)) {
      console.warn("不支持的图片格式");
      return false;
    }

    return true;
  }
}

// 创建单例实例
const texturePresetManager = new TexturePresetManager();

// 导出单例
export default texturePresetManager;
