import { computed, defineComponent, ref } from 'vue';
import type { PropType } from 'vue';
import { CheckBoxListEditorController } from '@ibiz-template/controller';
import { useNamespace } from '@ibiz-template/vue-util';
import '@/styles/components/editor/ibiz-check-box-list/ibiz-check-box-list.scss';

export default defineComponent({
  props: {
    value: String,
    controller: {
      type: CheckBoxListEditorController,
      required: true,
    },
    data: {
      type: Object as PropType<IData>,
      required: true,
    },
  },
  emits: {
    change: (_value: null | string | number | string[]) => true,
  },
  setup(props, { emit }) {
    const ns = useNamespace('check-box-list');

    const c = props.controller;

    const editorModel = c.model;

    const codeList = editorModel.codeList;

    // 代码表数据
    const items = ref<readonly IData[]>([]);
    c.loadCodeList(props.data).then(_codeList => {
      items.value = _codeList;
    });

    // 当前模式
    const currentMode = computed(() => {
      if (codeList && codeList.orMode) {
        return codeList.orMode.toLowerCase();
      }
      return 'str';
    });

    // 值分隔符
    let valueSeparator = ',';
    if (codeList && codeList.valueSeparator) {
      valueSeparator = codeList.valueSeparator;
    }

    // 选中数组
    const selectArray = computed({
      get() {
        if (props.value) {
          if (Object.is(currentMode.value, 'num') && items) {
            const selectsArray: Array<string | number> = [];
            const num: number = parseInt(props.value, 10);
            items.value.forEach((item: IData) => {
              // eslint-disable-next-line no-bitwise
              if ((num & item.value) === item.value) {
                selectsArray.push(item.value);
              }
            });
            return selectsArray;
          }
          if (Object.is(currentMode.value, 'str')) {
            if (props.value !== '') {
              if (codeList) {
                const selects: Array<string | number> =
                  props.value.split(valueSeparator);
                if (codeList.codeItemValueNumber) {
                  for (let i = 0, len = selects.length; i < len; i++) {
                    selects[i] = Number(selects[i]);
                  }
                }
                return selects;
              }
              return props.value.split(',');
            }
          }
        }
        return [];
      },
      set(val: Array<string | number>) {
        let value: null | string | number | string[] = null;
        if (Object.is(currentMode.value, 'num')) {
          let temp: number = 0;
          val.forEach((item: unknown) => {
            if (typeof item === 'string') {
              // eslint-disable-next-line no-bitwise
              temp |= parseInt(item, 10);
            }
          });
          value = temp;
        } else if (Object.is(currentMode.value, 'str')) {
          const _datas: string[] = [];
          if (items.value.length > 0) {
            items.value.forEach((_item: IData) => {
              const index = val.findIndex((_key: unknown) =>
                Object.is(_item.value, _key),
              );
              if (index === -1) {
                return;
              }
              _datas.push(_item.value);
            });
            value = _datas.join(valueSeparator);
          }
        }
        emit('change', value);
      },
    });

    const onSelectArrayChange = (value: Array<string | number>) => {
      selectArray.value = value;
    };

    return {
      ns,
      items,
      selectArray,
      onSelectArrayChange,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        <i-checkbox-group
          value={this.selectArray}
          on-on-change={this.onSelectArrayChange}
        >
          {this.items.map((_item, index: number) => (
            <i-checkbox
              key={index}
              label={_item.value}
              readonly={this.controller.model.readOnly}
            >
              <span class={this.ns.e('text')}>{_item.text}</span>
            </i-checkbox>
          ))}
        </i-checkbox-group>
      </div>
    );
  },
});
