import React, { useContext, useState } from "react";

import api from "../../services/vehiclesAPI";
import { LocalDateTimeString } from "../../utils/dates";
import { useInterval } from "usehooks-ts";

const CANSignalContext = React.createContext();

const BlankSignal = (msg) => ({
  timestamp: "",
  signal: msg,
  value: "",
});

const transformSignals = (signals) =>
  signals
    .map((signal) => {
      const { timestamp, value, name } = signal;

      return {
        timestamp: LocalDateTimeString(timestamp),
        signal: name,
        value: value,
      };
    })
    .flat();

export const CANSignalProvider = ({ token, children }) => {
  // auto scale polling if not getting response
  const durations = [10000, 30000, 60000, 120000];
  const delays = [500, 1500, 3000, 6000];
  const [vin, setVIN] = useState(null);
  const [signals, setSignals] = useState([]);
  const [delayIndex, setDelayIndex] = useState(0);

  useInterval(
    () => {
      getCANSignals()
    }, vin ? delays[delayIndex] : null
  )

  const getCANSignals = async () => {
    try {
      if (!vin) return;

      const date = new Date();
      date.setUTCSeconds(date.getUTCSeconds() - durations[delayIndex]);

      const result = await api.getCANSignals(vin, {
        after_utc: date,
      }, token);
      if (result.error)
        throw new Error(`Get CAN signals error. ${result.message}`);

      const items = transformSignals(result.data);

      if (items.length > 0) {
        setDelayIndex((index) => {
          if (index === 0) {
            return 0;
          }
          return index -= 1;
        });
        setSignals(items);
      } else {
        setDelayIndex((index) => {
          if (index < delays.length - 1) {
            return index += 1;
          }
          return index;
        });
        setSignals([BlankSignal("No signals")]);
      }
    } catch (e) {
      setSignals([BlankSignal(e.message)]);
    }
  };

  return (
    <CANSignalContext.Provider
      value={{
        duration: durations[delayIndex] / 1000,
        signals,
        setVIN,
      }}
    >
      {children}
    </CANSignalContext.Provider>
  );
};

export const useCANSignalContext = () => useContext(CANSignalContext);
