import { ref, watch, Ref, defineComponent, computed } from 'vue';
import {
  getDataPickerProps,
  getEditorEmits,
  useNamespace,
} from '@ibiz-template/vue-util';
import '@ibiz-template/theme/style/components/editor/ibiz-mpicker/ibiz-mpicker.scss';

export const IBizMPicker = defineComponent({
  name: 'IBizMPicker',
  props: getDataPickerProps(),
  emits: getEditorEmits(),
  setup(props, { emit }) {
    const ns = useNamespace('mpicker');

    const c = props.controller!;

    // 当前表单项绑定值key的集合
    const curValue: Ref<Array<string>> = ref([]);

    // 实体数据集
    const items: Ref<IData[]> = ref([]);

    // 选中项key-value键值对
    const selectItems: Ref<IData[]> = ref([]);

    // 下拉是否打开
    const open = ref(false);

    // 加载中
    const loading: Ref<boolean> = ref(false);

    // 格式化值，把实体属性名格式化成srfkey和srfmajortext
    const formatValue = (value: IData[]) => {
      let result: IData[] = [];
      if (c.keyName !== 'srfkey' || c.textName !== 'srfmajortext') {
        value.forEach((item: IData) => {
          result.push({
            srfmajortext: item[c.textName] || item.srfmajortext,
            srfkey: item[c.keyName],
          });
        });
      } else {
        result = value;
      }
      return result;
    };

    // 解析值,把srfkey和srfmajortext解析成实体属性名
    const parseValue = (value: IData[]) => {
      let result: IData[] = [];
      if (c.keyName !== 'srfkey' || c.textName !== 'srfmajortext') {
        value.forEach((item: IData) => {
          result.push({
            [c.textName]: item.srfmajortext,
            [c.keyName]: item.srfkey,
          });
        });
      } else {
        result = value;
      }
      return result;
    };

    // 监听传入值
    watch(
      () => props.value,
      newVal => {
        curValue.value = [];
        selectItems.value = [];
        if (newVal) {
          try {
            selectItems.value = parseValue(JSON.parse(newVal));
            selectItems.value.forEach((item: IData) => {
              curValue.value.push(item[c.keyName]);
              const index = items.value.findIndex(i =>
                Object.is(i[c.keyName], item[c.keyName]),
              );
              if (index < 0) {
                items.value.push({
                  [c.keyName]: item[c.keyName],
                  [c.textName]: item[c.textName] || item.srfmajortext,
                });
              }
            });
          } catch (error) {
            if ((error as IData).name === 'SyntaxError') {
              const srfkeys: string[] = newVal.split(',');
              let srfmajortexts: string[] = [];
              if (c.valueItem && props.data![c.valueItem]) {
                srfmajortexts = props.data![c.valueItem].split(',');
              }
              if (
                srfkeys &&
                srfkeys.length > 0 &&
                srfmajortexts &&
                srfmajortexts.length > 0 &&
                srfkeys.length === srfmajortexts.length
              ) {
                srfkeys.forEach((id: string, index: number) => {
                  curValue.value.push(id);
                  selectItems.value.push({
                    [c.keyName]: id,
                    [c.textName]: srfmajortexts[index],
                  });
                  const _index = items.value.findIndex(i =>
                    Object.is(i[c.keyName], id),
                  );
                  if (_index < 0) {
                    items.value.push({
                      [c.keyName]: id,
                      [c.textName]: srfmajortexts[index],
                    });
                  }
                });
              }
            }
          }
        }
      },
      { immediate: true, deep: true },
    );

    // 处理视图关闭，往外抛值
    const handleOpenViewClose = (result: IData[]) => {
      const selects: IData[] = [];
      if (result && Array.isArray(result)) {
        result.forEach((select: IData) => {
          selects.push({
            [c.keyName]: select[c.keyName] || select.srfkey,
            [c.textName]: select[c.textName] || select.srfmajortext,
          });
          const index = items.value.findIndex(item =>
            Object.is(item[c.keyName], select[c.keyName]),
          );
          if (index < 0) {
            items.value.push({
              [c.textName]: select[c.textName] || select.srfmajortext,
              [c.keyName]: select[c.keyName],
            });
          }
        });
      }
      if (props.data) {
        const value =
          selects.length > 0 ? JSON.stringify(formatValue(selects)) : '';
        emit('change', value);
      }
    };

    // 打开数据选择视图
    const openPickUpView = async () => {
      // TODO 后续参数
      // const _selectItems: IData[] = JSON.parse(JSON.stringify(selectItems.value));
      // if (!Object.is(c.keyName, 'srfkey')) {
      //   _selectItems.forEach((item: IData, index: number) => {
      //     _selectItems[index].srfkey = item[c.keyName];
      //   });
      // }
      // if (!Object.is(c.textName, 'srfmajortext')) {
      //   _selectItems.forEach((item: IData, index: number) => {
      //     _selectItems[index].srfmajortext = item[c.textName] || item.srfmajortext;
      //   });
      // }
      // Object.assign(c.context, {
      //   srfparentdata: { srfparentkey: props.data[c.keyName] },
      // });
      // Object.assign(c.params, { selectedData: [..._selectItems] });
      const res = await c.openPickUpView(props.data!);
      if (res) {
        handleOpenViewClose(res);
      }
    };

    // 下拉选中回调
    const onSelect = (selects: string[]) => {
      const val: Array<IData> = [];
      if (selects.length > 0) {
        selects.forEach((select: string) => {
          let index = items.value.findIndex(item =>
            Object.is(item[c.keyName], select),
          );
          if (index >= 0) {
            const item = items.value[index];
            val.push({
              [c.keyName]: item[c.keyName],
              [c.textName]: item[c.textName] || item.srfmajortext,
            });
          } else {
            index = selectItems.value.findIndex((item: IData) =>
              Object.is(item[c.keyName], select),
            );
            if (index >= 0) {
              const item = selectItems.value[index];
              val.push(item);
            }
          }
        });
        const value = val.length > 0 ? JSON.stringify(formatValue(val)) : '';
        emit('change', value);
      } else {
        emit('change', '');
      }
    };

    // 搜索
    const onSearch = async (query: string) => {
      if (c.model.appDataEntity) {
        loading.value = true;
        try {
          const res = await c.getServiceData(query, props.data!);
          loading.value = false;
          if (res) {
            items.value = res.data as IData[];
          }
        } catch (error) {
          loading.value = false;
        }
      }
    };

    // 下拉打开
    const onOpenChange = (flag: boolean) => {
      open.value = flag;
      emit('operate', flag);
      if (open.value) {
        items.value = [];
        onSearch('');
      }
    };

    const valueText = computed(() => {
      return selectItems.value
        .map(item => {
          return item[c.textName] || item.srfmajortext;
        })
        .join(',');
    });
    return {
      ns,
      c,
      curValue,
      loading,
      items,
      valueText,
      onSearch,
      onOpenChange,
      onSelect,
      openPickUpView,
    };
  },
  render() {
    return (
      <div
        class={[
          this.ns.b(),
          this.disabled ? this.ns.m('disabled') : '',
          this.readonly ? this.ns.m('readonly') : '',
        ]}
      >
        {this.readonly && this.valueText}
        {!this.readonly && (
          <i-select
            value={this.curValue}
            filterable
            transfer
            multiple
            loading={this.loading}
            placeholder={this.c.placeHolder}
            remote-method={this.onSearch}
            on-on-open-change={this.onOpenChange}
            on-on-change={this.onSelect}
            disabled={this.disabled}
          >
            {this.items.map((item, index) => {
              return (
                <i-option key={index} value={item[this.c.keyName]}>
                  {item[this.c.textName]}
                </i-option>
              );
            })}
          </i-select>
        )}
        {!this.readonly && (
          <div class={this.ns.e('buns-position')}>
            <div class={this.ns.e('btns')}>
              {this.c.pickupView ? (
                <i-button
                  icon='ios-search'
                  on-click={this.openPickUpView}
                  type={'text'}
                ></i-button>
              ) : null}
            </div>
          </div>
        )}
      </div>
    );
  },
});
