import Cookies from "js-cookie";
import moment from "moment";
import { Response } from "redux/Common/types";
import { SpotifyTrack, SpotifyUser } from "./../redux/User/types";
import { SpotifyApi } from "./api/spotify.api";

import { FLAGS, isOn } from "@komi-app/flags-sdk";

export const KOMI_SPOTIFY_ACCESS_TOKEN = "KOMI_SPOTIFY_TALENT_ACCESS_TOKEN";
export const KOMI_SPOTIFY_REFRESH_TOKEN = "KOMI_SPOTIFY_TALENT_REFRESH_TOKEN";

export default class SpotifyService {
  private __jwt = "";

  constructor(private readonly api: SpotifyApi) {
    this.api = api;
  }

  set jwt(value: string) {
    this.__jwt = value;
  }

  get jwt(): string {
    return this.__jwt?.length
      ? this.__jwt
      : Cookies.get(KOMI_SPOTIFY_ACCESS_TOKEN) || "";
  }

  logout = (): void => {
    this.__jwt = "";
    Cookies.remove(KOMI_SPOTIFY_ACCESS_TOKEN);
    Cookies.remove(KOMI_SPOTIFY_REFRESH_TOKEN);
  };

  signin = ({ access_token, expires_in, refresh_token }: SpotifyUser): void => {
    const isSpotifyFixEnabled = isOn(FLAGS.FIX_GS46_SPOTIFY_AUTH_FIX);

    if (isSpotifyFixEnabled) {
      const accessTokenExpirySeconds = parseInt(expires_in);
      const accessTokenCookieExpirySeconds = accessTokenExpirySeconds - 300; // force refresh 5 minutes before expiry
      const accessTokenCookieExpiryDate = moment()
        .add(accessTokenCookieExpirySeconds, "seconds")
        .toDate();

      Cookies.set(KOMI_SPOTIFY_ACCESS_TOKEN, access_token, {
        expires: accessTokenCookieExpiryDate,
      });

      const refreshTokenCookieExpiryDate = moment()
        .add(accessTokenExpirySeconds, "seconds")
        .toDate();
      Cookies.set(KOMI_SPOTIFY_REFRESH_TOKEN, refresh_token || "", {
        expires: refreshTokenCookieExpiryDate,
      });
    } else {
      const expireDate = moment().add(3600, "seconds").toDate();
      Cookies.set(KOMI_SPOTIFY_ACCESS_TOKEN, access_token, {
        expires: expireDate,
      });
      Cookies.set(KOMI_SPOTIFY_REFRESH_TOKEN, refresh_token || "", {
        expires: expireDate,
      });
    }
  };

  getSpotifyById = (
    type: string,
    id: string
  ): Promise<Response<SpotifyTrack>> => {
    return this.api.getSpotifyById(type, id);
  };
}
