import { z } from "zod"
import {
	HorizontalAlignment,
	VerticalAlignment,
	CssMediaType,
	FitToPaperModes,
	MeasurementUnit,
	UseMargins,
	ChromeGpuModes,
	ChangeTrackingModes,
	HtmlString,
	HtmlFilePath,
	ZipFilePath,
	PdfFilePath,
	UrlString,
	BarcodeType,
	PdfPageSelection,
	SaveOptions, Length, CropRectangle, MarginConfig, ImageFilePath, ImageBuffer, PdfPassword, PdfInput
} from "../../public/types"
import {pdfDocumentSchema} from "./pdfDocumentSchema";
import {Buffer} from "buffer";

export const horizontalAlignmentSchema: z.ZodType<HorizontalAlignment> = z.nativeEnum(HorizontalAlignment)

export const verticalAlignmentSchema: z.ZodType<VerticalAlignment> = z.nativeEnum(VerticalAlignment)

export const cssMediaTypeSchema: z.ZodType<CssMediaType> = z.nativeEnum(CssMediaType)

export const fitToPaperModesSchema: z.ZodType<FitToPaperModes> = z.nativeEnum(FitToPaperModes)

export const pdfPageSelectionSchema: z.ZodType<PdfPageSelection> = z.union([
	z.number(),
	z.array(z.number()),
	z.literal("all"),
	z.undefined()
])

export const measurementUnitSchema: z.ZodType<MeasurementUnit> = z.nativeEnum(MeasurementUnit)

export const saveOptionsSchema: z.ZodType<SaveOptions> = z.object({
	userPassword: z.string().optional(),
	ownerPassword: z
		.string()
		.optional(),
	saveAsPdfA: z
		.boolean()
		.optional(),
	incremental: z
		.boolean()
		.optional()
})

export const lengthSchema: z.ZodType<Length> = z.object({
	value: z.number(),
	unit: measurementUnitSchema
})

export const cropRectangleSchema: z.ZodType<CropRectangle> = z.object({
	x: z.number().optional(),
	y: z.number().optional(),
	width: z.number().optional(),
	height: z.number().optional()
})

export const marginConfigSchema: z.ZodType<MarginConfig> = z.object({
	default: z.number().optional(),
	top: z.number().optional(),
	right: z.number().optional(),
	bottom: z.number().optional(),
	left: z.number().optional()
})

export const filePathSchema: z.ZodType<string> = z.string()

export const pdfFilePathSchema: z.ZodType<PdfFilePath> = z.string()

export const zipFilePathSchema: z.ZodType<ZipFilePath> = z.string()

export const htmlStringSchema: z.ZodType<HtmlString> = z.string()

export const htmlFilePathSchema: z.ZodType<HtmlFilePath> = z.string()

export const urlStringSchema: z.ZodType<UrlString> = z.string()

export const stringSchema: z.ZodType<string> = z.string()

export const urlSchema: z.ZodType<URL> = z.instanceof(URL)

export const imageFilePathSchema: z.ZodType<ImageFilePath> = z.string()

export const bufferSchema: z.ZodType<Buffer> = z.instanceof(Buffer)

export const imageBufferSchema: z.ZodType<ImageBuffer> = bufferSchema

export const useMarginsSchema: z.ZodType<UseMargins> = z.nativeEnum(UseMargins)

export const pdfPasswordSchema: z.ZodType<PdfPassword> = z.object({
	userPassword: z.string().optional(),
	ownerPassword: z.string().optional()
})

export const chromeGpuModesSchema: z.ZodType<ChromeGpuModes> = z.nativeEnum(ChromeGpuModes)

export const changeTrackingModesSchema: z.ZodType<ChangeTrackingModes> = z.nativeEnum(ChangeTrackingModes)

export const pdfInputSchema: z.ZodType<PdfInput> = z.union([pdfDocumentSchema,bufferSchema,htmlStringSchema,htmlFilePathSchema,zipFilePathSchema,pdfFilePathSchema,urlSchema,urlStringSchema])

export const dateSchema: z.ZodType<Date> = z.instanceof(Date)

export const barcodeTypeSchema: z.ZodType<BarcodeType> = z.nativeEnum(BarcodeType)

export const stringArraySchema: z.ZodType<string[]> = z.array(z.string())

export const bufferArraySchema: z.ZodType<Buffer[]> = z.array(bufferSchema)

export const numberSchema: z.ZodType<number> = z.number()

export const booleanSchema: z.ZodType<boolean> = z.boolean()

export const mapStringSchema: z.ZodType<Map<string,string>> = z.map(z.string(),z.string())
