import type { Attachment } from "@root/model/attachment"

type ReadFileFormat = "text" | "url" | "array" | "binary";

type ReadFileOption<T extends ReadFileFormat> = T extends "text" | "url"
  ? Promise<string>
  : T extends "array"
  ? Promise<ArrayBuffer>
  : T extends "binary"
  ? Promise<Attachment>
  : Promise<null>;

export const readFile = <T extends ReadFileFormat>(
	file: File,
	format?: T
): ReadFileOption<T> => <ReadFileOption<T>>new Promise((resolve, reject) => {
	const reader = new FileReader()

	switch (format) {
	case "text":
		reader.readAsText(file)
		break

	case "url":
		reader.readAsDataURL(file)
		break

	case "array":
		reader.readAsArrayBuffer(file)
		break

	case "binary":
		reader.readAsBinaryString(file)
		break

	default:
		reader.readAsText(file)
		break
	}

	reader.onload = (): void => {
		if (!reader.result) {
			return reject(new Error("File is empty"))
		}

		if (format === "binary") {
			return resolve({
				name: file.name,
				content: reader.result as "string",
				mimetype: file.type,
			})
		}

		return resolve(reader.result)
	}

	reader.onerror = (): void => reject(new Error("Data conversion error"))
})
