import {
	Plugin,
	PropPanel,
	DEFAULT_FONT_NAME,
	getFallbackFontName,
	PropPanelSchema,
	PropPanelWidgetProps,
} from "@pdfme/common";
import { text } from "@pdfme/schemas";
import type { TextSchema } from "@pdfme/schemas/dist/types/src/text/types";

import {
	DEFAULT_FONT_SIZE,
	DEFAULT_ALIGNMENT,
	DEFAULT_VERTICAL_ALIGNMENT,
	DEFAULT_CHARACTER_SPACING,
	DEFAULT_LINE_HEIGHT,
	VERTICAL_ALIGN_TOP,
	VERTICAL_ALIGN_MIDDLE,
	VERTICAL_ALIGN_BOTTOM,
	DEFAULT_FONT_COLOR,
	DYNAMIC_FIT_VERTICAL,
	DYNAMIC_FIT_HORIZONTAL,
	DEFAULT_DYNAMIC_FIT,
	DEFAULT_DYNAMIC_MIN_FONT_SIZE,
	DEFAULT_DYNAMIC_MAX_FONT_SIZE,
	ALIGN_RIGHT,
	ALIGN_CENTER,
	DEFAULT_OPACITY,
	HEX_COLOR_PATTERN,
} from "./constants";
import {
	GebaeudeStammdaten,
	Rechnungen,
} from "@ibcornelsen/database/client";
import { VerbrauchsausweisWohnenClient } from "#components/Ausweis/types";
import { zodGetKeys } from "#lib/helpers/zod";
import { verbrauchsausweisWohnenPDFValidator } from "#lib/validators/verbrauchsausweis-wohnen-pdf-validator";

const UseDynamicFontSize = (props: PropPanelWidgetProps) => {
	const { rootElement, changeSchemas, activeSchema, i18n } = props;

	const checkbox = document.createElement("input");
	checkbox.type = "checkbox";
	checkbox.checked = Boolean((activeSchema as any)?.dynamicFontSize);
	checkbox.onchange = (e: any) => {
		const val = e.target.checked
			? {
					min: DEFAULT_DYNAMIC_MIN_FONT_SIZE,
					max: DEFAULT_DYNAMIC_MAX_FONT_SIZE,
					fit: DEFAULT_DYNAMIC_FIT,
			  }
			: undefined;
		changeSchemas([
			{ key: "dynamicFontSize", value: val, schemaId: activeSchema.id },
		]);
	};
	const label = document.createElement("label");
	label.innerText = i18n("schemas.text.dynamicFontSize") || "";
	label.style.cssText = "display: flex; width: 100%;";
	label.appendChild(checkbox);
	rootElement.appendChild(label);
};

type AusweisIndex = keyof Omit<Omit<VerbrauchsausweisWohnenClient, "gebaeude_aufnahme_allgemein">, "rechnungen">
| `gebaeude_aufnahme_allgemein.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]}`
| `gebaeude_aufnahme_allgemein.gebaeude_stammdaten.${keyof VerbrauchsausweisWohnenClient["gebaeude_aufnahme_allgemein"]["gebaeude_stammdaten"]}`
| `rechnungen.${keyof Rechnungen}`;

const ausweisKeys = zodGetKeys(verbrauchsausweisWohnenPDFValidator);

const variableOptions: {
	label: string;
	value: AusweisIndex;
}[] = ausweisKeys.map((key: AusweisIndex) => ({ label: key as string, value: key }));

interface VariableSchema extends TextSchema {
	variable: AusweisIndex | undefined
}

const propPanel: PropPanel<VariableSchema> = {
	schema: ({ options, activeSchema, i18n }) => {
		const font = options.font || {
			[DEFAULT_FONT_NAME]: { data: "", fallback: true },
		};
		const fontNames = Object.keys(font);
		const fallbackFontName = getFallbackFontName(font);

		const enableDynamicFont = Boolean(
			(activeSchema as any)?.dynamicFontSize
		);

		const textSchema: Record<string, PropPanelSchema> = {
			variable: {
				title: "Variable",
				type: "string",
				widget: "select",
				props: { options: variableOptions },
				span: 24,
			},
			fontName: {
				title: i18n("schemas.text.fontName"),
				type: "string",
				widget: "select",
				default: fallbackFontName,
				props: {
					options: fontNames.map((name) => ({
						label: name,
						value: name,
					})),
				},
				span: 12,
			},
			fontSize: {
				title: i18n("schemas.text.size"),
				type: "number",
				widget: "inputNumber",
				span: 6,
				disabled: enableDynamicFont,
			},
			characterSpacing: {
				title: i18n("schemas.text.spacing"),
				type: "number",
				widget: "inputNumber",
				span: 6,
			},
			alignment: {
				title: i18n("schemas.text.textAlign"),
				type: "string",
				widget: "select",
				props: {
					options: [
						{
							label: i18n("schemas.left"),
							value: DEFAULT_ALIGNMENT,
						},
						{ label: i18n("schemas.center"), value: ALIGN_CENTER },
						{ label: i18n("schemas.right"), value: ALIGN_RIGHT },
					],
				},
				span: 8,
			},
			verticalAlignment: {
				title: i18n("schemas.text.verticalAlign"),
				type: "string",
				widget: "select",
				props: {
					options: [
						{
							label: i18n("schemas.top"),
							value: VERTICAL_ALIGN_TOP,
						},
						{
							label: i18n("schemas.middle"),
							value: VERTICAL_ALIGN_MIDDLE,
						},
						{
							label: i18n("schemas.bottom"),
							value: VERTICAL_ALIGN_BOTTOM,
						},
					],
				},
				span: 8,
			},
			lineHeight: {
				title: i18n("schemas.text.lineHeight"),
				type: "number",
				widget: "inputNumber",
				props: {
					step: 0.1,
				},
				span: 8,
			},
			useDynamicFontSize: {
				type: "boolean",
				widget: "UseDynamicFontSize",
				bind: false,
				span: 16,
			},
			dynamicFontSize: {
				type: "object",
				widget: "card",
				column: 3,
				properties: {
					min: {
						title: i18n("schemas.text.min"),
						type: "number",
						widget: "inputNumber",
						hidden: !enableDynamicFont,
					},
					max: {
						title: i18n("schemas.text.max"),
						type: "number",
						widget: "inputNumber",
						hidden: !enableDynamicFont,
					},
					fit: {
						title: i18n("schemas.text.fit"),
						type: "string",
						widget: "select",
						hidden: !enableDynamicFont,
						props: {
							options: [
								{
									label: i18n("schemas.horizontal"),
									value: DYNAMIC_FIT_HORIZONTAL,
								},
								{
									label: i18n("schemas.vertical"),
									value: DYNAMIC_FIT_VERTICAL,
								},
							],
						},
					},
				},
			},
			fontColor: {
				title: i18n("schemas.textColor"),
				type: "string",
				widget: "color",
				rules: [
					{
						pattern: HEX_COLOR_PATTERN,
						message: i18n("hexColorPrompt"),
					},
				],
			},
			backgroundColor: {
				title: i18n("schemas.bgColor"),
				type: "string",
				widget: "color",
				rules: [
					{
						pattern: HEX_COLOR_PATTERN,
						message: i18n("hexColorPrompt"),
					},
				],
			},
		};

		return textSchema;
	},
	widgets: { UseDynamicFontSize },
	defaultValue: "Type Something...",
	defaultSchema: {
		type: "variable",
		position: { x: 0, y: 0 },
		width: 45,
		height: 10,
		rotate: 0,
		alignment: DEFAULT_ALIGNMENT,
		verticalAlignment: DEFAULT_VERTICAL_ALIGNMENT,
		fontSize: DEFAULT_FONT_SIZE,
		lineHeight: DEFAULT_LINE_HEIGHT,
		characterSpacing: DEFAULT_CHARACTER_SPACING,
		dynamicFontSize: undefined,
		fontColor: DEFAULT_FONT_COLOR,
		fontName: undefined,
		backgroundColor: "",
		opacity: DEFAULT_OPACITY,
		variable: undefined
	}
};

export const variable: Plugin<VariableSchema> = {
	ui: function(props) {
		// Wir binden die inputs auf dieses Element, damit wir die Werte später auslesen können.
		if (props.schema.variable && this) {
			props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
		}
		return text.ui(props);
	},
	pdf: (props) => {
		if (props.schema.variable && this) {
			props.value = (this as unknown as Record<string, string>)[props.schema.variable] as string;
		}
		text.pdf(props);
	},
	propPanel,
};
