import React from "react";
import styled from "styled-components";
import { WidgetProps } from "@rjsf/core";
import Checkbox from "./Checkbox";

// See https://github.com/rjsf-team/react-jsonschema-form/blob/master/packages/core/src/components/widgets/CheckboxesWidget.js

const selectValue = (value, selected, all) => {
  const at = all.indexOf(value);
  const updated = selected.slice(0, at).concat(value, selected.slice(at));
  // As inserting values at predefined index positions doesn't work with empty
  // arrays, we need to reorder the updated selection to match the initial order
  return updated.sort((a, b) => all.indexOf(a) > all.indexOf(b));
};

const deselectValue = (value, selected) => selected.filter((v) => v !== value);

type CheckboxesProps = Omit<WidgetProps, "options"> & {
  options: Record<string, any>;
};

const CheckboxContainer = styled.div`
  margin-bottom: 1rem;
`;

const Checkboxes: React.FC<CheckboxesProps> = ({
  id, disabled, options, value, autofocus, readonly, onChange,
}) => {
  const { enumOptions, enumDisabled, inline } = options;
  return (
    <div className="checkboxes" id={id}>
      {enumOptions.map((option, index) => {
        const key = `${id}_${index}`;
        const checked = value.indexOf(option.value) !== -1;
        const itemDisabled = enumDisabled && enumDisabled.indexOf(option.value) !== -1;
        const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
        const checkbox = (
          <Checkbox
            id={key}
            checked={checked}
            disabled={disabled || itemDisabled || readonly}
            autoFocus={autofocus && index === 0}
            onChange={(event) => {
              const all = enumOptions.map(({ val }) => val);
              if (event.target.checked) {
                onChange(selectValue(option.value, value, all));
              } else {
                onChange(deselectValue(option.value, value));
              }
            }}
          >
            {option.label}
          </Checkbox>
        );
        return inline ? (
          <label key={key} className={`checkbox-inline ${disabledCls}`}>
            {checkbox}
          </label>
        ) : (
          <CheckboxContainer key={key} className={disabledCls}>
            {checkbox}
          </CheckboxContainer>
        );
      })}
    </div>
  );
};

Checkboxes.defaultProps = {
  autofocus: false,
  options: {
    inline: false,
  },
};

export default Checkboxes;
