import { getIdToken, onAuthStateChanged } from "firebase/auth";
import { auth } from "./firebase";
import { TIPO_PROJECTO_FIREBASE } from "../constants";
const localStorageKey = "usr_jwt";
const {
  REACT_APP_CLOUD_FUNC: baseUrl,
  REACT_APP_PROJECT: tipoProyecto,
  REACT_APP_API_URL: apiUrl,
} = process.env;

const getCurrentToken = () => {
  return new Promise(async (resolve, reject) => {
    if (tipoProyecto === TIPO_PROJECTO_FIREBASE) {
      onAuthStateChanged(auth, (user) => {
        if (user) {
          getIdToken(user).then((token) => {
            if (token) {
              resolve(token);
            }
          });
        } else {
          resolve("");
        }
      });
    } else {
      const jwt = localStorage.getItem(localStorageKey);
      if (!jwt) reject("No hay sesión.");
      resolve(jwt);
    }
  });
};

const getHeaders = (token) => ({
  "Content-Type": "application/json",
  Accept: "application/json",
  Authorization: `Bearer ${token}`,
});

const getHeadersWithoutToken = () => ({
  "Content-Type": "application/json",
  Accept: "application/json",
});

const HttpService = {
  getCF: async (url, auth = true) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(baseUrl + url, {
      method: "GET",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
    });

    let serverResponse = await response.json();

    return {
      isError: response?.status !== 200 ? true : false,
      status: response?.status,
      resultado: serverResponse?.resultado || serverResponse || null,
      paginacion: serverResponse?.paginacion || null,
      mensaje: serverResponse?.mensaje || null,
    };
  },
  get: async (url, auth = true) => {
    debugger;
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(apiUrl + url, {
      method: "GET",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
    });

    let serverResponse = await response.json();

    return {
      isError: response?.status !== 200 ? true : false,
      status: response?.status,
      resultado: serverResponse?.resultado || serverResponse || null,
      paginacion: serverResponse?.paginacion || null,
      mensaje: serverResponse?.mensaje || null,
    };
  },
  postCF: async (url, data, auth = true, type = 1) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(baseUrl + url, {
      method: "POST",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
      body: JSON.stringify(data),
    });

    let serverResponse = null;
    try {
      if (type === 1) {
        serverResponse = await response.json();
      }
      if (type === 2) {
        serverResponse = await response.blob();
      }
    } catch (error) {
      console.log(error);
    }

    return {
      isError: response?.status !== 200 ? true : false,
      status: response?.status,
      errores: serverResponse?.errores || null,
      detalle: serverResponse?.detalle || null,
      mensaje: serverResponse?.mensaje || null,
      response: serverResponse || null,
    };
  },
  post: async (url, data, auth = true, type = 1) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(apiUrl + url, {
      method: "POST",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
      body: JSON.stringify(data),
    });

    let serverResponse = null;
    try {
      if (type === 1) {
        serverResponse = await response.json();
      }
      if (type === 2) {
        serverResponse = await response.blob();
      }
    } catch (error) {
      console.log(error);
    }

    return {
      isError: response?.status !== 200 ? true : false,
      status: response?.status,
      errores: serverResponse?.errores || null,
      detalle: serverResponse?.detalle || null,
      mensaje: serverResponse?.mensaje || null,
      response: serverResponse || null,
    };
  },
  delete: async (url, data, auth = true) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(baseUrl + url, {
      method: "DELETE",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
      body: JSON.stringify(data),
    });

    let serverResponse = await response.json();

    return {
      isError: response?.status !== 200 ? true : false,
      status: response?.status,
      errores: serverResponse?.errores || null,
      detalle: serverResponse?.detalle || null,
      mensaje: serverResponse?.mensaje || null,
    };
  },
  putCF: async (url, data, auth = true, type = 1) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(baseUrl + url, {
      method: "PUT",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
      body: JSON.stringify(data),
    });

    let serverResponse = null;
    try {
      if (type === 1) {
        serverResponse = await response.json();
      }
      if (type === 2) {
        serverResponse = await response.blob();
      }
    } catch (error) {
      console.log(error);
    }

    return {
      isError: response?.status >= 400 ? true : false,
      status: response?.status,
      errores: serverResponse?.errores || null,
      detalle: serverResponse?.detalle || null,
      mensaje: serverResponse?.mensaje || null,
      response: serverResponse || null,
    };
  },
  put: async (url, data, auth = true, type = 1) => {
    let token = null;
    if (auth) token = await getCurrentToken();
    const response = await fetch(apiUrl + url, {
      method: "PUT",
      headers: auth ? getHeaders(token) : getHeadersWithoutToken(),
      body: JSON.stringify(data),
    });

    let serverResponse = null;
    try {
      if (type === 1) {
        serverResponse = await response.json();
      }
      if (type === 2) {
        serverResponse = await response.blob();
      }
    } catch (error) {
      console.log(error);
    }

    return {
      isError: response?.status >= 400 ? true : false,
      status: response?.status,
      errores: serverResponse?.errores || null,
      detalle: serverResponse?.detalle || null,
      mensaje: serverResponse?.mensaje || null,
      response: serverResponse || null,
    };
  },
};

export default HttpService;
