import * as React from 'react';
import * as PropTypes from 'prop-types';
import { Checkbox as TeaCheckbox, ConfigProvider } from 'tea-component';

import classNames from '../../../utils/classnames';
import getLocalCounter from '../../../utils/getLocalCounter';
import isObjectEqual from '../../../utils/isObjectEqual';
import FormCell from '../formcell';
import fromEntries from 'object.fromentries';
import { usePlatform } from '../../../utils/platform';

export default function Checkbox({
  // 系统属性
  className,
  style,
  events,
  // 组件属性
  name,
  label,
  labelVisible = true,
  range,
  layout,
  disabled,
  requiredFlag,
}) {
  const cls = classNames({
    'weda-ui': true,
    'weda-checkbox': true,
    [className]: className,
  });

  const platform = usePlatform();
  const isH5 = platform === 'h5';
  const subCls = classNames({
    'weui-cell': isH5,
    'weui-cell_active': isH5,
    'weui-check__label': isH5,
    'weui-cell_disabled': isH5 && disabled,
  });

  const [checkedItems, setCheckedItems] = React.useState(
    platform === 'h5'
      ? fromEntries(range.map(({ value, checked }) => [value, !!checked]))
      : range.filter(({ checked }) => checked).map(({ value }) => value)
  );
  // 两次range不同时, 需要刷新checkedItems
  const prevRangeRef = React.useRef();
  React.useEffect(() => {
    if (!isObjectEqual(prevRangeRef.current, range)) {
      prevRangeRef.current = range;
      setCheckedItems(
        fromEntries(range.map(({ value, checked }) => [value, !!checked]))
      );
    }
  });

  /**
   * 在ios h5端, label和input的绑定不生效
   * 导致 onChange 事件触发有问题, 所以改为监听 onClick 事件
   */
  const getChangeHandler = function (value) {
    const onChange = function (e) {
      const checked = !checkedItems[value];
      const newMap = Object.assign({}, checkedItems, { [value]: checked });
      setCheckedItems(newMap);
      events.change(
        {
          value: Object.entries(newMap)
            .filter(([, checked]) => checked)
            .map(([value]) => value),
        },
        { originEvent: e }
      );
    };
    return onChange;
  };

  // 现在低码组件往源码组件传入的id不唯一, 暂时使用hashcode替代
  const hashcode = getLocalCounter();
  let checkboxElement;
  if (platform === 'h5') {
    checkboxElement = range.map(({ label, value }, index) => {
      const _id = `checkbox-${hashcode}-${index}`;
      const _name = `checkbox-${hashcode}-${name}`;
      return (
        <label
          className={subCls}
          htmlFor={_id}
          key={_id}
          onClick={getChangeHandler(value)}
        >
          <div className="weui-cell__hd">
            <input
              type="checkbox"
              className="weui-check"
              value={value}
              name={_name}
              id={_id}
              defaultChecked={checkedItems[value]}
              disabled={disabled}
              onClick={(e) => e.stopPropagation()}
            />
            <i className="weui-icon-checked"></i>
          </div>
          <div className="weui-cell__bd">
            <p>{label}</p>
          </div>
        </label>
      );
    });
  } else {
    checkboxElement = (
      <ConfigProvider classPrefix="wedatea2td">
        <TeaCheckbox.Group
          disabled={disabled}
          value={Object.entries(checkedItems)
            .filter(([, checked]) => checked)
            .map(([value]) => value)}
          onChange={(value) => {
            const newMap = range
              .map((opt) => opt.value)
              .reduce((acc, cur) => {
                const idx = value.indexOf(cur);
                if (idx < 0) {
                  acc[cur] = false;
                } else {
                  acc[cur] = true;
                }
                return acc;
              }, {});
            setCheckedItems(newMap);
            events.change({
              value: Object.entries(newMap)
                .filter(([, checked]) => checked)
                .map(([value]) => value),
            });
          }}
        >
          {range.map(({ value, label }, index) => {
            const _id = `checkbox-${hashcode}-${index}`;
            return (
              <TeaCheckbox key={_id} name={value} id={_id}>
                {label}
              </TeaCheckbox>
            );
          })}
        </TeaCheckbox.Group>
      </ConfigProvider>
    );
  }
  return (
    <FormCell
      className={cls}
      style={style}
      label={labelVisible ? label : null}
      layout={layout}
      multiCell={true}
      requiredFlag={requiredFlag}
    >
      {'========================'}
      {checkboxElement}
    </FormCell>
  );
}
