import { Command } from "./Command";
import { BrushStore } from "../store/BrushStore";

/**
 * 笔刷属性设置基类命令
 * 所有笔刷属性设置命令的基类
 */
class BaseBrushCommand extends Command {
  constructor(options = {}) {
    super(options);
    this.brushStore = options.brushStore || BrushStore;
  }
}

/**
 * 笔刷大小设置命令
 */
export class BrushSizeCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {Number} options.size 要设置的笔刷大小
   * @param {Number} options.previousSize 之前的笔刷大小（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `设置笔刷大小: ${options.size}`,
      description: `将笔刷大小从 ${options.previousSize || "?"} 设为 ${options.size}`,
    });

    this.size = options.size;
    this.previousSize = options.previousSize || this.brushStore.state.size;
  }

  execute() {
    // 记录当前大小用于撤销
    if (this.previousSize === null) {
      this.previousSize = this.brushStore.state.size;
    }

    // 执行设置
    this.brushStore.setBrushSize(this.size);
    return this.size;
  }

  undo() {
    this.brushStore.setBrushSize(this.previousSize);
    return this.previousSize;
  }
}

/**
 * 笔刷颜色设置命令
 */
export class BrushColorCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {String} options.color 要设置的颜色
   * @param {String} options.previousColor 之前的颜色（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `设置笔刷颜色: ${options.color}`,
      description: `将笔刷颜色从 ${options.previousColor || "?"} 设为 ${options.color}`,
    });

    this.color = options.color;
    this.previousColor = options.previousColor || this.brushStore.state.color;
  }

  execute() {
    // 记录当前颜色用于撤销
    if (this.previousColor === null) {
      this.previousColor = this.brushStore.state.color;
    }

    // 执行设置
    this.brushStore.setBrushColor(this.color);
    return this.color;
  }

  undo() {
    this.brushStore.setBrushColor(this.previousColor);
    return this.previousColor;
  }
}

/**
 * 笔刷透明度设置命令
 */
export class BrushOpacityCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {Number} options.opacity 要设置的透明度 (0-1)
   * @param {Number} options.previousOpacity 之前的透明度（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `设置笔刷透明度: ${options.opacity}`,
      description: `将笔刷透明度从 ${options.previousOpacity || "?"} 设为 ${options.opacity}`,
    });

    this.opacity = options.opacity;
    this.previousOpacity = options.previousOpacity || this.brushStore.state.opacity;
  }

  execute() {
    // 记录当前透明度用于撤销
    if (this.previousOpacity === null) {
      this.previousOpacity = this.brushStore.state.opacity;
    }

    // 执行设置
    this.brushStore.setBrushOpacity(this.opacity);
    return this.opacity;
  }

  undo() {
    this.brushStore.setBrushOpacity(this.previousOpacity);
    return this.previousOpacity;
  }
}

/**
 * 笔刷类型设置命令
 */
export class BrushTypeCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {String} options.brushType 要设置的笔刷类型
   * @param {String} options.previousType 之前的笔刷类型（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `设置笔刷类型: ${options.brushType}`,
      description: `将笔刷类型从 ${options.previousType || "?"} 设为 ${options.brushType}`,
    });

    this.brushType = options.brushType;
    this.previousType = options.previousType || this.brushStore.state.type;
    this.brushManager = options.brushManager;
  }

  execute() {
    // 记录当前类型用于撤销
    if (this.previousType === null) {
      this.previousType = this.brushStore.state.type;
    }

    // 执行设置
    // this.brushStore.setBrushType(this.brushType);
    this.brushManager.setBrushType(this.brushType);
    return this.brushType;
  }

  undo() {
    // this.brushStore.setBrushType(this.previousType);
    this.brushManager.setBrushType(this.previousType);
    return this.previousType;
  }
}

/**
 * 材质设置命令
 */
export class TextureCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {Boolean} options.enabled 是否启用材质
   * @param {String} options.path 材质路径
   * @param {Number} options.scale 材质缩放
   * @param {Object} options.previous 之前的材质设置（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    super({
      ...options,
      name: options.enabled ? "启用笔刷材质" : "禁用笔刷材质",
      description: options.enabled ? `启用材质: ${options.path || "[默认]"}` : "禁用笔刷材质",
    });

    this.enabled = options.enabled;
    this.path = options.path;
    this.scale = options.scale;

    // 保存之前状态用于撤销
    this.previous = options.previous || {
      enabled: this.brushStore.state.textureEnabled,
      path: this.brushStore.state.texturePath,
      scale: this.brushStore.state.textureScale,
    };
  }

  execute() {
    // 记录当前状态用于撤销
    if (!this.previous) {
      this.previous = {
        enabled: this.brushStore.state.textureEnabled,
        path: this.brushStore.state.texturePath,
        scale: this.brushStore.state.textureScale,
      };
    }

    // 执行设置
    this.brushStore.setTextureEnabled(this.enabled);

    if (this.path) {
      this.brushStore.setTexturePath(this.path);
    }

    if (this.scale !== undefined) {
      this.brushStore.setTextureScale(this.scale);
    }

    return {
      enabled: this.enabled,
      path: this.path,
      scale: this.scale,
    };
  }

  undo() {
    if (!this.previous) return null;

    this.brushStore.setTextureEnabled(this.previous.enabled);
    this.brushStore.setTexturePath(this.previous.path);
    this.brushStore.setTextureScale(this.previous.scale);

    return this.previous;
  }
}

/**
 * 预设应用命令
 */
export class BrushPresetCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {Number|Object} options.preset 预设索引或预设对象
   * @param {Object} options.previousState 之前的状态（可选）
   * @param {Object} options.brushStore BrushStore实例（可选）
   */
  constructor(options = {}) {
    const presetName =
      typeof options.preset === "object" ? options.preset.name : `预设 ${options.preset}`;

    super({
      ...options,
      name: `应用笔刷预设: ${presetName}`,
      description: `应用预设: ${presetName}`,
    });

    this.preset = options.preset;

    // 保存之前状态用于撤销
    this.previousState = options.previousState || {
      size: this.brushStore.state.size,
      color: this.brushStore.state.color,
      opacity: this.brushStore.state.opacity,
      type: this.brushStore.state.type,
      textureEnabled: this.brushStore.state.textureEnabled,
      textureScale: this.brushStore.state.textureScale,
      texturePath: this.brushStore.state.texturePath,
    };
  }

  execute() {
    // 记录当前状态用于撤销
    if (!this.previousState) {
      this.previousState = {
        size: this.brushStore.state.size,
        color: this.brushStore.state.color,
        opacity: this.brushStore.state.opacity,
        type: this.brushStore.state.type,
        textureEnabled: this.brushStore.state.textureEnabled,
        textureScale: this.brushStore.state.textureScale,
        texturePath: this.brushStore.state.texturePath,
      };
    }

    // 应用预设
    if (typeof this.preset === "number") {
      this.brushStore.applyPreset(this.preset);
    } else if (typeof this.preset === "object") {
      // 应用自定义预设对象
      if (this.preset.size !== undefined) this.brushStore.setBrushSize(this.preset.size);
      if (this.preset.color !== undefined) this.brushStore.setBrushColor(this.preset.color);
      if (this.preset.opacity !== undefined) this.brushStore.setBrushOpacity(this.preset.opacity);
      if (this.preset.type !== undefined) this.brushStore.setBrushType(this.preset.type);

      if (this.preset.textureEnabled !== undefined) {
        this.brushStore.setTextureEnabled(this.preset.textureEnabled);
      }

      if (this.preset.texturePath !== undefined) {
        this.brushStore.setTexturePath(this.preset.texturePath);
      }

      if (this.preset.textureScale !== undefined) {
        this.brushStore.setTextureScale(this.preset.textureScale);
      }
    }

    return true;
  }

  undo() {
    if (!this.previousState) return false;

    // 恢复之前的状态
    this.brushStore.setBrushSize(this.previousState.size);
    this.brushStore.setBrushColor(this.previousState.color);
    this.brushStore.setBrushOpacity(this.previousState.opacity);
    this.brushStore.setBrushType(this.previousState.type);
    this.brushStore.setTextureEnabled(this.previousState.textureEnabled);
    this.brushStore.setTextureScale(this.previousState.textureScale);
    this.brushStore.setTexturePath(this.previousState.texturePath);

    return true;
  }
}

/**
 * 笔刷属性命令
 * 用于修改笔刷的任意属性，包括特殊属性
 */
export class BrushPropertyCommand extends Command {
  /**
   * 构造函数
   * @param {Object} options 命令选项
   * @param {String} options.propertyId 属性ID
   * @param {any} options.value 新的属性值
   * @param {Object} options.brushStore BrushStore实例
   */
  constructor(options) {
    super({
      name: "笔刷属性更改",
      description: `更改笔刷属性 ${options.propertyId}`,
      options,
    });

    this.propertyId = options.propertyId;
    this.newValue = options.value;
    this.oldValue = null;
    this.brushStore = options.brushStore || BrushStore;
  }

  /**
   * 执行命令
   * @returns {Boolean} 是否执行成功
   */
  execute() {
    if (!this.brushStore) {
      console.error("BrushStore不可用");
      return false;
    }

    // 保存旧值用于撤销
    this.oldValue = this.brushStore.getPropertyValue(this.propertyId);

    // 更新属性值
    this.brushStore.updatePropertyValue(this.propertyId, this.newValue);

    return true;
  }

  /**
   * 撤销命令
   * @param {Object} context 命令上下文
   * @returns {Boolean} 是否撤销成功
   */
  undo() {
    if (!this.brushStore || this.oldValue === null) {
      return false;
    }

    // 恢复旧值
    this.brushStore.updatePropertyValue(this.propertyId, this.oldValue);

    return true;
  }
}

/**
 * 材质选择命令
 */
export class TextureSelectionCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {String} options.textureId 要设置的材质ID
   * @param {String} options.previousTextureId 之前的材质ID（可选）
   * @param {Object} options.brushManager 笔刷管理器实例
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `切换纹理材质`,
      description: `切换到材质: ${options.textureId}`,
    });

    this.textureId = options.textureId;
    this.previousTextureId = options.previousTextureId;
    this.brushManager = options.brushManager;
  }

  execute() {
    // 记录当前材质用于撤销
    const currentBrush = this.brushManager.activeBrush;
    if (currentBrush && currentBrush.getCurrentTexture) {
      const currentTexture = currentBrush.getCurrentTexture();
      this.previousTextureId = currentTexture ? currentTexture.id : null;
    }

    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    // 设置材质
    const activeBrush = this.brushManager.activeBrush;
    if (activeBrush && activeBrush.setTextureById) {
      activeBrush.setTextureById(this.textureId);
    }

    return this.textureId;
  }

  undo() {
    if (!this.previousTextureId) return false;

    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    // 恢复之前的材质
    const activeBrush = this.brushManager.activeBrush;
    if (activeBrush && activeBrush.setTextureById) {
      activeBrush.setTextureById(this.previousTextureId);
    }

    return this.previousTextureId;
  }
}

/**
 * 材质属性设置命令
 */
export class TexturePropertyCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {String} options.property 要设置的属性名称 (scale, rotation, offsetX, offsetY等)
   * @param {any} options.value 要设置的属性值
   * @param {any} options.previousValue 之前的属性值（可选）
   * @param {Object} options.brushManager 笔刷管理器实例
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `设置材质属性: ${options.property}`,
      description: `将材质${options.property}从 ${
        options.previousValue || "?"
      } 设为 ${options.value}`,
    });

    this.property = options.property;
    this.value = options.value;
    this.previousValue = options.previousValue;
    this.brushManager = options.brushManager;
  }

  execute() {
    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    const activeBrush = this.brushManager.activeBrush;
    if (!activeBrush || !activeBrush.setTextureProperty) {
      return false;
    }

    // 记录当前值用于撤销
    if (this.previousValue === undefined) {
      this.previousValue = activeBrush.getTextureProperty(this.property);
    }

    // 设置新值
    activeBrush.setTextureProperty(this.property, this.value);
    return this.value;
  }

  undo() {
    if (this.previousValue === undefined) return false;

    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    const activeBrush = this.brushManager.activeBrush;
    if (activeBrush && activeBrush.setTextureProperty) {
      activeBrush.setTextureProperty(this.property, this.previousValue);
    }

    return this.previousValue;
  }
}

/**
 * 材质预设应用命令
 */
export class TexturePresetCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {String|Object} options.preset 预设ID或预设对象
   * @param {Object} options.previousState 之前的材质状态（可选）
   * @param {Object} options.brushManager 笔刷管理器实例
   */
  constructor(options = {}) {
    const presetName = typeof options.preset === "object" ? options.preset.name : options.preset;

    super({
      ...options,
      name: `应用材质预设: ${presetName}`,
      description: `应用材质预设: ${presetName}`,
    });

    this.preset = options.preset;
    this.previousState = options.previousState;
    this.brushManager = options.brushManager;
  }

  execute() {
    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    const activeBrush = this.brushManager.activeBrush;
    if (!activeBrush || !activeBrush.applyTexturePreset) {
      return false;
    }

    // 记录当前状态用于撤销
    if (!this.previousState) {
      this.previousState = activeBrush.getCurrentTextureState();
    }

    // 应用预设
    activeBrush.applyTexturePreset(this.preset);
    return true;
  }

  undo() {
    if (!this.previousState) return false;

    // 确保当前是材质笔刷
    if (this.brushManager.getCurrentBrushType() !== "texture") {
      this.brushManager.setBrushType("texture");
    }

    const activeBrush = this.brushManager.activeBrush;
    if (activeBrush && activeBrush.restoreTextureState) {
      activeBrush.restoreTextureState(this.previousState);
    }

    return true;
  }
}

/**
 * 纹理上传命令
 */
export class TextureUploadCommand extends BaseBrushCommand {
  /**
   * @param {Object} options 命令选项
   * @param {File} options.file 要上传的纹理文件
   * @param {String} options.name 纹理名称（可选）
   * @param {String} options.category 纹理分类（可选）
   * @param {Object} options.texturePresetManager 纹理预设管理器实例
   * @param {Object} options.brushManager 笔刷管理器实例
   */
  constructor(options = {}) {
    super({
      ...options,
      name: `上传纹理: ${options.name || options.file?.name || "未知"}`,
      description: `上传自定义纹理文件`,
    });

    this.file = options.file;
    this.name = options.name || options.file?.name?.replace(/\.[^/.]+$/, "") || "自定义纹理";
    this.category = options.category || "自定义材质";
    this.texturePresetManager = options.texturePresetManager;
    this.brushManager = options.brushManager;
    this.uploadedTextureId = null;
  }

  async execute() {
    if (!this.file || !this.texturePresetManager) {
      throw new Error("缺少必要的文件或纹理预设管理器");
    }

    try {
      // 创建文件 data URL
      const dataUrl = await this._fileToDataUrl(this.file);

      // 添加到纹理预设管理器
      this.uploadedTextureId = this.texturePresetManager.addCustomTexture({
        name: this.name,
        category: this.category,
        file: this.file,
        dataUrl: dataUrl,
        preview: dataUrl,
      });

      // 如果是纹理笔刷，自动应用新上传的纹理
      if (this.brushManager) {
        if (this.brushManager.getCurrentBrushType() !== "texture") {
          this.brushManager.setBrushType("texture");
        }

        const activeBrush = this.brushManager.activeBrush;
        if (activeBrush && activeBrush.updateProperty) {
          activeBrush.updateProperty("textureSelector", this.uploadedTextureId);
        }
      }

      return {
        textureId: this.uploadedTextureId,
        dataUrl: dataUrl,
        name: this.name,
      };
    } catch (error) {
      console.error("纹理上传失败:", error);
      throw new Error(`纹理上传失败: ${error.message}`);
    }
  }

  undo() {
    if (!this.uploadedTextureId || !this.texturePresetManager) {
      return false;
    }

    // 从纹理预设管理器中移除上传的纹理
    try {
      this.texturePresetManager.removeCustomTexture(this.uploadedTextureId);
      return true;
    } catch (error) {
      console.error("撤销纹理上传失败:", error);
      return false;
    }
  }

  /**
   * 将文件转换为 data URL
   * @private
   * @param {File} file
   * @returns {Promise<string>}
   */
  _fileToDataUrl(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (event) => {
        resolve(event.target.result);
      };
      reader.onerror = (error) => {
        reject(error);
      };
      reader.readAsDataURL(file);
    });
  }
}
