import * as React from 'react';
import { Dialog, Form, Input, Message } from '@alifd/next';
import { showToast } from '../ui/toast';
import { hideLoading, showLoading } from '../ui/loading';

const FormItem = Form.Item;
const REASON_KEY = 'reason';

export function serviceParams(queryService) {
  const { value = {} } = queryService || {};
  const { input = [] } = value;

  return input.reduce((result, { name, bind }) => {
    if (name) {
      result[name] = bind;
    }

    return result;
  }, {});
}

export function evaluate(context, target, defaultValue = null) {
  // console.log('evaluate', context, target);
  if (typeof target === 'function') {
    try {
      return target(context);
    } catch (err) {
      return defaultValue;
    }
  }

  if (target && typeof target === 'object') {
    if (Array.isArray(target)) {
      return target.map((item) => evaluate(context, item, defaultValue));
    }

    const keys = Object.keys(target);
    const result = {};
    keys.forEach((key) => {
      result[key] = evaluate(context, target[key], defaultValue);
    });
    return result;
  }

  return target;
}

interface ICallServiceOptions {
  service: any;
  hasConfirm?: boolean;
  hasConfirmReason?: boolean;
  confirmReasonRequired?: boolean;
  confirmReasonPlaceholder?: string;
  confirmContent?: string;
  confirmTitle?: string;
  confirmContentMaxLength?: number;
  confirmReasonTitle?: string;
  data?: any;
  context?: any;
  callback?: (resp: any) => void;
  onError?: (error: any, resp: any) => void;
  onSuccess?: (resp: any) => void;
  noLoading?: boolean;
}

export function callService(ctx, options: ICallServiceOptions) {
  const {
    service,
    hasConfirm = false,
    confirmTitle = '提示',
    confirmContent = '确定要执行该操作吗？',
    hasConfirmReason = false,
    confirmReasonRequired = false,
    confirmReasonPlaceholder = '',
    confirmContentMaxLength = 120,
    confirmReasonTitle = '备注',
    data = {},
    context = {},
    callback,
    onError,
    onSuccess,
    noLoading = false,
  } = options || {};

  if (!ctx || !service) {
    return;
  }

  const executeRequest = (extData = {}) => {
    const rawParams = serviceParams(service);
    const params = evaluate(context, rawParams);

    !noLoading && showLoading();
    ctx
      .executeRequest(service.service, { ...params, ...data, ...extData })
      .then((resp) => {
        const { success, errorMessage, message } = resp;
        if (errorMessage || (success !== null && !success)) {
          const err: any = new Error(errorMessage || message || '网络错误');
          err.resp = resp;
          throw err;
        }

        !noLoading && hideLoading();
        onSuccess && onSuccess(resp);
        callback && callback(resp);
      })
      .catch((err) => {
        !noLoading && hideLoading();
        if (onError) {
          onError(new Error(err.message), err.resp);
        } else {
          Message.error(err.message);
        }
        callback && callback(err.resp);
      });
  };

  if (hasConfirm) {
    const confirmData: any = {};

    Dialog.show({
      type: 'confirm',
      // 二期组件统一使用配置化主题，next-前缀
      // 此处不加prefix会被一期影响，前缀变为 retailforce-
      prefix: 'next-',
      messageProps: { type: 'warning' },
      title: confirmTitle,
      overlayProps: { className: 'oms-confirm-dialog' },
      content: (
        <div>
          {confirmContent}
          {hasConfirmReason && (
            <Form style={{ marginTop: 12 }} labelCol={{ fixedSpan: 3 }}>
              <FormItem label={confirmReasonTitle} required={confirmReasonRequired}>
                <Input.TextArea
                  name={confirmReasonTitle}
                  onChange={(value) => (confirmData[REASON_KEY] = value)}
                  placeholder={confirmReasonPlaceholder}
                  maxLength={confirmContentMaxLength}
                  hasLimitHint
                />
              </FormItem>
            </Form>
          )}
        </div>
      ),
      onOk: () => {
        if (hasConfirmReason && confirmReasonRequired && !confirmData[REASON_KEY]) {
          showToast({ content: '请填写备注', type: 'error' });
          return false;
        }

        executeRequest(hasConfirmReason && confirmData);
      },
    });
  } else {
    executeRequest();
  }
}
