import {ActionDispatch, FormEvent, useState} from 'react';
import {
    Action,
    actionLoadedMaze,
    actionLoadingFailed,
    actionStartedLoading,
    actionToggledShowSolution
} from "./state/action.ts";
import styles from "./input-form.module.scss";
import "./input-form.scss";
import {State} from "./state/state.ts";
import {ValidatingInputNumberField, ValidatingInputRegExpField, ValidatorFunction} from "./validating-input-field.tsx";

export default function InputForm({state, dispatch}: {
    state: State,
    dispatch: ActionDispatch<[Action]>
}) {
    const [width, setWidth] = useState(10);
    const [height, setHeight] = useState(10);
    const [id, setId] = useState<string>();
    const [algorithm, setAlgorithm] = useState('wilson');

    const handleSubmit = (e: FormEvent) => {
        e.preventDefault();
        dispatch(actionStartedLoading());
        dispatch(actionToggledShowSolution(false));
        const url = `https://manuel.friedli.info/labyrinth/create/json?w=${width}&h=${height}&id=${id || ''}&algorithm=${algorithm}`;
        fetch(url)
            .then(response => response.json())
            .then(result => {
                dispatch(actionLoadedMaze(result));
            })
            .catch(reason => {
                console.error("Failed to fetch maze data.", reason);
                dispatch(actionLoadingFailed(reason));
            });
    };
    const validateSizeInput: ValidatorFunction<string, number> = (value: string) => {
        const numberValue = Number(value);
        if (isNaN(numberValue) || "" === value || (Math.floor(numberValue) !== numberValue)) {
            return {
                valid: false,
                message: "Must be an integer greater than 1."
            };
        }
        if (numberValue < 1) {
            return {
                valid: false,
                message: "Must be greater than 1."
            };
        }
        return {
            valid: true,
            value: numberValue
        };
    };
    return (
        <form onSubmit={handleSubmit}>
            <div className={styles.inputform}>
                <ValidatingInputNumberField id={"width"}
                                            label={"Width"}
                                            value={width}
                                            constraints={{
                                                min: 2
                                            }}
                                            validatorFn={validateSizeInput}
                                            disabled={state.loading}
                                            onChange={setWidth}
                />
                <ValidatingInputNumberField id={"height"}
                                            label={"Height"}
                                            value={height}
                                            constraints={{
                                                min: 2
                                            }}
                                            validatorFn={validateSizeInput}
                                            disabled={state.loading}
                                            onChange={setHeight}
                />
                {/*<ValidatingInputBigIntField id={"id"}*/}
                {/*                            label={"ID (optional)"}*/}
                {/*                            value={id}*/}
                {/*                            validatorFn={validateIdInput}*/}
                {/*                            disabled={state.loading}*/}
                {/*                            onChange={setId}*/}
                {/*                            constraints={{*/}
                {/*                                min: -9223372036854775808n,*/}
                {/*                                max: 9223372036854775807n*/}
                {/*                            }}*/}
                {/*/>*/}
                <ValidatingInputRegExpField id={"id"}
                                            label={"ID (optional)"}
                                            value={id}
                                            disabled={state.loading}
                                            onChange={setId}
                                            constraints={[
                                                /^[0-9a-fA-F]{0,16}$/
                                            ]}
                                            placeholder={"Hex-Number (without 0x prefix)"}
                />
                <label htmlFor="algorithm">Algorithm:</label>
                <select id={"algorithm"}
                        value={algorithm}
                        disabled={state.loading}
                        onChange={e => setAlgorithm(e.target.value)}>
                    <option value="wilson">Wilson</option>
                    <option value="random">Random Depth First</option>
                </select>
            </div>
            <button type={"submit"}
                    disabled={state.loading
                        || isNaN(width)
                        || isNaN(height)
                    }
                    className={styles.submitbutton}>{state.loading ? "Loading ..." : "Create Maze!"}
            </button>
        </form>
    );
}
