import { saveAs } from 'file-saver';
import {
  types,
  getParent,
  flow,
  getEnv,
  getRoot,
  isAlive,
  Instance
} from 'mobx-state-tree';
import { IRendererStore } from './index';
import { ServiceStore } from './service';
import {
  extendObject,
  createObject,
  isObjectShallowModified,
  sortArray,
  isEmpty,
  qsstringify
} from '../utils/helper';
import { Api, Payload, fetchOptions, Action, ApiObject } from '../types';
import pick from 'lodash/pick';
import { resolveVariableAndFilter } from '../utils/tpl-builtin';
import { normalizeApiResponseData } from '../utils/api';


class ServerError extends Error {
  type = 'ServerError'
}

export const LionTableStore = ServiceStore.named('LionTableStore')
  .props({

  })
  .views(self => ({

  }))
  .actions(self => {
    const lionSaveRemote: (
      api: Api,
      data?: object,
      options?: fetchOptions
    ) => Promise<any> = flow(function* lionSaveRemote(
      api: Api,
      data: object,
      options: fetchOptions = {}
    ) {
      try {
        options = {
          method: 'post', // 默认走 post
          ...options
        };

        self.markSaving(true);
        const json: Payload = yield getEnv(self).fetcher(api, data, options);
        self.markSaving(false);

        if (!isEmpty(json.data) || json.ok) {
          self.updateData(
            normalizeApiResponseData(json.data),
            {
              __saved: Date.now()
            },
            !!api && (api as ApiObject).replaceData
          );
          self.updatedAt = Date.now();
        }

        if (!json.ok) {
          self.updateMessage(
            json.msg ?? options.errorMessage ?? self.__('saveFailed'),
            true
          );
          getEnv(self).notify(
            'error',
            self.msg,
            json.msgTimeout !== undefined
              ? {
                closeButton: true,
                timeout: json.msgTimeout
              }
              : undefined
          );
          throw new ServerError(self.msg);
        } else {
          self.updateMessage(json.msg ?? options.successMessage);
          self.msg &&
            getEnv(self).notify(
              'success',
              self.msg,
              json.msgTimeout !== undefined
                ? {
                  closeButton: true,
                  timeout: json.msgTimeout
                }
                : undefined
            );
        }
        return json.data;
      } catch (e) {
        self.markSaving(false);

        if (!isAlive(self) || self.disposed) {
          return;
        }

        e.type !== 'ServerError' && getEnv(self).notify('error', e.message);
        throw e;
      }
    });
    return {
      lionSaveRemote
    }
  })

export type ILionTableStore = Instance<typeof LionTableStore>;
