import * as api from '../api/client'

const LS_KEY_RESULTS = 'spu_analysis_results'
const LS_KEY_SELECTED_SPU = 'spu_analysis_selectedSpu'

function loadFromLocalStorage() {
  try {
    const raw = localStorage.getItem(LS_KEY_RESULTS)
    const res = raw ? JSON.parse(raw) : {}
    const sel = localStorage.getItem(LS_KEY_SELECTED_SPU) || ''
    return { res, sel }
  } catch (e) {
    return { res: {}, sel: '' }
  }
}

function saveToLocalStorage(results, selectedSpu) {
  try {
    localStorage.setItem(LS_KEY_RESULTS, JSON.stringify(results || {}))
    localStorage.setItem(LS_KEY_SELECTED_SPU, selectedSpu || '')
  } catch (e) {}
}

function pickFirstSpu(obj) {
  const keys = Object.keys(obj || {})
  const first = keys.find(k => k !== '_analysis_summary_')
  return first || ''
}

const state = () => {
  const cached = loadFromLocalStorage()
  return {
    results: cached.res,
    loading: false,
    error: null,
    selectedSpu: cached.sel
  }
}

const mutations = {
  SET_RESULTS(state, payload) {
    state.results = payload || {}
  },
  SET_LOADING(state, payload) {
    state.loading = !!payload
  },
  SET_ERROR(state, payload) {
    state.error = payload || null
  },
  SET_SELECTED_SPU(state, payload) {
    state.selectedSpu = payload || ''
  }
}

const actions = {
  async uploadFile({ commit }, file) {
    commit('SET_LOADING', true)
    commit('SET_ERROR', null)
    try {
      const res = await api.uploadSpuFile(file)
      return res
    } catch (e) {
      commit('SET_ERROR', (e && e.message) || '上传失败')
      throw e
    } finally {
      commit('SET_LOADING', false)
    }
  },
  async analyzeFile({ commit }, file) {
    commit('SET_LOADING', true)
    commit('SET_ERROR', null)
    try {
      const response = await api.analyzeSpuFile(file)
      const results = response && response.data ? response.data : {}
      commit('SET_RESULTS', results)
      const firstSpu = pickFirstSpu(results)
      commit('SET_SELECTED_SPU', firstSpu || '')
      saveToLocalStorage(results, firstSpu || '')
    } catch (e) {
      if (e && (e.code === 'ECONNABORTED' || (e.message && e.message.indexOf('timeout') >= 0))) {
        commit('SET_ERROR', '分析超时，数据量较大，请稍后重试或联系管理员')
      } else {
        const msg = (e && e.response && e.response.data && e.response.data.message) || (e && e.message) || '分析失败'
        commit('SET_ERROR', msg)
      }
      throw e
    } finally {
      commit('SET_LOADING', false)
    }
  },
  async analyzeProductLifecycle({ commit }, file) {
    commit('SET_LOADING', true)
    commit('SET_ERROR', null)
    try {
      const response = await api.analyzeProductLifecycle(file)
      return response
    } catch (e) {
      commit('SET_ERROR', (e && e.message) || '商品生命周期分析失败')
      throw e
    } finally {
      commit('SET_LOADING', false)
    }
  },
  async fetchResults({ commit, state }) {
    commit('SET_LOADING', true)
    commit('SET_ERROR', null)
    try {
      const results = await api.getSpuResults()
      if (results && !results.message) {
        commit('SET_RESULTS', results)
        let selectedSpu = state.selectedSpu
        if (!selectedSpu || !results[selectedSpu]) {
          selectedSpu = pickFirstSpu(results)
          commit('SET_SELECTED_SPU', selectedSpu)
        }
        saveToLocalStorage(results, selectedSpu)
      }
    } catch (e) {
      commit('SET_ERROR', (e && e.message) || '获取结果失败')
    } finally {
      commit('SET_LOADING', false)
    }
  },
  selectSpu({ commit, state }, spu) {
    const next = spu || ''
    commit('SET_SELECTED_SPU', next)
    saveToLocalStorage(state.results, next)
  },
  clearResults({ commit }) {
    commit('SET_RESULTS', {})
    commit('SET_SELECTED_SPU', '')
    commit('SET_ERROR', null)
    saveToLocalStorage({}, '')
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
