import React, { useEffect, useState } from "react";
import {
	materialRenderers,
	materialCells
	// @ts-ignore
} from "@jsonforms/material-renderers";
// @ts-ignore
import { JsonForms, JsonFormsCore } from "@jsonforms/react";
import { useCloudUiProvider } from "../Providers";
import { twMerge } from "tailwind-merge";
import TextInputControl, {
	textControlTester,
	numberControlTester
} from "./renderers/TextInputControl";
import SelectInputControl, {
	singleSelectControlTester,
	multiSelectControlTester
} from "./renderers/SelectInputControl";
import DateTimeInputControl, {
	dateControlTester,
	timeControlTester,
	dateTimeControlTester
} from "./renderers/DateTimeInputControl";

const API_ENDPOINT = "https://cloud-ui-ishbaid.vercel.app/api/forms";
const FASTGEN_ENDPINT = "https://cloudui.fastgenapp.com/forms";

const renderers = [
	...materialRenderers,
	//register custom renderers
	{
		tester: textControlTester,
		renderer: TextInputControl
	},
	{
		tester: singleSelectControlTester,
		renderer: SelectInputControl
	},
	{
		tester: dateControlTester,
		renderer: DateTimeInputControl
	},
	{
		tester: timeControlTester,
		renderer: DateTimeInputControl
	},
	{
		tester: dateTimeControlTester,
		renderer: DateTimeInputControl
	},
	{
		tester: numberControlTester,
		renderer: TextInputControl
	},
	{
		tester: multiSelectControlTester,
		renderer: SelectInputControl
	}
];

export const CloudForm = ({
	id,
	onChange,
	onCtaClick,
	defaultValues,
	isDraft = false
}: {
	id: string;
	onChange?: (state: Pick<JsonFormsCore, "data" | "errors">) => void;
	onCtaClick?: () => void;
	defaultValues?: any;
	isDraft?: boolean;
}) => {
	const [formSchema, setFormSchema] = useState(null);
	const [uiSchema, setUiSchema] = useState(null);
	const [initialData, setInitialData] = useState(defaultValues ?? null);
	const [formResponse, setFormResponse] = useState(null);
	const [cta, setCta] = useState(null);
	const { apiKey, user } = useCloudUiProvider();
	const [hasSubmitted, setHasSubmitted] = useState(false);

	const buttonColor = formSchema?.settings?.color ?? "#4F46E5";

	useEffect(() => {
		fetchFormData();
	}, []);

	const handleChange = (state: Pick<JsonFormsCore, "data" | "errors">) => {
		if (onChange) {
			onChange(state);
		}
		setFormResponse(state.data);
	};

	const handleCtaClick = async () => {
		if (onCtaClick) {
			onCtaClick();
		}
		await fetch(FASTGEN_ENDPINT + "/" + id + "/responses", {
			method: "POST",
			body: JSON.stringify({
				responseData: formResponse,
				apiKey,
				user: user ?? null
			})
		});
		setHasSubmitted(true);
	};

	const fetchFormData = async () => {
		const response = await fetch(API_ENDPOINT + "/" + id, {
			headers: new Headers({
				"X-Api-Key": apiKey
			})
		});
		let data = (await response.json()).form;
		if (isDraft) {
			data = data.draft;
		}
		if (Object.hasOwnProperty.call(data, "formSchema")) {
			setFormSchema(data.formSchema);
		}
		if (Object.hasOwnProperty.call(data, "uiSchema")) {
			setUiSchema(data.uiSchema);
		}
		if (Object.hasOwnProperty.call(data, "defaultValues")) {
			setInitialData(data.defaultValues);
		}
		if (Object.hasOwnProperty.call(data, "cta")) {
			setCta(data.cta);
		}
	};
	return formSchema ? (
		<>
			<JsonForms
				schema={formSchema}
				uischema={uiSchema}
				data={initialData}
				renderers={renderers}
				cells={materialCells}
				onChange={handleChange}
			/>
			{cta && (
				<div className="flex flex-col">
					<button
						disabled={hasSubmitted}
						type="button"
						className={twMerge(
							"self-end rounded-md bg-indigo-600 my-2 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600",
							hasSubmitted && "bg-gray-400 hover:bg-gray-400"
						)}
						style={{ backgroundColor: buttonColor }}
						onClick={handleCtaClick}>
						{!hasSubmitted ? cta.primary.label : "Submitted"}
					</button>
				</div>
			)}
		</>
	) : (
		<div>Loading...</div>
	);
};
