import { useInputState } from "@common/hooks/useInputState";
import { useState } from "preact/hooks";
import styles from "../../assets/settings-modal.module.css";
import { DEFAULT_GENERATION_SETTINGS, type GenerationSettings, useAppState } from "../../contexts/state";

type NumericKey = keyof GenerationSettings;

interface ParamConfig {
    key: NumericKey;
    label: string;
    min: number;
    max: number;
    step: number;
}

const PARAMS: ParamConfig[] = [
    { key: "temperature", label: "Temperature", min: 0, max: 4, step: 0.01 },
    { key: "top_p", label: "Top P", min: 0, max: 1, step: 0.01 },
    { key: "top_k", label: "Top K", min: 0, max: 200, step: 1 },
    { key: "min_p", label: "Min P", min: 0, max: 1, step: 0.01 },
    { key: "repetition_penalty", label: "Repetition Penalty", min: 1, max: 3, step: 0.01 },
    { key: "frequency_penalty", label: "Frequency Penalty", min: -2, max: 2, step: 0.01 },
];

function ParamRow({ config, initialValue, onChange }: {
    config: ParamConfig;
    initialValue: number;
    onChange: (key: NumericKey, value: number) => void;
}) {
    const [draft, setDraft] = useInputState(String(initialValue));

    const commit = () => {
        const parsed = parseFloat(draft);
        if (!isNaN(parsed)) {
            onChange(config.key, parsed);
        }
    };

    return (
        <div class={styles.formGroup}>
            <label class={styles.label}>
                {config.label}
                <span class={styles.labelHint}>
                    (default: {DEFAULT_GENERATION_SETTINGS[config.key]})
                </span>
            </label>
            <input
                type="number"
                value={draft}
                min={config.min}
                max={config.max}
                step={config.step}
                class={styles.input}
                onInput={setDraft}
                onBlur={commit}
                onKeyDown={(e) => e.key === "Enter" && commit()}
            />
        </div>
    );
}

export const SamplingSettings = () => {
    const { generationSettings, dispatch } = useAppState();
    const [resetKey, setResetKey] = useState(0);

    const handleChange = (key: NumericKey, value: number) => {
        dispatch({ type: "SET_GENERATION_SETTINGS", settings: { [key]: value } });
    };

    const handleReset = () => {
        dispatch({ type: "SET_GENERATION_SETTINGS", settings: DEFAULT_GENERATION_SETTINGS });
        setResetKey(k => k + 1);
    };

    return (
        <div class={styles.form}>
            {PARAMS.map(config => (
                <ParamRow
                    key={`${config.key}-${resetKey}`}
                    config={config}
                    initialValue={generationSettings[config.key]}
                    onChange={handleChange}
                />
            ))}
            <div>
                <button class={styles.buttonSecondary} onClick={handleReset}>
                    Reset to defaults
                </button>
            </div>
        </div>
    );
};
