const state = {
  port: null,
  connectionStatus: 'disconnected', // 'disconnected', 'connecting', 'connected', 'error'
  baudRate: 9600,
  reader:null,
  readerStatus:"notReading",//"notReading","reading",
  receivedData: '',
  error: null
}

const mutations = {
  SET_PORT(state, port) {
    state.port = port
  },
  SET_READER(state, reader) {
    state.reader = reader
  },
  SET_CONNECTION_STATUS(state, status) {
    state.connectionStatus = status
  },
  SET_READER_STATUS(state, status) {
    state.readerStatus = status
  },
  SET_BAUD_RATE(state, baudRate) {
    state.baudRate = baudRate
  },
  APPEND_RECEIVED_DATA(state, data) {
    state.receivedData += data
  },
  REFRESH_RECEIVED_DATA(state, data) {
    state.receivedData = data
  },
  CLEAR_RECEIVED_DATA(state) {
    state.receivedData = ''
  },
  SET_ERROR(state, error) {
    state.error = error
  }
}

const actions = {
  async requestPort({ commit, state }) {
    try {
      commit('SET_CONNECTION_STATUS', 'connecting')
      const port = await navigator.serial.requestPort()
      commit('SET_PORT', port)
      return port
    } catch (error) {
      commit('SET_CONNECTION_STATUS', 'error')
      commit('SET_ERROR', error)
      throw error
    }
  },

  async connect({ commit, state, dispatch }) {
    try {
      if (!state.port) {
        await dispatch('requestPort')
      }

      commit('SET_CONNECTION_STATUS', 'connecting')
      await state.port.open({ baudRate: state.baudRate })
      commit('SET_CONNECTION_STATUS', 'connected')

      // 开始监听数据
      dispatch('startReading')
    } catch (error) {
      commit('SET_CONNECTION_STATUS', 'error')
      commit('SET_ERROR', error)
      throw error
    }
  },

  async disconnect({ commit, state,dispatch }) {
    if (state.port) {
      try {
        dispatch("stopReading")
        await state.port.close()
      } catch (error) {
        console.error('关闭端口时出错:', error)
      }
      commit('SET_READER', null)
      commit('SET_PORT', null)

    }
    commit('SET_CONNECTION_STATUS', 'disconnected')
    commit('SET_READER_STATUS', 'notReading')
  },

  async startReading({ commit, state, dispatch }) {
    if (!state.port || state.connectionStatus !== 'connected') return

    const reader = state.port.readable.getReader()
    commit('SET_READER', reader)
    try {
      while (true) {
        const { value, done } = await state.reader.read()
        commit('SET_READER_STATUS', 'reading')
        if (done) {
          state.reader.releaseLock()
          commit('SET_READER_STATUS', 'notReading')
          break
        }
        if (value) {
         // const text = new TextDecoder().decode(value)
          commit('REFRESH_RECEIVED_DATA', value)
        }
      }
    } catch (error) {
      commit('SET_ERROR', error)
      dispatch('disconnect')
    } finally {
      reader.releaseLock()
      // 如果仍然处于读取状态但reader结束了，尝试重新开始
      if (state.readerStatus == "reading" && state.port && state.port.readable) {
        setTimeout(() => dispatch('startReading'), 0);
      }
    }
  },
  async stopReading({ commit, state }) {
    if (!state.port === null || !state.port.writable) {
      console.log("Not opened.");
      return;
    }

    if (state.readerStatus == "reading" && state.reader) {
      commit('SET_READER_STATUS', 'notReading');
      state.reader.cancel();
      state.reader.releaseLock();
      console.log("停止读取");
    }
  },
  async sendData({ state }, data) {
    if (!state.port || state.connectionStatus !== 'connected') {
      throw new Error('端口未连接')
    }

    const writer = state.port.writable.getWriter()
    try {
      const encoder = new TextEncoder()
      await writer.write(encoder.encode(data))
    } catch (error) {
      throw error
    } finally {
      writer.releaseLock()
    }
  },

  updateBaudRate({ commit }, baudRate) {
    commit('SET_BAUD_RATE', baudRate)
  },

  clearData({ commit }) {
    commit('CLEAR_RECEIVED_DATA')
  }
}

const getters = {
  isConnected: state => state.connectionStatus === 'connected',
  isConnecting: state => state.connectionStatus === 'connecting',
  isReading: state => state.readerStatus === 'reading',
  connectionStatus: state => state.connectionStatus,
  receivedData: state => state.receivedData,
  portInfo: state => state.port ? {
    name: state.port.getInfo().usbProductId || 'Unknown',
    baudRate: state.baudRate
  } : null
}

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