// Note: avoid Node's crypto to support runtimes where it's unavailable (e.g., edge/browsers)

export interface PiiHasher {
  hash(input: string): string;
}

export class Md5PiiHasher implements PiiHasher {
  constructor(private readonly salt: string) {}
  hash(input: string) {
    // FNV-1a 32-bit using Math.imul, repeated 4 times with variant salt to get 128-bit hex
    const fnv1a32 = (str: string) => {
      // Convert to UTF-8 bytes without relying on TextEncoder/Buffer
      const data = unescape(encodeURIComponent(str));
      let hash = 0x811c9dc5; // offset basis (2166136261)
      for (let i = 0; i < data.length; i++) {
        hash = Math.imul(hash ^ data.charCodeAt(i), 0x01000193); // 16777619
      }
      return hash >>> 0; // unsigned 32-bit
    };

    // Four independent 32-bit hashes to produce a stable 128-bit hex string
    const h1 = fnv1a32(`${this.salt}::1::${input}`);
    const h2 = fnv1a32(`${this.salt}::2::${input}`);
    const h3 = fnv1a32(`${this.salt}::3::${input}`);
    const h4 = fnv1a32(`${this.salt}::4::${input}`);
    const toHex8 = (n: number) => n.toString(16).padStart(8, "0");
    return `${toHex8(h1)}${toHex8(h2)}${toHex8(h3)}${toHex8(h4)}`;
  }
}

export const piiHasher: PiiHasher = new Md5PiiHasher(process.env.CALENDSO_ENCRYPTION_KEY ?? "");

export const hashEmail = (email: string, hasher: PiiHasher = piiHasher): string => {
  const [localPart, domain] = email.split("@");
  // Simple hash function for email, can be replaced with a more complex one if needed
  return `${hasher.hash(localPart)}@${domain}`;
};
