import { BehaviorSubject } from 'rxjs';
import { API_USER_SIGN_IN, FIREBASE_LOGIN } from './config';

const currentUserSubject = new BehaviorSubject(sessionStorage.getItem('currentUser') !== undefined ? JSON.parse(sessionStorage.getItem('currentUser')) : {});


export const authenticationService = {
  login,
  logout,
  updateClass,
  registerUser,
  authenticate,
  loginToSystem,
  refreshFireToken,
  resetPassword,
  newPassword,
  fetchUserEmail,
  verifyEmail,
  currentUser: currentUserSubject.asObservable(),
  get currentUserValue() { return currentUserSubject.value },
  get currentClassValue() { return sessionStorage.getItem('currentClass') },
  get currentClassNameValue() { return sessionStorage.getItem('currentClassName') }
};

async function registerUser(email, password) {
  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email, password, returnSecureToken: true })
  };
  const response = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions);

  const data = await response.json();
  return data;

}

function login(username, password, saveAuth) {
  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email: username, password, returnSecureToken: true })
  };

  // return fetch(`${config.apiUrl}/users/authenticate`, requestOptions)
  return fetch(FIREBASE_LOGIN, requestOptions)
    .then(response => {
      if (response.ok) {
        return response.json();
      }
    })
    .then(token => {

      //check to see if the credentials were received
      // console.log(token.idToken);
      if (!token) {
        throw new Error("Credentials not correct, please check and try again.")
      }

      // store user details and jwt token in local storage to keep user logged in between page refreshes
      sessionStorage.setItem('currentToken', token.idToken);
      saveAuth && localStorage.setItem('currentToken', token.idToken);
      sessionStorage.setItem('refreshToken', token.refreshToken);
      saveAuth && localStorage.setItem('refreshToken', token.refreshToken);
      let user = loginToSystem(saveAuth);
      currentUserSubject.next(user);          //Why is this written twice?
      return user;
    });
}


// TOKEN VERIFICATION

function loginToSystem(saveAuth) {
  let idToken = sessionStorage.getItem('currentToken');
  const requestOptions = {
    method: "POST",
    headers: {
      "Access-Control-Allow-Origin": "*",
      Accept: "application/json",
      "Content-Type": "application/json",
      Authorization: "Bearer ".concat(idToken),
    },
  };
  return fetch(
    API_USER_SIGN_IN,
    requestOptions
  )
    .then((response) => {
      if (response.ok) {
        return response.json();
      }
      // window.localStorage.clear();
      // history.push("/login");
    })
    .then((user) => {
      // console.log(user.result);
      let userResult = user.result;
      userResult['jwtToken'] = sessionStorage.getItem('currentToken');
      userResult['refreshToken'] = sessionStorage.getItem('refreshToken');
      sessionStorage.setItem('currentUser', JSON.stringify(userResult));
      saveAuth && localStorage.setItem('currentUser', JSON.stringify(userResult));
      currentUserSubject.next(userResult);        // Check login function. This is written twice
      return userResult;
    })
    .catch((error) => {
      console.error('Error:', error);      // This was removed but I added it back
    });
}

function authenticate(auth) {
  const requestOptions = {
    method: 'GET',
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    }
  };

  // return fetch(`${config.apiUrl}/users/authenticate`, requestOptions)
  return fetch('https://api.practicekea.com/api-user/v1/Users/VerifyAccount/' + auth, requestOptions)
    .then((response) => {
      if (response.ok) {
        // console.log(response.json());
        return response.json();
      }
    })
    .then(data => {
      return data;
    }).catch((error) => {
      //  console.error('Error:', error);
    });

}


function updateClass(className, classId) {
  sessionStorage.setItem('currentClass', classId);
  sessionStorage.setItem('currentClassName', className);

}
function logout() {
  // remove user from local storage to log user out
  sessionStorage.removeItem('currentUser');
  sessionStorage.removeItem('currentToken');
  sessionStorage.removeItem('refreshToken');
  sessionStorage.removeItem('currentClass');
  sessionStorage.removeItem('currentClassName');
  localStorage.removeItem('currentUser');
  localStorage.removeItem('currentToken');
  localStorage.removeItem('refreshToken');
  localStorage.removeItem('currentClass');
  localStorage.removeItem('currentClassName');
  currentUserSubject.next(null);
}

function refreshFireToken() {
  let refreshTokenInStore = sessionStorage.getItem('refreshToken');
  let currentUserStored = JSON.parse(sessionStorage.getItem('currentUser'));
  if (!refreshTokenInStore) {
    let json = JSON.parse(localStorage.getItem('currentUser'));
    refreshTokenInStore = json.refreshToken;
    currentUserStored = json;
  }
  // console.log(refreshTokenInStore);
  if (!refreshTokenInStore) {
    throw "No login found";
  }
  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ grant_type: 'refresh_token', refresh_token: refreshTokenInStore })
  };

  return fetch(`https://securetoken.googleapis.com/v1/token?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions)
    .then(response => {
      if (response.ok) {
        return response.json();
      }
    })
    .then(token => {

      // check to see if the credentials were received
      if (!token) {
        throw new Error("Credentials not correct, please check and try again.")
      }

      // store user details and jwt token in session storage to keep user logged in between page refreshes
      sessionStorage.setItem('currentToken', token.id_token);
      sessionStorage.setItem('refreshToken', token.refresh_token);

      if (currentUserStored.id) {
        currentUserStored.refreshToken = token.refresh_token;
        currentUserStored.jwtToken = token.id_token;
        sessionStorage.setItem('currentUser', JSON.stringify(currentUserStored));
        currentUserSubject.next(currentUserStored);
        return currentUserStored;
      }

      // cases when currentUserStored does not exist
      let user = loginToSystem();             // may not be needed everytime
      currentUserSubject.next(user);          //Why is this written twice?
      return user;
    }).catch((err) => {
      // refreshFireToken();
      console.error(err);
      throw "No access token found, trying again...";
    });
}

async function resetPassword(email) {
  if (email) {
    const requestOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ requestType: 'PASSWORD_RESET', email })
    };
    try {
      const res = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions)
      const data = await res.json();
      if (res.status === 400) {
        throw data;
      }
      return data;
    } catch (err) {
      throw err;
    }

  } else {
    throw "Please enter an email address";
  }
}

async function newPassword(oobCode, newPassword) {
  if (newPassword && oobCode) {
    const requestOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ oobCode, newPassword })
    };
    try {
      const res = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions);
      const data = await res.json();
      if (res.status === 400) {
        throw data;
      }
      return data;
    } catch (err) {
      throw err;
    }
  } else {
    throw "Please enter your new password";
  }
}

async function fetchUserEmail(oobCode) {
  if (oobCode) {
    const requestOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ oobCode })
    };
    try {
      const res = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:resetPassword?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions);
      const data = await res.json();
      if (res.status === 400) {
        throw data;
      }
      return data;
    } catch (err) {
      throw err;
    }
  } else {
    throw { error: "Please check your reset password link" }
  }
}

async function verifyEmail(oobCode) {
  if (oobCode) {
    const requestOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ oobCode })
    };
    try {
      const res = await fetch(`https://identitytoolkit.googleapis.com/v1/accounts:update?key=${process.env.REACT_APP_FIREBASE_API_KEY}`, requestOptions);
      const data = await res.json();
      if (res.status === 400) {
        throw data;
      }
      return data;
    } catch (err) {
      throw err;
    }
  } else {
    throw { error: "Please check if your verification email link is correct." }
  }
}
