// src/store/index.js
import Vue from 'vue'
// import Vuex from 'vuex'
import Vuex from '@/vuex'

// 会默认调用 Vuex 的 install 方法

// Vue.use方法的简单实现
// Vue.use = function(plugin, options) {
//   plugin.install(Vue, options)
// }
Vue.use(Vuex)

// Vuex是一个对象,里面有一个大写的Store和install方法
export default new Vuex.Store({
  state: {
    count: 1,
    // 注意,如果state中的属性和模块同名,后面的会覆盖前面的,导致无法取到这个值
    a: 'a'
  },
  getters: {
    getCount(state) {
      return state.count + 1
    }
  },
  mutations: {
    changeCount(state, payload) {
      state.count += payload 
    }
  },
  actions: {
    changeCount({ commit }, payload) {
      setTimeout(() => {
        commit('changeCount', payload)
      }, 1000)
    }
  },
  modules: {
    a: {
      namespaced: true,
      state: {
        name: 'f',
        count: 18
      },
      mutations: {
        changeCount(state, payload) {
          state.count += payload 
        }
      },
      modules: {
        c: {
          namespaced: true,
          state: {
            name: 'c',
            count: 16
          },
          mutations: {
            changeCount(state, payload) {
              state.count += payload 
            }
          }
        }
      }
    },
    b: {
      namespaced: true,
      state: {
        name: 'g',
        count: 17
      },
      mutations: {
        changeCount(state, payload) {
          state.count += payload 
        }
      }
    }
  }
})
// src/vuex/store.js
import { applyMixin } from './install'
import ModuleCollection from './module/module-collection'
const forEachValue = (obj, cb) => {
  Object.keys(obj).forEach(key => cb(obj[key], key))
}
export let Vue
export class Store {
  constructor(options) {
    // 可能用户会有嵌套的module
    this._modules = new ModuleCollection(options)
    console.log('ddd', this._modules)
  }
}

export const install = (_Vue) => {
  Vue = _Vue
  applyMixin(Vue)
}
// src/vuex/utils.js
export const forEachValue = (obj, cb) => {
  Object.keys(obj).forEach(key => cb(obj[key], key))
}
// src/vuex/module/module-collection.js
import { forEachValue } from "../utils"

export default class ModuleCollection {
  constructor(options) { // 遍历用户的属性对数据进行格式化
    this.root = null
    this.register([], options)
  }
  register(path, rootModule) {
    const newModule = {
      _raw: rootModule,
      _children: {},
      state: rootModule.state
    }
    if (path.length == 0) {
      this.root = newModule
    }else {
      const parent = path.slice(0, -1).reduce((memo, current) => {
        return memo._children[current]
      }, this.root)
      parent._children[path[path.length - 1]] = newModule
    }
    // 检测是否配置了 modules 属性
    if (rootModule.modules) {
      forEachValue(rootModule.modules, (module, moduleName) => {
        this.register(path.concat(moduleName), module)
      })
    }
  }
}