'use client';

import { Typography } from '../../typography/typography';
import { InputLayout } from '../input-layout/input-layout';
import React, {
    ChangeEvent,
    forwardRef,
    HTMLProps,
    InputHTMLAttributes,
    useId,
    useLayoutEffect,
    useRef,
    useState,
} from 'react';

interface SliderProps extends InputHTMLAttributes<HTMLInputElement> {
    options?: number[];
}

function fractionCalc(current: number | string, max: number | string): number {
    const _current = isNaN(parseInt(current as string))
        ? 50
        : parseInt(current as string);
    const _max = isNaN(parseInt(max as string)) ? 100 : parseInt(max as string);

    return (_current / _max) * 100;
}

function gradientStyle(value: number): string {
    return `linear-gradient( to right, var(--md-sys-color-primary) ${value}%, var(--md-sys-color-surface-container-highest) ${value}%)`;
}

function setWebkitProgressSlider(
    element: SliderProps | HTMLProps<HTMLInputElement>,
    isChrome: boolean,
) {
    if (isChrome) {
        const initialFraction = fractionCalc(
            (element.value as string) ?? (element.defaultValue as string),
            element.max as string,
        );

        if (element.style === undefined) {
            element.style = {};
        }

        element.style.background = gradientStyle(initialFraction);
    }
}

export const Slider = forwardRef<HTMLInputElement, SliderProps>(
    ({ options, ...props }, ref) => {
        const sliderId = useId();
        const isChrome = useRef<boolean>(
            navigator.userAgent.indexOf('AppleWebKit') != -1,
        );
        const [value, setValue] = useState(props.defaultValue ?? 50);
        const [mounted, setMounted] = useState<boolean>(false);

        useLayoutEffect(() => {
            setMounted(true);
        }, []);

        if (!mounted) {
            return;
        }

        setWebkitProgressSlider(props, isChrome.current);

        return (
            <div className={'m3 m3-slider-container'}>
                <InputLayout
                    {...props}
                    className={props.className}
                    list={sliderId}
                    onChange={(event: ChangeEvent<HTMLInputElement>) => {
                        props.onChange?.apply(this, props?.onChange?.prototype);
                        setValue(event.target.value);
                        setWebkitProgressSlider(
                            event.target as unknown as HTMLProps<HTMLInputElement>,
                            isChrome.current,
                        );
                    }}
                    ref={ref}
                    style={{
                        ...props.style,
                        background: `linear-gradient(to right, var(--md-sys-color-primary) ${progress}%, var(--md-sys-color-surface-container-highest) ${progress}%)`,
                    }}
                    type={'range'}
                    typeInput={'slider'}
                />
                {options && (
                    <datalist id={sliderId}>
                        {options.map((option, index) => (
                            <option key={index} value={option} />
                        ))}
                    </datalist>
                )}
                <div className={'m3 m3-slider-label'}>
                    <Typography role={'label'} size={'small'}>
                        {value}
                    </Typography>
                </div>
            </div>
        );
    },
);
