import React, { useReducer, createContext, useMemo } from "react";

const StoreContext = createContext();

const ACTIONS = {
  UPDATE: "u",
};


const pipelineMappingsMock = [["primary", "secondary1","tertiary1"],
                              ["primary", "secondary1", "tertiary2"], 
                              ["primary", "secondary2", "tertiary3"]];

const silencedMock = new Array(10).fill(0).map((v, i) => ({
  name: `Test${i + 1}`,
  class: `SomeTestClass${i % 2 ? i - 1 : i / 2}`,
  method: "someMethod",
  id: Date.now(),
  silencedUntil: `2022-05-10T16:${2 + i}:33.810Z`,
}));

const catalogMock = new Array(10).fill(0).map((v, i) => ({
  name: `Test${i + 1}`,
  class: `SomeTestClass${i % 2 ? i - 1 : i / 2}`,
  repo: "Repo",
  isCompound: i % 5 ? false : true,
  type: i % 3 ? "api" : "ui",
}));

const failingMock = new Array(12).fill(0).map((v, i) => ({
  class: `SomeTestClass${i % 2 ? i - 1 : i / 2}`,
  name: `TestThatDoesOneThing${i + 1}`,
  timestamp: `2022-05-10T16:0${i < 10 ? i : i - 10}:33.810Z`,
  method: `SomeMethod`,
  silencedUntil: i % 4 ? null : `2022-05-10T16:0${i}:33.810Z`,
  frequency: "1hour",
  type: i % 3 ? "api" : "ui",
  dailyFails: i + 1,
  screenshot: "https://picsum.photos/1920/1080",
  recentResults: [1, 0, 0, 1, 0],
  isCompound: i % 5 ? false : true,
  failedMessage: `Some Test FailureMessage ${i}`,
  jobStatus: (() => {
    switch (i) {
      case 1:
        return "o";
      case 3:
        return "e";
      case 4:
        return "p";
      case 5:
        return "a";
      case 6:
        return "c";
      case 8:
        return "q";
      default:
        return null;
    }
  })(),
}));

const localStorage = {setItem: ()=>{}, getItem: ()=>{}};

const localSettings = localStorage.getItem("settings");
const defaultSettings = {
  focusJob: true,
  simplifiedControls: true,
  logAppDetails: true,
  defaultRegion: "us",
  defaultPage: "failing",
};

const settings = localSettings ? JSON.parse(localSettings) : defaultSettings;
const settingsKeys = Object.keys(defaultSettings);

const initialState = {
  pages: ["failing", "alerting", "jobs", "catalog", "settings", "about"],
  intervals: [],
  catalog: catalogMock,
  failing: failingMock,
  silenced: silencedMock,
  pipelineMappings: pipelineMappingsMock,
  regions: [],
  catalogSearch: "",
  ...settings,
};

const settingsUpdater = (oldState, storeUpdate) => {
  const settingsToUpdate = {};
  for (var k of settingsKeys) {
    settingsToUpdate[k] = oldState[k];
    if (storeUpdate[k] === undefined) continue;
    settingsToUpdate[k] = storeUpdate[k];
  }

  localStorage.setItem("settings", JSON.stringify(settingsToUpdate));
};

const reducer = (state, action) => {
  const { store } = action;
  // Actions
  switch (action.type) {
    case ACTIONS.UPDATE:
      settingsUpdater(state, store);
      return { ...state, ...store };
    default:
      return state;
  }
};

export const StoreProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, initialState);

  function silenceRequest(silenceInfo) {
    const req = {
      name: silenceInfo.name ?? "*",
      class: silenceInfo.class ?? "*",
      method: silenceInfo.method ?? "*",
      silencedUntil: silenceInfo.silencedUntil,
    };
    console.log("Would upsert silence", req);
  }

  function removeFailure(failure) {
    const req = {
      name: failure.name,
      class: failure.class,
    };
    console.log("Would remove failure", req);
  }

  const context = {
    state,
    dispatch,
    silenceRequest,
    removeFailure,
    updateStore: (store) => dispatch({ type: ACTIONS.UPDATE, store }),
  };
  const contextValue = useMemo(() => context, [state, dispatch]);

  return (
    <StoreContext.Provider value={contextValue}>
      {children}
    </StoreContext.Provider>
  );
};

export default StoreContext;
