/**
 * 加密工具模块
 * 独立的加密解密功能，支持请求数据加密和响应数据解密
 * 可直接集成到任何Vue项目中使用
 */

import { CryptoUtils } from './crypto';
import { CommonParamsManager } from './commonParams';
import { Base64 } from 'js-base64';
import CryptoJS from 'crypto-js';
/**
 * 公共参数配置接口
 */
export interface CommonParamsConfig {
  device?: string;
  source?: string;
  appversion?: string;
  signatureKey?: string;
  enableSignature?: boolean;
}
/**
 * 加密配置接口
 */
export interface CryptoConfig {
  key: string;
  iv: string;
  mode?: typeof CryptoJS.mode.CBC;
  padding?: typeof CryptoJS.pad.Pkcs7;
}
/**
 * 加密工具配置
 */
export interface CryptoToolConfig {
  enabled?: boolean;
  cryptoConfig?: CryptoConfig;
  commonParamsConfig?: CommonParamsConfig;
  secretKeys?: Record<string, CryptoConfig>;
  enableRequestEncryption?: boolean;
  enableResponseDecryption?: boolean;
}

/**
 * 默认加密工具配置
 */
export const DEFAULT_CRYPTO_TOOL_CONFIG: CryptoToolConfig = {
  enabled: true,
  cryptoConfig: undefined,
  commonParamsConfig: undefined,
  secretKeys: undefined,
  enableRequestEncryption: true,
  enableResponseDecryption: true
};

/**
 * 加密工具类
 */
export class CryptoTool {
  private config: CryptoToolConfig;
  private cryptoUtils: CryptoUtils;
  private commonParamsManager: CommonParamsManager;

  constructor(config?: CryptoToolConfig) {
    this.config = { ...DEFAULT_CRYPTO_TOOL_CONFIG, ...config };
    
    // 初始化加密工具
    this.cryptoUtils = new CryptoUtils(
      this.config.cryptoConfig,
      this.config.enabled && (this.config.enableRequestEncryption || this.config.enableResponseDecryption)
    );
    
    // 初始化公共参数管理器
    this.commonParamsManager = new CommonParamsManager(this.config.commonParamsConfig);
  }

  /**
   * 设置配置
   */
  setConfig(config: CryptoToolConfig): void {
    this.config = { ...this.config, ...config };
    
    // 更新加密工具配置
    if (config.cryptoConfig) {
      this.cryptoUtils.setConfig(config.cryptoConfig);
    }
    
    // 更新加密工具启用状态
    this.cryptoUtils.setEnabled(
      this.config.enabled && (this.config.enableRequestEncryption || this.config.enableResponseDecryption)
    );
    
    // 更新公共参数管理器配置
    if (config.commonParamsConfig) {
      this.commonParamsManager.setConfig(config.commonParamsConfig);
    }
  }

  /**
   * 设置Token
   */
  setToken(token: string): void {
    this.commonParamsManager.setToken(token);
  }

  /**
   * 获取随机密钥名称
   */
  private getRandomSecretKeyName(): string {
    if (!this.config.secretKeys) {
      return 'default';
    }
    
    const keys = Object.keys(this.config.secretKeys);
    if (keys.length === 0) {
      return 'default';
    }
    
    const randomIndex = Math.floor(Math.random() * keys.length);
    return keys[randomIndex];
  }

  /**
   * 获取密钥配置
   */
  private getSecretConfig(keyName: string): CryptoConfig | undefined {
    if (!this.config.secretKeys) {
      return undefined;
    }
    
    return this.config.secretKeys[keyName];
  }

  /**
   * 加密数据
   */
  encrypt(data: any, secretKeyName?: string): any {
    if (!this.config.enabled || !this.config.enableRequestEncryption) {
      return data;
    }

    try {
      // 生成或使用指定的密钥名称
      const keyName = secretKeyName || this.getRandomSecretKeyName();
      
      // 获取对应的密钥配置
      const secretConfig = this.getSecretConfig(keyName);
      if (secretConfig) {
        this.cryptoUtils.setConfig(secretConfig);
      }

      // 序列化数据
      const dataString = typeof data === 'string' ? data : JSON.stringify(data);
      
      // 加密数据
      const encryptedData = this.cryptoUtils.encrypt(dataString);
      
      // Base64编码
      const base64Encoded = Base64.encode(encryptedData);
      
      // URL编码
      return {
        sign_data: encodeURIComponent(base64Encoded),
        sign_name: keyName
      };
    } catch (error) {
      console.error('数据加密失败:', error);
      throw new Error('数据加密失败');
    }
  }

  /**
   * 解密数据
   */
  decrypt(encryptedData: string, secretKeyName: string): any {
    if (!this.config.enabled || !this.config.enableResponseDecryption) {
      return encryptedData;
    }

    try {
      // 获取对应的密钥配置
      const secretConfig = this.getSecretConfig(secretKeyName);
      if (secretConfig) {
        this.cryptoUtils.setConfig(secretConfig);
      }

      // URL解码
      const urlDecoded = decodeURIComponent(encryptedData);
      
      // Base64解码
      const base64Decoded = Base64.decode(urlDecoded);
      
      // 解密数据
      const decryptedData = this.cryptoUtils.decrypt(base64Decoded);
      
      // 解析JSON
      return JSON.parse(decryptedData);
    } catch (error) {
      console.error('数据解密失败:', error);
      throw new Error('数据解密失败');
    }
  }

  /**
   * 处理请求数据
   */
  processRequest(data: any, method: string = 'POST'): any {
    if (!this.config.enabled || !this.config.enableRequestEncryption) {
      return data;
    }

    try {
      // 生成随机密钥名称
      const secretKeyName = this.getRandomSecretKeyName();
      
      // 加密数据
      const encryptedData = this.encrypt(data, secretKeyName);
      
      return encryptedData;
    } catch (error) {
      console.error('请求数据处理失败:', error);
      throw error;
    }
  }

  /**
   * 处理响应数据
   */
  processResponse(response: any): any {
    if (!this.config.enabled || !this.config.enableResponseDecryption) {
      return response;
    }

    try {
      // 检查响应数据是否包含加密数据
      if (response && typeof response === 'object' && 'encrypted_data' in response) {
        // 获取签名名称
        const signName = response.sign_name || response.headers?.sign_name || 'default';
        
        // 解密响应数据
        if (typeof response.encrypted_data === 'string' && response.encrypted_data.length > 0) {
          const decryptedData = this.decrypt(response.encrypted_data, signName);
          
          // 更新响应数据
          return {
            ...response,
            data: decryptedData
          };
        } else {
          // 空数据情况
          return {
            ...response,
            data: null
          };
        }
      }

      return response;
    } catch (error) {
      console.error('响应数据处理失败:', error);
      throw error;
    }
  }

  /**
   * 生成公共参数
   */
  generateCommonParams(customParams?: Record<string, any>, signName?: string): Record<string, any> {
    return this.commonParamsManager.generateCommonParams(customParams, signName);
  }

  /**
   * 为请求头添加公共参数
   */
  addCommonParamsToHeaders(headers: Record<string, any>, customParams?: Record<string, any>, signName?: string): Record<string, any> {
    return this.commonParamsManager.addCommonParamsToHeaders(headers, customParams, signName);
  }

  /**
   * 启用加密功能
   */
  enable(): void {
    this.config.enabled = true;
    this.cryptoUtils.setEnabled(true);
  }

  /**
   * 禁用加密功能
   */
  disable(): void {
    this.config.enabled = false;
    this.cryptoUtils.setEnabled(false);
  }

  /**
   * 检查加密功能是否启用
   */
  isEnabled(): boolean {
    return this.config.enabled === true;
  }
}

/**
 * 默认加密工具实例
 */
export const defaultCryptoTool = new CryptoTool();

/**
 * 创建加密工具实例
 */
export const createCryptoTool = (config?: CryptoToolConfig): CryptoTool => {
  return new CryptoTool(config);
};

export default CryptoTool;