"use client";
import classNames from "classnames";
import { forwardRef } from "react";
import style from "./textbox.module.css";

export type TextboxWidth = "80%" | "100%" | "50%" | "custom";
export type TextboxVariant = "solid" | "transparent" | "search";
export type TextboxIcon = "none" | "search";
export type TextboxType = "text" | "password" | "email" | "number" | "comments";

interface TextboxProps {
    name?: string;
    type: TextboxType;
    value: string;
    placeholder?: string;
    width?: TextboxWidth;
    variant?: TextboxVariant;
    icon?: TextboxIcon;
    onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
    onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
    onClick?: (e: React.MouseEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
    style?: React.CSSProperties;
    limitSize?: number | undefined;
}

const Textbox = forwardRef<HTMLInputElement | HTMLTextAreaElement, TextboxProps>((props, ref) => {
    const {
        width = "80%",
        variant = "solid",
        icon = "none",
        placeholder,
        type = "text",
        limitSize = undefined,
    } = props;

    /* eslint-disable @typescript-eslint/no-explicit-any */
    const getWidth = (base: any) => {
        if (width === "100%") {
            return classNames(base, style.textboxWidth100);
        } else if (width === "80%") {
            return classNames(base, style.textboxWidth80);
        } else if (width === "50%") {
            return classNames(base, style.textboxWidth50);
        }
        return classNames(base);
    };

    const getClassNames = () => {
        const classList: classNames.ArgumentArray = [];

        classList.push(style.textbox);

        if (variant === "transparent") {
            classList.push(style.textboxTransparent);
        } else if (variant === "solid") {
            classList.push(style.textboxSolid);
        } else if (variant === "search") {
            classList.push(style.textboxSearch);
        }

        if (width === "100%") {
            classList.push(style.textboxWidth100);
        } else if (width === "80%") {
            classList.push(style.textboxWidth80);
        } else if (width === "50%") {
            classList.push(style.textboxWidth50);
        }

        if (icon === "search") {
            classList.push(style.textboxIconSearch);
        } else if (icon === "none") {
            if (variant === "transparent") {
                classList.push(style.textboxIconNoneTransparent);
            } else {
                classList.push(style.textboxIconNoneSolid);
            }
        }

        return classNames(classList);
    };

    const calcRemaining = () => {
        if (limitSize) {
            return limitSize - props.value.length;
        }
        return 0;
    };

    return (
        <>
            {variant !== "search" && placeholder && (
                <div className={getWidth(style.textboxLabelContainer)}>
                    <div className={style.textboxLabel}>{placeholder}</div>
                    {limitSize && <span> [{calcRemaining()}]</span>}
                </div>
            )}

            {type === "comments" ? (
                <textarea
                    className={getClassNames()}
                    id={props.name}
                    onChange={props.onChange}
                    onKeyUp={props.onKeyUp}
                    onClick={props.onClick}
                    value={props.value}
                    style={props.style}
                    ref={ref as React.Ref<HTMLTextAreaElement>}
                    {...(limitSize && { maxLength: limitSize })}
                />
            ) : (
                <input
                    className={getClassNames()}
                    placeholder={variant === "search" ? placeholder : ""}
                    type={type}
                    id={props.name}
                    value={props.value}
                    onChange={props.onChange}
                    onKeyUp={props.onKeyUp}
                    onClick={props.onClick}
                    style={props.style}
                    ref={ref as React.Ref<HTMLInputElement>}
                    {...(limitSize && { maxLength: limitSize })}
                />
            )}
        </>
    );
});

Textbox.displayName = "Textbox";

export default Textbox;
