import Cookies from "js-cookie";

const readDefaultState = () => {
  try {
    return JSON.parse(Cookies.get("custom_storage") || "");
  } catch (err) {
    return {};
  }
};

const defaultState = {
  // loading effect
  loading: false,
  // media devices
  streams: [],
  localStream: null,
  currentStream: null,
  otherStreams: [],
  devicesList: [],
  // web sdk params
  config: {
    uid: 0,
    host: true,
    channelName: "",
    token:
      "0068a9a7badbd3a4b4683d11e5750e3de71IACaM0K8TQ9SVI80lpAL8PVgkuhbg95mSyzGhOXYwpPtmp1fCyoAAAAAEAAB6BGrYLFtXwEAAQBfsW1f",
    resolution: "720p_1",
    ...readDefaultState(),
    microphoneId: "",
    cameraId: "",
  },
  agoraClient: null,
  mode: "live",
  codec: "vp8",
  muteVideo: false,
  muteAudio: false,
  screen: false,
  profile: false,
  // beauty: false
};

const reducer = (state: any, action: any) => {
  switch (action.type) {
    case "config": {
      return { ...state, config: action.payload };
    }
    case "client": {
      return { ...state, client: action.payload };
    }
    case "loading": {
      return { ...state, loading: action.payload };
    }
    case "codec": {
      return { ...state, codec: action.payload };
    }
    case "video": {
      return { ...state, muteVideo: action.payload };
    }
    case "audio": {
      return { ...state, muteAudio: action.payload };
    }
    case "screen": {
      return { ...state, screen: action.payload };
    }
    case "devicesList": {
      return { ...state, devicesList: action.payload };
    }
    case "localStream": {
      return { ...state, localStream: action.payload };
    }
    case "profile": {
      return { ...state, profile: action.payload };
    }
    case "currentStream": {
      const { streams } = state;
      const newCurrentStream = action.payload;
      const otherStreams = streams.filter(
        (it: any) => it.getId() !== newCurrentStream.getId()
      );
      return { ...state, currentStream: newCurrentStream, otherStreams };
    }
    case "addStream": {
      const { streams, currentStream } = state;
      const newStream = action.payload;
      let newCurrentStream = currentStream;
      if (!newCurrentStream) {
        newCurrentStream = newStream;
      }
      if (streams.length === 4) return { ...state };
      const newStreams = [...streams, newStream];
      const otherStreams = newStreams.filter(
        (it) => it.getId() !== newCurrentStream.getId()
      );
      return {
        ...state,
        streams: newStreams,
        currentStream: newCurrentStream,
        otherStreams,
      };
    }
    case "removeStream": {
      const { streams, currentStream } = state;
      const { stream, uid } = action;
      const targetId = stream ? stream.getId() : uid;
      let newCurrentStream = currentStream;
      const newStreams = streams.filter(
        (stream: any) => stream.getId() !== targetId
      );
      if (currentStream && targetId === currentStream.getId()) {
        if (newStreams.length === 0) {
          newCurrentStream = null;
        } else {
          newCurrentStream = newStreams[0];
        }
      }
      const otherStreams = newCurrentStream
        ? newStreams.filter(
            (it: any) => it.getId() !== newCurrentStream.getId()
          )
        : [];
      return {
        ...state,
        streams: newStreams,
        currentStream: newCurrentStream,
        otherStreams,
      };
    }
    case "clearAllStream": {
      // const {streams, localStream, currentStream, beauty} = state;
      const { streams, localStream, currentStream } = state;
      streams.forEach((stream: any) => {
        if (stream.isPlaying()) {
          stream.stop();
        }
        // stream.close();
      });

      if (localStream) {
        localStream.isPlaying() && localStream.stop();
        localStream.close();
      }
      if (currentStream) {
        currentStream.isPlaying() && currentStream.stop();
        currentStream.close();
      }
      return { ...state, currentStream: null, localStream: null, streams: [] };
    }
    // case 'enableBeauty': {
    //   return {
    //     ...state,
    //     beauty: action.enable
    //   }
    // }
    default:
      throw new Error("mutation type not defined");
  }
};

export { reducer, defaultState };
