import antDesign from '@iconify/json/json/ant-design.json';
import ep from '@iconify/json/json/ep.json';
import mdi from '@iconify/json/json/mdi.json';
import {
  addCollection as addOfflineCollection,
  addIcon as addOfflineIcon,
  Icon as IconifyIcon,
} from '@iconify/vue/offline';
import type {
  IconifyIcon as IconifyIconData,
  IconifyJSON,
} from '@iconify/vue/offline';

import { LOCAL_ICON_DATA } from './local-icons';

const LOCAL_ICON_NAMES = new Set<string>();

function getCollectionPrefix(data: IconifyJSON, prefix?: string | boolean) {
  if (prefix === false) {
    return '';
  }
  return `${typeof prefix === 'string' ? prefix : data.prefix}:`;
}

/**
 * Register an icon collection in the offline Iconify store and local name index.
 */
function registerCollection(data: IconifyJSON, prefix?: string | boolean) {
  addOfflineCollection(data, prefix);
  const iconPrefix = getCollectionPrefix(data, prefix);
  Object.keys(data.icons).forEach((name) => {
    LOCAL_ICON_NAMES.add(`${iconPrefix}${name}`);
  });
  Object.keys(data.aliases ?? {}).forEach((name) => {
    LOCAL_ICON_NAMES.add(`${iconPrefix}${name}`);
  });
}

/**
 * Register a single icon in the offline Iconify store.
 */
function registerIcon(name: string, data: IconifyIconData) {
  addOfflineIcon(name, data);
  LOCAL_ICON_NAMES.add(name);
}

/**
 * Return locally registered icon names for the requested collection.
 */
function listIcons(provider = '', prefix = ''): string[] {
  const providerPrefix = provider ? `@${provider}:` : '';
  const iconPrefix = prefix ? `${prefix}:` : '';
  return [...LOCAL_ICON_NAMES].filter((name) =>
    name.startsWith(`${providerPrefix}${iconPrefix}`),
  );
}

/**
 * Check whether an icon name is available without a network request.
 */
function isLocalIcon(name: string) {
  return LOCAL_ICON_NAMES.has(name);
}

registerCollection(antDesign);
registerCollection(ep);
registerCollection(mdi);
Object.entries(LOCAL_ICON_DATA).forEach(([name, data]) => {
  registerIcon(name, data);
});

export * from './create-icon';

export * from './lucide';

export type { IconifyIcon as IconifyIconStructure } from '@iconify/vue/offline';
export {
  IconifyIcon,
  isLocalIcon,
  listIcons,
  registerCollection as addCollection,
  registerIcon as addIcon,
};
