'use client';

import clsx from 'clsx';
import { motion } from 'framer-motion';
import { Refresh } from 'iconsax-react';
import React, { useEffect, useRef, useState } from 'react';

type Props = {
    className?: ToggleButtonClassName;
    pending?: boolean;
    defaultChecked?: boolean;
    onToggle?: (checked: boolean) => void;
    name: string; // required for form data
    children?: React.ReactNode;
    disabled?: boolean;
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'className' | 'onClick' | 'type'>;

export type ToggleButtonClassName = {
    wrapper?: string;
    wrapperDeactive?: string;
    wrapperActive?: string;
    wrapperDisabled?: string;
    wrapperEnabled?: string;
    wrapperPending?: string;
    icon?: string;
    iconDeactive?: string;
    iconActive?: string;
    content?: string;
    contentDeactive?: string;
    contentActive?: string;
};

export const ToggleButtonClassNames: ToggleButtonClassName = {
    wrapper:
        'relative transition-all border border-solid duration-200 cursor-pointer w-full rounded-normal p-3 font-normal text-sm overflow-clip',
    wrapperDeactive: 'bg-container border-neutral-200 dark:border-neutral-500',
    wrapperActive: 'border-[#439C46]',
    wrapperDisabled: 'bg-disabled text-disabled-text',
    wrapperEnabled: 'bg-container text-white hover:bg-gray-100 dark:hover:bg-neutral-700 active:brightness-110',
    wrapperPending: 'bg-transparent text-transparent cursor-auto',
    content: 'text-xs transition-all duration-150',
    contentDeactive: 'text-foreground',
    contentActive: 'text-[#439C46]',
};

function ToggleButton({
    className = ToggleButtonClassNames,
    disabled = false,
    pending = false,
    defaultChecked = false,
    onToggle,
    name,
    children,
    ...rest
}: Props) {
    const [checked, setChecked] = useState(defaultChecked);
    const inputRef = useRef<HTMLInputElement>(null);

    const handleClick = () => {
        if (disabled || pending) return;
        const newChecked = !checked;
        setChecked(newChecked);
        onToggle?.(newChecked);
    };

    useEffect(() => {
        const form = inputRef.current?.form;
        if (!form) return;

        const onReset = () => setChecked(defaultChecked);
        form.addEventListener('reset', onReset);
        return () => form.removeEventListener('reset', onReset);
    }, [defaultChecked]);


    return (
        <>
            <input
                type="checkbox"
                name={name}
                checked={checked}
                readOnly
                hidden
                ref={inputRef}
            />

            <button
                type="button"
                disabled={disabled}
                onClick={handleClick}
                className={clsx(
                    className.wrapper,
                    disabled ? className.wrapperDisabled : className.wrapperEnabled,
                    pending && className.wrapperPending,
                    checked ? className.wrapperActive : className.wrapperDeactive
                )}
                {...rest}
            >
                {pending && (
                    <motion.div
                        className="absolute left-0 top-0 h-full w-full bg-neutral-200 "
                        initial={{ y: '100%' }}
                        animate={{ y: 0 }}
                    >
                        <motion.div
                            animate={{ rotateZ: [0, 360] }}
                            transition={{ duration: 1.2, repeat: Infinity, ease: 'linear' }}
                            whileHover={{ scale: 1.1 }}
                            whileTap={{ scale: 0.9 }}
                            className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
                        >
                            <Refresh className="stroke-primary" size={24} />
                        </motion.div>
                    </motion.div>
                )}

                <span
                    className={clsx(
                        className.content,
                        disabled || !checked ? className.contentDeactive : className.contentActive
                    )}
                >
                    {children}
                </span>
            </button>
        </>
    );
}

export default ToggleButton;
