import { ServiceError } from "@grpc/grpc-js";
import { IronPdfServiceClient } from "../../generated_proto/ironpdfengineproto/IronPdfService";
import { Access } from "../../access";
import { StringDictionaryResultP__Output } from "../../generated_proto/ironpdfengineproto/StringDictionaryResultP";
import { handleEmptyResultP__Output, handleRemoteException } from "../util";
import {
	StringDictionaryFromProto,
	StringDictionaryToProto,
} from "./converter";
import { EmptyResultP__Output } from "../../generated_proto/ironpdfengineproto/EmptyResultP";

export async function getMetadataDict(
	id: string
): Promise<Map<string, string>> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise(
		(
			resolve: (_: Map<string, string>) => void,
			reject: (errorMsg: string) => void
		) => {
			client.Pdfium_Metadata_GetMetadataDict(
				{
					document: { documentId: id },
				},
				(
					err: ServiceError | null,
					value: StringDictionaryResultP__Output | undefined
				) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						if (value?.exception) {
							handleRemoteException(value.exception, reject);
						}
						resolve(StringDictionaryFromProto(value.result));
					}
				}
			);
		}
	);
}

export async function setMetadataDict(
	id: string,
	metadataDict: Map<string, string>
): Promise<void> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise(
		(resolve: () => void, reject: (errorMsg: string) => void) => {
			client.Pdfium_Metadata_SetMetadataDict(
				{
					document: { documentId: id },
					metadataDict: StringDictionaryToProto(metadataDict),
				},
				(
					err: ServiceError | null,
					value: EmptyResultP__Output | undefined
				) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handleEmptyResultP__Output(value, reject);
						resolve();
					}
				}
			);
		}
	);
}

export async function setMetadata(
	id: string,
	key: string,
	value: string
): Promise<void> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise(
		(resolve: () => void, reject: (errorMsg: string) => void) => {
			client.Pdfium_Metadata_SetMetadata(
				{
					document: { documentId: id },
					key: key,
					value: value,
				},
				(
					err: ServiceError | null,
					value: EmptyResultP__Output | undefined
				) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handleEmptyResultP__Output(value, reject);
						resolve();
					}
				}
			);
		}
	);
}

export async function removeMetadata(id: string, key: string): Promise<void> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise(
		(resolve: () => void, reject: (errorMsg: string) => void) => {
			client.Pdfium_Metadata_RemoveMetadata(
				{
					document: { documentId: id },
					key: key,
				},
				(
					err: ServiceError | null,
					value: EmptyResultP__Output | undefined
				) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handleEmptyResultP__Output(value, reject);
						resolve();
					}
				}
			);
		}
	);
}
