import { promises as fs } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

// Definindo __dirname para módulos ES
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Importando pacotes necessários
import { cleanupSVG, importDirectory, isEmptyColor, parseColors, runSVGO } from '@iconify/tools';
import { getIcons, getIconsCSS, stringToIcon } from '@iconify/utils';

// Fontes dos ícones
const sources = {
  svg: [
    {
      dir: 'src/assets/images/iconify-svg',
      monotone: false,
      prefix: 'custom',
    },
  ],
  icons: [],
  json: [
    // Importando JSON com a sintaxe de módulos ES
    {
      filename: (await import('@iconify-json/tabler/icons.json', { assert: { type: 'json' } })).default,
      icons: [],
    },
    {
      filename: (await import('@iconify-json/fa/icons.json', { assert: { type: 'json' } })).default,
      icons: ['facebook', 'google', 'twitter', 'circle'],
    },
  ],
};

// Arquivo de destino para salvar os ícones
const target = join(__dirname, 'icons.css');

(async function () {
  // Criar diretório de saída, se necessário
  const dir = dirname(target);
  try {
    await fs.mkdir(dir, { recursive: true });
  } catch (err) {
    // Tratamento de erro silencioso
  }

  const allIcons = [];

  // Convertendo sources.icons para sources.json
  if (sources.icons) {
    const sourcesJSON = sources.json ? sources.json : (sources.json = []);
    // Ordenar ícones por prefixo
    const organizedList = organizeIconsList(sources.icons);
    for (const prefix in organizedList) {
      const filename = (await import(`@iconify/json/json/${prefix}.json`, { assert: { type: 'json' } })).default;
      sourcesJSON.push({ filename, icons: organizedList[prefix] });
    }
  }

  // Coletar ícones dos arquivos JSON
  if (sources.json) {
    for (const item of sources.json) {
      const filename = item.filename;
      const content = filename;
      for (const key in content) {
        if (key === 'prefix' && content.prefix === 'tabler') {
          for (const k in content.icons) {
            content.icons[k].body = content.icons[k].body.replace(/stroke-width="2"/g, 'stroke-width="1.5"');
          }
        }
      }
      if (item.icons?.length) {
        const filteredContent = getIcons(content, item.icons);
        if (!filteredContent) throw new Error(`Cannot find required icons in ${filename}`);
        allIcons.push(filteredContent);
      } else {
        allIcons.push(content);
      }
    }
  }

  // Coletar ícones SVG personalizados
  if (sources.svg) {
    for (const source of sources.svg) {
      const iconSet = await importDirectory(source.dir, { prefix: source.prefix });
      await iconSet.forEach(async (name, type) => {
        if (type !== 'icon') return;
        const svg = iconSet.toSVG(name);
        if (!svg) {
          iconSet.remove(name);
          return;
        }
        try {
          await cleanupSVG(svg);
          if (source.monotone) {
            await parseColors(svg, {
              defaultColor: 'currentColor',
              callback: (attr, colorStr, color) => (!color || isEmptyColor(color) ? colorStr : 'currentColor'),
            });
          }
          await runSVGO(svg);
        } catch (err) {
          console.error(`Error parsing ${name} from ${source.dir}:`, err);
          iconSet.remove(name);
          return;
        }
        iconSet.fromSVG(name, svg);
      });
      allIcons.push(iconSet.export());
    }
  }

  // Gerar CSS a partir dos ícones coletados
  const cssContent = allIcons
    .map(iconSet => getIconsCSS(iconSet, Object.keys(iconSet.icons), { iconSelector: '.{prefix}-{name}', mode: 'mask' }))
    .join('\n');

  await fs.writeFile(target, cssContent, 'utf8');
  console.log(`Saved CSS to ${target}!`);
})().catch(err => {
  console.error(err);
});

// Função para organizar a lista de ícones
function organizeIconsList(icons) {
  const sorted = Object.create(null);
  icons.forEach(icon => {
    const item = stringToIcon(icon);
    if (!item) return;
    const prefix = item.prefix;
    const prefixList = sorted[prefix] ? sorted[prefix] : (sorted[prefix] = []);
    const name = item.name;
    if (!prefixList.includes(name)) prefixList.push(name);
  });
  return sorted;
}
