import React, { ChangeEvent, FC, useRef } from "react";

import "./button.css";

type ButtonProps = {
    text: string;
    image?: string;
    imageAlt?: string;
    enabled?: boolean;
    focusable?: boolean;
    file?: boolean;
    accept?: string;
    size?: string;
    style?: string[];
    onClick?: () => void;
    onFile?: (file: File) => void;
};

export const Button: FC<ButtonProps> = ({
    text,
    image,
    imageAlt,
    enabled = false,
    focusable = true,
    file = false,
    accept = ".txt",
    size = "small",
    style = ["simple", "border"],
    onClick,
    onFile
}) => {
    const classes = () =>
        [
            "button",
            size,
            enabled ? "enabled" : "",
            file ? "file" : "",
            ...style
        ].join(" ");
    const fileRef = useRef<HTMLInputElement>(null);
    const onFileChange = (event: ChangeEvent<HTMLInputElement>) => {
        if (!event.target.files) return;
        if (event.target.files.length === 0) return;
        const file = event.target.files[0];
        onFile && onFile(file);
        event.target.value = "";
    };
    const onMouseDown = (event: React.MouseEvent) => {
        event.stopPropagation();
        event.preventDefault();
    };
    const onMouseUp = (event: React.MouseEvent) => {
        event.stopPropagation();
        event.preventDefault();
    };
    const onKeyPress = (event: React.KeyboardEvent) => {
        if (event.key !== "Enter") return;
        if (file) fileRef.current?.click();
        onClick && onClick();
    };
    const renderSimple = () => (
        <span
            className={classes()}
            onClick={onClick}
            onKeyPress={onKeyPress}
            tabIndex={focusable ? 0 : undefined}
        >
            {text}
        </span>
    );
    const renderComplex = () => (
        <span
            className={classes()}
            onClick={onClick}
            onMouseDown={onMouseDown}
            onMouseUp={onMouseUp}
            onKeyPress={onKeyPress}
            tabIndex={focusable ? 0 : undefined}
        >
            {image && <img src={image} alt={imageAlt ?? text ?? "button"} />}
            {file && (
                <input
                    ref={fileRef}
                    type="file"
                    accept={accept}
                    onChange={onFileChange}
                />
            )}
            <span>{text}</span>
        </span>
    );
    return image ? renderComplex() : renderSimple();
};

export default Button;