/**
 * Common utility functions for masking sensitive data across the application
 */

/**
 * Mask sensitive field for display
 * Shows only last 4 characters for shorter fields, last 6 for longer fields
 * @param value - Sensitive value to mask
 * @returns Masked value
 */
export function maskSensitiveField(value: string): string {
  if (!value) {
    return '******';
  }
  
  if (value.length <= 4) {
    return '****';
  } else if (value.length <= 8) {
    return '****' + value.slice(-4);
  } else {
    return '****' + value.slice(-6);
  }
}

/**
 * Mask API token for display (legacy function for backward compatibility)
 * Shows only last 6 characters
 * @param token - API token to mask
 * @returns Masked token
 */
export function maskApiToken(token: string): string {
  if (!token || token.length <= 6) {
    return '******';
  }
  return '****' + token.slice(-6);
}

/**
 * Mask MyOperator credentials object
 * Keeps only specified fields unmasked
 * @param myoperator - MyOperator credentials object
 * @param unmaskedFields - Array of field names to keep unmasked
 * @returns Masked credentials object
 */
export function maskMyOperatorCredentials(
  myoperator: any,
  unmaskedFields: string[] = ['isActive', 'connectionStatus', 'lastSyncedAt', 'lastConnectionTest']
): any {
  if (!myoperator) {
    return myoperator;
  }

  const masked: any = {};
  
  // Add unmasked fields
  unmaskedFields.forEach(field => {
    if (myoperator[field] !== undefined) {
      masked[field] = myoperator[field];
    }
  });

  // Add masked sensitive fields
  const sensitiveFields = ['apiToken', 'secretKey', 'xApiKey', 'companyId', 'webhookSecret'];
  sensitiveFields.forEach(field => {
    if (myoperator[field]) {
      masked[`masked${field.charAt(0).toUpperCase() + field.slice(1)}`] = maskSensitiveField(myoperator[field]);
    }
  });

  return masked;
}

/**
 * Mask WhatsApp credentials object
 * @param whatsapp - WhatsApp credentials object
 * @returns Masked WhatsApp credentials
 */
export function maskWhatsAppCredentials(whatsapp: any): any {
  if (!whatsapp) {
    return whatsapp;
  }

  const masked = { ...whatsapp };
  
  // Mask sensitive fields
  if (masked.accessToken) {
    masked.maskedAccessToken = maskSensitiveField(masked.accessToken);
    delete masked.accessToken;
  }
  
  if (masked.fbSecretId) {
    masked.maskedFbSecretId = maskSensitiveField(masked.fbSecretId);
    delete masked.fbSecretId;
  }

  return masked;
}

/**
 * Mask Fast2SMS credentials object
 * @param fast2sms - Fast2SMS credentials object
 * @returns Masked Fast2SMS credentials
 */
export function maskFast2SmsCredentials(fast2sms: any): any {
  if (!fast2sms) {
    return fast2sms;
  }

  const masked = { ...fast2sms };
  
  // Mask sensitive fields
  if (masked.accessToken) {
    masked.maskedAccessToken = maskSensitiveField(masked.accessToken);
    delete masked.accessToken;
  }

  return masked;
}

/**
 * Comprehensive company data masking function
 * Masks all sensitive fields in a company object
 * @param companyData - Company data object
 * @param options - Masking options
 * @returns Company data with sensitive fields masked
 */
export function maskCompanyData(
  companyData: any,
  options: {
    maskMyOperator?: boolean;
    maskWhatsApp?: boolean;
    maskFast2Sms?: boolean;
    myOperatorUnmaskedFields?: string[];
  } = {}
): any {
  if (!companyData) {
    return companyData;
  }

  // Create a deep copy to avoid mutating original data
  const masked = JSON.parse(JSON.stringify(companyData));

  // Default options
  const {
    maskMyOperator = true,
    maskWhatsApp = true,
    maskFast2Sms = true,
    myOperatorUnmaskedFields = ['isActive', 'connectionStatus', 'lastSyncedAt', 'lastConnectionTest']
  } = options;

  // Mask MyOperator credentials
  if (maskMyOperator && masked.myoperator) {
    masked.myoperator = maskMyOperatorCredentials(masked.myoperator, myOperatorUnmaskedFields);
  }

  // Mask WhatsApp credentials
  if (maskWhatsApp && masked.whatsapp) {
    masked.whatsapp = maskWhatsAppCredentials(masked.whatsapp);
  }

  // Mask Fast2SMS credentials
  if (maskFast2Sms && masked.fast2sms) {
    masked.fast2sms = maskFast2SmsCredentials(masked.fast2sms);
  }

  return masked;
}

/**
 * Mask company data in array format
 * @param companies - Array of company objects
 * @param options - Masking options
 * @returns Array of companies with sensitive fields masked
 */
export function maskCompaniesData(
  companies: any[],
  options?: Parameters<typeof maskCompanyData>[1]
): any[] {
  if (!Array.isArray(companies)) {
    return companies;
  }

  return companies.map(company => maskCompanyData(company, options));
}

/**
 * Transform company data for API response
 * Applies masking and removes internal fields
 * @param companyData - Raw company data from database
 * @param options - Transform options
 * @returns Transformed company data safe for API response
 */
export function transformCompanyForResponse(
  companyData: any,
  options: {
    includeTimeStamps?: boolean;
    maskSensitiveData?: boolean;
    customMaskingOptions?: Parameters<typeof maskCompanyData>[1];
  } = {}
): any {
  if (!companyData) {
    return companyData;
  }

  const {
    includeTimeStamps = false,
    maskSensitiveData = true,
    customMaskingOptions = {}
  } = options;

  let transformed = companyData;

  // Convert to plain object if it's a Mongoose document
  if (typeof companyData.toObject === 'function') {
    transformed = companyData.toObject();
  } else if (typeof companyData.toJSON === 'function') {
    transformed = companyData.toJSON();
  } else {
    transformed = JSON.parse(JSON.stringify(companyData));
  }

  // Apply masking
  if (maskSensitiveData) {
    transformed = maskCompanyData(transformed, customMaskingOptions);
  }

  // Handle timestamps
  if (!includeTimeStamps) {
    delete transformed.createdAt;
    delete transformed.updatedAt;
  }

  // Remove internal fields
  delete transformed.__v;
  delete transformed.password;

  // Transform _id to id if present
  if (transformed._id) {
    transformed.id = transformed._id.toString();
    delete transformed._id;
  }

  return transformed;
}