import { Dictionary } from "lodash";
import React from "react";
import { SPACE_BETWEEN_HORIZONTALLY } from "../../../utils/styles";
import Select from "../Select/Select";

export type formInput = {
	name: string;
	label: string;
	validationMessage: string;
	inputProps: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
	options?: Dictionary<string>;
};

export type FormProps = {
	onSubmitForm: (fields: Dictionary<any>) => void;
	submitFormButtonText: string;
	submitFormButtonColor?: string;
	formInputs: formInput[];
};

type FormState = {
	fields: Dictionary<any>;
};

// Generates a Form Message for every invalid matcher. This is used instead of manually creating
// a Form Message for every invalid case.
// function formMessageMatchAll(message: string) {
// 	const invalidMatchers: ReactForm.ValidityMatcher[] = [
// 		"badInput",
// 		"patternMismatch",
// 		"rangeOverflow",
// 		"rangeUnderflow",
// 		"stepMismatch",
// 		"tooLong",
// 		"tooShort",
// 		"typeMismatch",
// 		"valueMissing"
// 	];

// 	return invalidMatchers.map((matcher) => (
// 		<div key={"match-" + matcher} className="FormMessage">
// 			{message}
// 		</div>
// 	));
// }

export default class Form extends React.Component<FormProps, FormState> {
	clickedButtonName = "";

	constructor(props: FormProps | Readonly<FormProps>) {
		super(props);

		// initialize state from defaultValues provided
		const fields: { [index: string]: any } = {};

		props.formInputs.forEach((formInput) => {
			if (formInput.inputProps.defaultValue) fields[formInput.name] = formInput.inputProps.defaultValue;
		});

		this.state = { fields };
	}

	handleFormInput = (event: React.ChangeEvent<HTMLInputElement>) => {
		const { name, value } = event.target;
		const fields = this.state.fields;
		this.setState({ fields: { ...fields, ...{ [name]: value } } });
	};

	onSubmit = (event: any) => {
		event.preventDefault();
		if (this.clickedButtonName == this.props.submitFormButtonText) this.props.onSubmitForm(this.state.fields);
	};

	handleClick = (event: any) => {
		this.clickedButtonName = event.target.name;
	};

	render() {
		// console.log("new Form state: " + JSON.stringify(this.state, null, 4))

		const { formInputs, submitFormButtonText, submitFormButtonColor } = this.props;

		return (
			<form className="FormRoot" onSubmit={this.onSubmit}>
				{formInputs.map((formInput) => {
					return (
						<div key={formInput.name} className="FormField">
							{/* Range Input additional label */}
							{formInput.inputProps.type && formInput.inputProps.type === "range" ? (
								<label className="FormLabel">
									{formInput.label} Slider:
									<em style={{ color: "grey" }}>
										{this.state.fields[formInput.name] || formInput.inputProps.defaultValue || 1}
									</em>
								</label>
							) : (
								<span style={{ color: "#494F55" }}>{formInput.label}</span>
							)}

							{/* Validations */}
							{/* {formMessageMatchAll(formInput.validationMessage)} */}

							{/* Input */}
							<span>
								{formInput.options !== undefined ? (
									<Select
										values={formInput.options}
										defaultValue={Object.keys(formInput.options)[0]}
										onUpdate={(value) => {
											const fields = this.state.fields;
											this.setState({ fields: { ...fields, ...{ [formInput.name]: value } } });
										}}
										triggerStyle={{ ...SPACE_BETWEEN_HORIZONTALLY, width: "100%", }}
									/>
								) : (
									<input
										className="Input"
										name={formInput.name}
										onChange={this.handleFormInput}
										{...formInput.inputProps}
									/>
								)}
							</span>
						</div>
					);
				})}
				<div style={{ display: "flex", marginTop: 25 }}>
					<div style={{ marginRight: 25 }}>
						<button
							className={`Button ${submitFormButtonColor || "green"}`}
							name={submitFormButtonText}
							onClick={this.handleClick}
						>
							{submitFormButtonText}
						</button>
					</div>
				</div>
			</form>
		);
	}
}
