import AsyncStorage from '@react-native-community/async-storage';
import * as api from '../services/store';

export default {
  namespace: 'store',
  state: {
    auth: {},
    socket: '',
    ai: {
      temperature: 0,
      humidity: 0,
      shock: 0,
      trigger: {
        text: 0,
        data: 0,
      },
      offset: 0,
    },
  },
  reducers: {
    initScaleData(state) {
      state.ai = {
        ...state.ai,
        shock: 0,
        trigger: {
          text: 0,
          data: 0,
        },
        offset: 0,
      };
      return {...state};
    },
    setAuth(state, {id, auth}) {
      state.id = id;
      state.auth = auth;
      window.auth = auth;
      if (window.socket) {
        window.socket.io.opts.query = {
          token: auth.token,
        };
      }
      return {...state};
    },
    setScaleData(state, {data}) {
      state.ai = data;
      return {...state};
    },
    setSocket(state, {socket}) {
      state.socket = socket;
      return {...state};
    },
  },
  effects: {
    *auth(action, {put, call}) {
      const {data} = action.key
        ? yield call(api.token, action)
        : yield call(api.refreshToken);
      if (data && data.code === 1) {
        let set = [];
        if (action.key) {
          set = [
            ['KEY', action.key],
            ['SECRET', action.secret],
            ['DEVICE', action.device],
          ];
        }
        if (action.host) {
          set.push(['HOST', action.host]);
        }
        if (data.data && data.data.contact) {
          set.push(['CONTACT', data.data.contact]);
        }
        set.push(['auth', JSON.stringify(data.data)]);
        yield call(AsyncStorage.multiSet, set);
        // 缓存数据到内存，方便调用
        const getValues = () =>
          AsyncStorage.multiGet(['HOST', 'KEY', 'DEVICE', 'CONTACT']);
        const values = yield call(getValues);
        window.deviceInfo = {};
        values.map(r => {
          const k = r[0];
          const v = r[1];
          if (k && v) {
            window.deviceInfo[k.toLowerCase()] = v;
          }
        });
        yield put({type: 'setAuth', id: data.id, auth: data.data});
        yield put({type: 'region'});
      }
      return data;
    },
    *logout(action, {put, call}) {
      yield call(AsyncStorage.removeItem, 'auth');
      yield put({type: 'app/replace', route: 'home'});
    },
    *version(action, {call}) {
      yield call(api.version);
    },
    *region(action, {call}) {
      const {data} = yield call(api.region);
      if (data.code === 1) {
        window.region = data.data;
        window.regionArr = [];
        ['citycode', 'adcode', 'towncode'].map(k => {
          const v = window.region[k];
          if (v) {
            window.regionArr.push(v);
          }
        });
        window.regionArr.push(window.region.key);
        window.regionArr = window.regionArr.reverse();
      }
    },
    *door(action, {call}) {
      const {data} = yield call(api.door, action);
      if (data.code === 1) {
        return data.data;
      }
    },
    *wxdoor(action, {call}) {
      const {data} = yield call(api.wxdoor, action);
      if (data.code === 1) {
        return data.data;
      }
    },
    *scaleData(action, {put, call, select}) {
      let {data} = yield call(api.scaleData);
      if (data.code === 1 && data.data) {
        let trigger = yield select(state => state.store.ai.trigger);
        const dataTran = tranAIData(data.data, trigger);
        yield put({type: 'setScaleData', data: dataTran});
        return data.data;
      }
    },
    *sendsms(action, {call}) {
      const {data} = yield call(api.sendsms, action);
      return data;
    },
    *verifysms(action, {call}) {
      const {data} = yield call(api.verifysms, action);
      return data;
    },
    *getAdvertising(action, {call}) {
      return yield call(api.getAdvertising, action);
    },
    *getStore(action, {call}) {
      return yield call(api.getStore, action);
    },
  },
};

const randomData = Math.random();

let tranAIData = (data, trigger) => {
  let aiData = {
    shock: 0,
    trigger: {
      text: 0,
      data: 0,
    },
    offset: 0,
  };
  let max = 0;
  let min = 500000;
  let sum = 0;
  data.weights.map(v => {
    if (v > max) {
      max = v;
    }
    if (v < min) {
      min = v;
    }
    sum += v;
  });
  let ave = sum / 10;
  if (max - min >= 600) {
    aiData.shock = (100 + Math.random() * 80) * (ave / 75000);
  } else {
    aiData.shock = ((max - min) / 4) * (ave / 75000);
  }
  if (data.stableWeight && data.stableWeight > 0) {
    aiData.trigger.data = 96;
    aiData.trigger.text = data.stableWeight;
  } else {
    aiData.trigger.data = trigger.data + Math.random() * 30;
    aiData.trigger.text = ave;
  }
  if (data.stableWeight && data.stableWeight > 0) {
    aiData.offset = randomData * 30;
  } else if (max - ave > 30 && ave - min > 30) {
    aiData.offset = 30 + Math.random() * 30;
  } else {
    aiData.offset = max - ave > ave - min ? ave - min : max - ave;
  }
  if (
    !data.weights ||
    (Number(data.weights[0]) === 0 &&
      Number(data.weights[data.weights.length - 1]) === 0)
  ) {
    aiData = {
      shock: 0,
      trigger: {
        text: 0,
        data: 0,
      },
      offset: 0,
    };
  }
  return {temperature: data.temperature, humidity: data.humidity, ...aiData};
};
