import React from "react";
import { getPropValue } from "../../utils/helper";
import { stripNumber } from "../../utils/tpl-builtin";
import { FormControlProps } from './Item';

function renderCommonStatic(props: any, defaultValue: any) {
  const {
    type,
    render,
    staticSchema,
    precision,
    prefix,
    suffix,
    percent,
    kilobitSeparator,
    affix
  } = props;
  const staticProps = {
    ...props,
    ...staticSchema
  };

  switch (type) {
    case 'select':
    case 'checkboxes':
    case 'button-group-select':
    case 'input-tree':
    case 'tree-select':
    case 'nested-select':
    case 'cascader-select':
    case 'radios':
    case 'multi-select':
    case 'transfer':
    case 'transfer-picker':
    case 'tabs-transfer':
    case 'tabs-transfer-picker':
      return render('static-select', { type: 'words' }, staticProps);

    case 'input-date':
    case 'input-datetime':
    case 'input-time':
    case 'input-month':
    case 'input-quarter':
    case 'input-year':
      return renderStaticDateTypes(staticProps);

    case 'input-date-range':
    case 'input-datetime-range':
    case 'input-time-range':
    case 'input-month-range':
    case 'input-quarter-range':
    case 'input-year-range':
      return render('static-input-date-range', { type: 'date-range' }, {
        ...props,
        valueFormat: props.format,
        format: props.inputFormat,
        ...staticSchema
      });

    case 'input-password':
      return render('static-input-password', { type: 'password' }, staticProps);

    case 'input-color':
      return render('static-color', { type: 'color' }, staticProps);

    case 'input-tag':
      return render('static-input-tag', { type: 'tags' }, staticProps);

    case 'input-url':
      return render('static-input-url', { type: 'link', href: defaultValue }, staticProps);

    case 'input-number':
      let viewValue;
      if (defaultValue != 0 && !defaultValue) {
        viewValue = <span className="text-muted">-</span>
      } else {
        let value = defaultValue;
        // 设置了精度，但是原始数据是字符串，需要转成 float 之后再处理
        if (typeof value === 'string' && precision) {
          value = stripNumber(parseFloat(value));
        }

        if (typeof value == 'number' && isNaN(value)) {
          viewValue = false;
        } else if (percent) {
          // 如果是百分比展示
          value = parseFloat(value) || 0;
          const decimals = typeof percent === 'number' ? percent : 0;

          let whole = value * 100;
          let multiplier = Math.pow(10, decimals);

          value =
            (Math.round(whole * multiplier) / multiplier).toFixed(decimals) + '%';
          viewValue = <span>{value}</span>;
        } else {
          if (typeof value === 'number' && precision) {
            value = value.toFixed(precision);
          }

          if (kilobitSeparator) {
            value = (value + '').replaceAll(',', '');
            value = value.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
          }

          viewValue = <span>{value}</span>;
        }
      }
      return <>{prefix}
        {viewValue}
        {affix ?? suffix}</>
    default:
      return defaultValue;
  }
}

/**
 * 表单项类成员render支持静态展示装饰器
 */
export function supportStatic<T extends FormControlProps>() {
  return function (
    target: any,
    name: string,
    descriptor: TypedPropertyDescriptor<any>
  ) {
    const original = descriptor.value;
    descriptor.value = function (...args: any[]) {
      const props = (this as TypedPropertyDescriptor<any> & { props: T }).props;
      if (props.staticShow) {
        const {
          render,
          staticSchema,
          classPrefix: ns,
          classnames: cx,
          className,
          staticPlaceholder = '-'
        } = props;

        let body;
        const displayValue = getPropValue(props);
        const isValueEmpty = displayValue == null || displayValue === '';

        if (staticSchema && (
          staticSchema.type
          || Array.isArray(staticSchema)
          || typeof staticSchema === 'string'
          || typeof staticSchema === 'number'
        )) {
          // 有自定义schema 且schema有type 时，展示schema
          body = render('form-static-schema', staticSchema, props);
        } else if (target.renderStatic) {
          // 特殊组件，control有 renderStatic 时，特殊处理
          body = target.renderStatic.apply(this, [...args,
          isValueEmpty ? staticPlaceholder : displayValue
          ]);
        } else if (isValueEmpty) {
          // 空值时，展示 staticPlaceholder
          body = staticPlaceholder;
        } else {
          // 可复用组件 统一处理
          body = renderCommonStatic(props, displayValue);
        }

        return <div className={cx(`${ns}Form-static`, className)} style={{ padding: '5px 0' }}>{body}</div>
      }

      return original.apply(this, args);
    }
    return descriptor;
  }
}

function renderStaticDateTypes(props: any) {
  const { render, type, inputFormat, timeFormat, format, value } = props;
  return render(
    'static-input-date',
    {
      type: 'date',
      value,
      format: type === 'time' && timeFormat ? timeFormat : inputFormat,
      valueFormat: format
    }
  );
}
