<template>
  <mu-form-item :label="currentConfig.label" :prop="currentConfig.key" :inline="currentConfig.inline"
                :tip="currentConfig.tip" :validators="currentConfig.validators" trigger="change">
    <el-radio class="mu-radio" v-model="currentValue"
              v-for="(item, index) in currentConfig.options"
              :key="index"
              :name="currentConfig.name"
              :label="item[currentConfig.optionsConfig.props.value]"
              :disabled="currentConfig.disabled || item[currentConfig.optionsConfig.props.disabled]"
              @change="handleChange">
      {{item[currentConfig.optionsConfig.props.label]}}
    </el-radio>
  </mu-form-item>
</template>

<script lang="ts">
  import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator';
  import { SystemApi } from '../../../api';

  type Size = 'small' | 'medium' | 'large';

  interface InputConfig {
    name?: string,
    size?: Size,
    disabled?: boolean,
    label?: string,
    key?: string,
    inline?: boolean,
    tip?: string,
    validators?: any,
    options?: any,
    optionsConfig?: {
      props?: any,
      optionsLoad?: Function,
      sourceConfigs?: any
    }
  }

  @Component({
    name: 'mcRadio'
  })
  export default class extends Vue {
    @Prop({ default: () => [] }) private value!: any;
    @Prop({ default: () => [] }) private config?: InputConfig;
    @Prop() private extension?: (value: any) => void;
    private isLoading: boolean = false;
    private currentValue: string = this.value;
    private defaultConfig: any = {
      options: [],
      optionsConfig: {
        props: {
          label: 'label',
          value: 'value',
          disabled: 'disabled'
        }
      }
    };

    // 检测值
    @Watch("value")
    onValueChanged(val: string) {
      this.currentValue = val;
    }

    // 合并默认数据
    get currentConfig() {
      const result = this.config;
      Object.keys(this.defaultConfig).forEach((key: string) => {
        if (this.config[key] === undefined) return result[key] = this.defaultConfig[key];
        // 处理options的配置
        if (key === 'optionsConfig' && this.config.optionsConfig) {
          Object.keys(this.defaultConfig.optionsConfig).forEach((optionKey: string) => {
            if (this.config.optionsConfig[optionKey] === undefined)
              result.optionsConfig[optionKey] = this.defaultConfig.optionsConfig[optionKey];
          });
          return;
        }
      });
      return result;
    }

    mounted() {
      this.extension && this.extension({
        onHandleData: (type: string, params?: any, callback?: Function) => {
          const { sourceConfigs, optionsLoad } = this.config.optionsConfig;
          const currentSource = (sourceConfigs || []).find((item: any) => item.type === type);
          switch (type) {
            case "load":
              if (!this.config.options) this.$set(this.config, 'options', []);
              if (optionsLoad) return this.config.options = optionsLoad();
              if (!currentSource) return callback && callback();
              return this.handleLoad(currentSource, params, callback);
            default:
              return;
          }
        }
      });
    }

    /**
     * 加载数据
     * @author tanxj
     * @param source 数据源配置
     * @param params 加载数据参数
     * @param callback 回调
     */
    handleLoad(source: any, params?: any, callback?: Function) {
      this.isLoading = true;
      const { api, onBeforeSubmit, onSuccess, onError } = source;
      const next = (currentParams: any) => {
        const { serviceName, funcName, config } = api;
        SystemApi.handleApi({ serviceName, funcName, params: currentParams }, config).then(async (ret: any) => {
          this.isLoading = false;
          if (onSuccess) {
            this.config.options = onSuccess(ret.data, this.config) || ret.data;
          }
          callback && callback(ret);
        }, (error: any) => {
          this.isLoading = false;
          onError && onError(error);
        });
      };
      onBeforeSubmit ? onBeforeSubmit({ ...api.params, ...params }, next, this.value) : next({ ...api.params, ...params });
    }


    /**
     * 输入框值改变
     * @author tanxj
     * @param value 值
     */
    @Emit('on-change')
    handleChange(value: any) {
      this.$emit('input', this.currentValue);
    }
  }
</script>

