import fs from 'node:fs';
import path from 'path';
import prettier from 'prettier';
import {filteredFonts} from './filtered-fonts';
import {removeWhitespace, unquote} from './utils';

const OUTDIR = './src';

const typesInfo = `
// This file is auto-generated by 'bun scripts/generate-index.ts'
// Do not edit this file manually

type Variants = Record<
  string,
  {
    weights: string;
    subsets: string;
  }
>;

export type FontInfo = {
  fontFamily: string;
  importName: string;
  version: string;
  url: string;
  unicodeRanges: Record<string, string>;
  fonts: Record<string, Record<string, Record<string, string>>>;
	subsets: string[];
}

export type GoogleFont = {
  getInfo: () => FontInfo;
  fontFamily: string;
  loadFont: <T extends keyof Variants>(
    style?: T | undefined,
    options?:
      | {
          weights?: Variants[T]["weights"][] | undefined;
          subsets?: Variants[T]["subsets"][] | undefined;
          document?: Document | undefined;
          ignoreTooManyRequestsWarning?: boolean;
        }
      | undefined
  ) => {
		fontFamily: FontInfo['fontFamily'];
		fonts: FontInfo['fonts'];
		unicodeRanges: FontInfo['unicodeRanges'];
		waitUntilDone: () => Promise<undefined>;
  };
};
`;

const generate = async () => {
	// Prepare filename
	const filename = `index.ts`;

	console.log(`- Generating ${filename}`);
	let output = `${typesInfo}
  
  export const getAvailableFonts = () => ${JSON.stringify(
		filteredFonts.map((f) => {
			const importName = removeWhitespace(unquote(f.family));
			return {
				fontFamily: unquote(f.family),
				importName,
				load: `() => import('./${importName}') as Promise<GoogleFont>`,
			};
		}),
	)};`.replace(/\"\(\)\s\=\>\s(.*?)\"/g, (e) => {
		return e.substring(1, e.length - 1);
	});

	//  Format output
	output = await prettier.format(output, {
		parser: 'typescript',
		singleQuote: true,
		quoteProps: 'consistent',
		printWidth: 80,
		useTabs: false,
	});

	//  Save
	await fs.promises.writeFile(path.resolve(OUTDIR, filename), output);
	console.log(`- ${filename} generated`);

	// Generate file for package.json
	const packageFilename = `package.json`;
	const read = JSON.parse(await fs.promises.readFile(packageFilename, 'utf-8'));
	for (const font of filteredFonts) {
		if (!read.typesVersions) read.typesVersions = {};
		if (!read.typesVersions['>=1.0']) read.typesVersions['>=1.0'] = {};
		read.typesVersions['>=1.0'][removeWhitespace(unquote(font.family))] = [
			`dist/cjs/${removeWhitespace(unquote(font.family))}.d.ts`,
		];
	}

	await fs.promises.writeFile(
		packageFilename,
		JSON.stringify(read, null, '\t') + '\n',
	);
};

generate().catch((err) => {
	console.error(err);
	process.exit(1);
});
