import React, { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
import { GlyphIcon } from '@theorchard/suite-icons';
import cx from 'classnames';
import { Form } from 'react-bootstrap';
import { Tooltip } from '../tooltip';
import type { FormCheckProps } from 'react-bootstrap';

const CLASS_NAME = 'FormCheckbox';

export interface CheckboxProps extends Omit<FormCheckProps, 'type' | 'as'> {
    testId?: string;

    /**
     * An index to a corresponding data visualization color.
     * The checkbox will be colored accordingly if specified.
     */
    colorIndex?: number;

    /**
     * If true, shows the checkbox in indeterminate "-" state.
     */
    indeterminate?: boolean;

    /**
     * Show icon between checkbox and label
     */
    icon?: React.ReactNode;

    /**
     * Props for the tooltip
     */
    tooltip?: { size: 12 | 16; message: string; id?: string };

    /**
     * Can pass a custom color to the checkbox.
     */
    customColor?: string;

    /**
     * Replaces checkbox with padlock glyph, indicating the state is locked.
     */
    locked?: boolean;
}

/**
 * Checkboxes are square interactive UI elements used to turn an option on or off. They allow the user to select one or more items from a set.
 *
 * @type atom
 * @status live
 * @tags form-elements
 */
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
    (
        {
            colorIndex,
            className,
            checked,
            indeterminate,
            testId,
            tooltip,
            icon,
            customColor,
            locked,
            ...props
        },
        ref
    ) => {
        const innerRef = useRef<HTMLInputElement>(null);

        const tooltipId = tooltip?.id ?? props.id ?? 'checkbox-tooltip-id';
        const tooltipLabel = tooltip ? (
            <Tooltip id={tooltipId} message={tooltip.message}>
                <GlyphIcon name="info" size={tooltip.size} />
            </Tooltip>
        ) : null;

        const label = (icon || props.label || tooltipLabel) && (
            <>
                {icon}
                {props.label}
                {tooltipLabel}
            </>
        );

        const color =
            customColor ?? (colorIndex !== undefined ? `var(--data-${colorIndex})` : undefined);
        const colorCustomStyle = color
            ? ({
                  '--checkbox-base': color,
                  '--checkbox-hover': 'hsl(from var(--checkbox-base) h s calc(l - 10))',
              } as React.CSSProperties)
            : {};

        // Forward our inner ref to any parent refs.
        // The non-null assertion ( or casting ) is needed to overcome
        // a TS compat issue between forwardRef and inner ref types.
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        useImperativeHandle(ref, () => innerRef.current!, []);

        useEffect(() => {
            if (innerRef.current) innerRef.current.indeterminate = !!indeterminate;
        }, [indeterminate]);

        if (locked)
            return (
                <div
                    className={cx(CLASS_NAME, className, 'FormCheckbox form-check locked')}
                    data-testid={testId}
                    style={{ ...colorCustomStyle, ...props.style }}
                >
                    <GlyphIcon name="lock" size={16} />
                    {label && <label className="form-check-label">{label}</label>}
                </div>
            );

        return (
            <Form.Check
                {...props}
                label={label}
                ref={innerRef}
                checked={checked}
                data-testid={testId}
                className={cx(CLASS_NAME, className, {
                    checked,
                    indeterminate,
                })}
                style={{ ...colorCustomStyle, ...props.style }}
            />
        );
    }
);
