'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import {
    FormControl,
    isIndeterminate,
    FormControlDefaultProps,
    FormControlProps
} from './FormControl';
import {Checkbox} from 'react-bootstrap';

export type CheckboxControlProps = Checkbox.CheckboxProps & {
    removeName?: boolean;
} & FormControlProps &
    Partial<CheckboxControlDefaultProps>;

export type CheckboxControlDefaultProps = {
    testAutomationId: string;
    removeName: boolean;
} & FormControlDefaultProps;

type Value = boolean | null;

type ConverterOutput = {
    checked: Value;
};

export class CheckboxControl extends FormControl<
    CheckboxControlProps & React.HTMLProps<CheckboxControl>
> {
    static propTypes: any = {
        ...FormControl.propTypes,
        removeName: PropTypes.bool
    };

    static defaultProps = {
        ...FormControl.defaultProps,
        testAutomationId: 'checkbox',
        removeName: false
    };

    input: any;

    // @ts-ignore
    getValue(): Value {
        return this.getInputDOMNode().checked;
    }

    // @ts-ignore
    inputConverter(value: Value): ConverterOutput {
        return {checked: value};
    }

    // @ts-ignore
    outputConverter(e: React.ChangeEvent<HTMLInputElement>): Value {
        return e.target.checked;
    }

    getInputDOMNode(): HTMLInputElement {
        return this.input;
    }

    componentWillReceiveProps(newProps) {
        this.getInputDOMNode().indeterminate = isIndeterminate(newProps.checked);
    }

    componentDidMount() {
        this.componentWillReceiveProps(this.props);
        this.testAutomationIdHandler();
    }

    componentDidUpdate() {
        this.testAutomationIdHandler();
    }

    testAutomationIdHandler() {
        if (this.input && !this.props.hasFormGroupContainer) {
            this.input.parentNode.setAttribute(
                'data-test-automation-id',
                this.props.testAutomationId
            );
        }
    }

    render() {
        let {
            checked,
            readOnly,
            disabled,
            children,
            hiddenLabel,
            removeName,
            ...props
        } = this.getPropsFromContext() as any;

        return (
            <Checkbox
                disabled={readOnly || disabled}
                checked={checked}
                inputRef={ref => (this.input = ref)}
                data-test-automation-id="input"
                {...this.getSafeProps(props)}
                name={removeName ? null : props.name}>
                <span data-test-automation-id="label" className={!!hiddenLabel ? 'sr-only' : ''}>
                    {children}
                </span>
            </Checkbox>
        );
    }
}
