import React, { useState } from 'react';
import { Div, Label } from '@cloudflare/elements';
import { createStyledComponent } from '@cloudflare/style-container';
import Checkbox from './Checkbox';
import Error from './Error';
import { useRenderOnResize } from '@cloudflare/util-hooks';

type FormCheckboxesProps<ValueType> = {
  name: string;
  label?: React.ReactNode;
  labelProps?: React.ComponentType<typeof Div>;
  options: {
    label: React.ReactNode;
    value: ValueType;
    disabled?: boolean;
  }[];
  value?: ValueType[];
  onChange: (value: ValueType[]) => void;
  className?: string;
  error?: React.ReactNode;
  errorProps?: React.ComponentProps<typeof Div>;
  disabled?: boolean;
  layout?: 'row' | 'column';
};

let count = 0;

function Checkboxes<ValueType>({
  name,
  label,
  labelProps,
  options,
  value: values,
  onChange,
  className,
  error,
  errorProps,
  disabled
}: FormCheckboxesProps<ValueType>) {
  useRenderOnResize();

  const [ids] = useState(() => ({
    label: `cf-form-checkboxes-label${++count}`,
    error: `cf-form-checkboxes-error${++count}`
  }));

  return (
    <div className={className}>
      {label && (
        <Label id={ids.label} {...labelProps} mb={2}>
          {label}
        </Label>
      )}
      {options.map((option, index) => {
        const hasValue = values?.includes(option.value);
        return (
          <Checkbox
            name={name}
            label={option.label}
            checked={values?.includes(option.value)}
            onChange={() => {
              const newValues = values ? [...values] : [];
              if (hasValue) {
                newValues?.splice(newValues.indexOf(option.value), 1);
              } else {
                newValues?.push(option.value);
              }
              onChange(newValues);
            }}
            disabled={disabled || option.disabled}
            labelFirst={false}
            noLabel
            invalid={!!error}
            labelProps={{ display: 'inline-block' }}
            erroredBy={error ? ids.error : undefined}
            describedBy={label ? ids.label : undefined}
            componentStyleProps={{ display: 'inline-block' }}
            marginBottom={error && index === options.length - 1 ? 2 : 3}
          />
        );
      })}
      {error && (
        <Error mb={2} mt={-2} {...(errorProps || {})} id={ids.error}>
          {error}
        </Error>
      )}
    </div>
  );
}

const StyledFormCheckboxes = createStyledComponent(() => ({}), Checkboxes);

export type CheckboxesProps<ValueType> = FormCheckboxesProps<ValueType> &
  Omit<React.ComponentProps<typeof Div>, 'onChange'>;

export default function FormCheckboxes<ValueType>(
  props: CheckboxesProps<ValueType>
) {
  // @ts-ignore
  return <StyledFormCheckboxes {...props} />;
}
