
export enum AddressType {
  REGULAR = 'regular',
  SYSTEM_CONTRACT = 'system_contract',
  TOKEN_CONTRACT = 'token_contract',
  SPECIAL = 'special'
}

export interface RegisteredAddressInfo {
  address: string;         
  name: string;            
  type: AddressType;       
  metadata?: Record<string, any>; 
}

const addressRegistry = new Map<string, RegisteredAddressInfo>();

const defaultAddresses: RegisteredAddressInfo[] = [
  {
    address: '0x0000000000000000000000000000000000000000',
    name: 'Zero Address',
    type: AddressType.SPECIAL
  }
];

defaultAddresses.forEach(info => {
  addressRegistry.set(info.address.toLowerCase(), {
    ...info,
    address: info.address.toLowerCase()
  });
});

/**
 * 
 * @param {string} address 
 * @param {string} name 
 * @param {AddressType} type 
 * @param {Record<string, any>} metadata 
 */
export function registerAddress(
  address: string,
  name: string,
  type: AddressType = AddressType.REGULAR,
  metadata?: Record<string, any>
): void {
  const normalizedAddress = address.toLowerCase();
  
  addressRegistry.set(normalizedAddress, {
    address: normalizedAddress,
    name,
    type,
    metadata
  });
}

/**
 * 
 * @param {string} address 
 * @param {string} name 
 * @param {Record<string, any>} metadata 
 */
export function registerSystemContract(
  address: string,
  name: string,
  metadata?: Record<string, any>
): void {
  registerAddress(address, name, AddressType.SYSTEM_CONTRACT, metadata);
}

/**
 * 
 * @param {string} address 
 * @param {string} name 
 * @param {Record<string, any>} metadata 
 */
export function registerTokenContract(
  address: string,
  name: string,
  metadata?: Record<string, any>
): void {
  registerAddress(address, name, AddressType.TOKEN_CONTRACT, metadata);
}

/**
 * 
 * @param {Array} addresses 
 */
export function registerAddresses(
  addresses: Array<{
    address: string;
    name: string;
    type?: AddressType;
    metadata?: Record<string, any>;
  }>
): void {
  addresses.forEach(({ address, name, type = AddressType.REGULAR, metadata }) => {
    registerAddress(address, name, type, metadata);
  });
}

/**
 * 
 * @param {string} address 
 * @returns {boolean} 
 */
export function unregisterAddress(address: string): boolean {
  return addressRegistry.delete(address.toLowerCase());
}

/**
 * 
 * @param {string} address 
 * @returns {RegisteredAddressInfo | null} 
 */
export function getAddressInfo(address: string): RegisteredAddressInfo | null {
  const normalizedAddress = address.toLowerCase();
  return addressRegistry.has(normalizedAddress)
    ? addressRegistry.get(normalizedAddress) || null
    : null;
}

/**
 * 
 * @param {string} address 
 * @returns {boolean} 
 */
export function isRegisteredAddress(address: string): boolean {
  return addressRegistry.has(address.toLowerCase());
}

/**
 * 
 * @param {string} address 
 * @returns {boolean} 
 */
export function isSystemContract(address: string): boolean {
  const info = getAddressInfo(address);
  return info !== null && info.type === AddressType.SYSTEM_CONTRACT;
}

/**
 * 
 * @param {string} address 
 * @returns {boolean} 
 */
export function isTokenContract(address: string): boolean {
  const info = getAddressInfo(address);
  return info !== null && info.type === AddressType.TOKEN_CONTRACT;
}

/**
 * 
 * @param {string} address 
 * @returns {string | null} 
 */
export function getAddressName(address: string): string | null {
  const info = getAddressInfo(address);
  return info ? info.name : null;
}

/**
 * 
 * @param {AddressType} type 
 * @returns {Record<string, string>} 
 */
export function getAllRegisteredAddresses(type?: AddressType): Record<string, string> {
  const result: Record<string, string> = {};
  
  addressRegistry.forEach((info, address) => {
    if (!type || info.type === type) {
      result[address] = info.name;
    }
  });
  
  return result;
} 