import { ref, defineComponent, Ref, watch, computed, VNode } from 'vue';
import { getSpanProps, useNamespace } from '@ibiz-template/vue-util';
import dayjs from 'dayjs';
import '@ibiz-template/theme/style/components/editor/ibiz-span/ibiz-span.scss';
import { CodeListItem } from '@ibiz-template/service';
import { DataTypes } from '@ibiz-template/core';

export const IBizSpan = defineComponent({
  name: 'IBizSpan',
  props: getSpanProps(),
  setup(props) {
    const ns = useNamespace('span');
    const c = props.controller;

    const text: Ref<string> = ref('');

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

    watch(
      () => props.value,
      (newVal, oldVal) => {
        if (newVal !== oldVal) {
          if (newVal == null) {
            text.value = '';
            return;
          }
          const { dataType } = c.parent;
          if (c.valueFormat) {
            try {
              if (dataType != null && DataTypes.isDate(dataType)) {
                text.value = dayjs(newVal).format(c.valueFormat);
              } else {
                text.value = ibiz.util.text.format(`${newVal}`, c.valueFormat);
              }
            } catch (error) {
              text.value = `${newVal}`;
              ibiz.log.error(`${newVal} 值格式化错误`);
            }
          } else {
            text.value = `${newVal}`;
          }
          if (c.unitName) {
            text.value += c.unitName;
          }
        }
      },
      {
        immediate: true,
      },
    );

    // 代码表数据
    const items = ref<readonly CodeListItem[]>([]);
    if (codeList) {
      watch(
        () => props.data,
        newVal => {
          c.loadCodeList(newVal).then(_codeList => {
            items.value = _codeList;
          });
        },
        {
          immediate: true,
          deep: true,
        },
      );
    }

    /** 代码表转换后文本 */
    const codeListText = computed(() => {
      if (!codeList || !props.value || items.value.length === 0) {
        return undefined;
      }
      if (codeList.codeItemValueNumber) {
        return items.value.find(item => item.value === props.value);
      }
      const values = (props.value as string).split(valueSeparator);
      const selects = items.value.filter(item =>
        values.includes(item.value as string & Number),
      );
      return selects.map(item => item.text).join(valueSeparator);
    });

    return {
      ns,
      text,
      codeListText,
      items,
      codeList,
    };
  },
  render() {
    let content: string | VNode = '';
    if (this.codeList && this.items.length) {
      content = (
        <code-list
          codeListItems={this.items}
          codeList={this.codeList}
          value={this.value}
        ></code-list>
      );
    } else if (this.text != null) {
      content = this.text;
    }
    return (
      <span
        class={[
          this.ns.b(),
          this.disabled ? this.ns.m('disabled') : '',
          this.readonly ? this.ns.m('readonly') : '',
        ]}
      >
        {content}
      </span>
    );
  },
});
