import React, { createContext, useContext, useEffect, useState } from 'react';
import api, { setAccessToken } from './api';
import { getGlobalStorage } from './storage';

export interface AccessToken {
  token: string;
  expiresIn: number;
  tokenType?: string;
  scope?: string;
  expiresAt: number;
}

interface AuthContextType {
  authStatus: 'auth' | 'loading' | 'fail';
  setToken: (token: AccessToken | undefined | null) => void;

}


const AuthContext = createContext<AuthContextType>(null!);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [authStatus, setAuthStatus] = useState<'auth' | 'loading' | 'fail'>('loading');


  const setToken = (nextToken: AccessToken | undefined | null) => {
    // tokenCache = nextToken;

    if (nextToken && nextToken.token && nextToken.expiresIn) {
      // if (!tokenCache.expiresAt) {
      nextToken.expiresAt = nextToken.expiresIn + Date.now() / 1000;
      // }

    } else {
      nextToken = null;
    }
    if (nextToken) {
      setAuthStatus('auth');
      getGlobalStorage().setObject("access_token", nextToken, nextToken.expiresIn);
    } else {
      setAuthStatus('fail');
      getGlobalStorage().remove("access_token");
    }
    setAccessToken(nextToken);
  };

  useEffect(() => {
    const token = getGlobalStorage().getObject("access_token");
    setToken(token);
  }, []);


  return (
    <AuthContext.Provider
      value={{
        authStatus,
        setToken,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuthContext() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuthContext must be used within an AuthProvider');
  }
  return context;
}

export function useAuth() {
  return useAuthContext();
}

export async function signIn(mobile: string, password: string) {
  const {
    token,
    expires_in
  } = await api.post<{
    token: string,
    expires_in: number,
  }>("/user/login", {
    mobile, password
  });
  return {
    token,
    expiresIn: expires_in
  } as AccessToken;
}

export async function smsSignIn(mobile: string, captcha: string) {
  const {
    token,
    expires_in
  } = await api.post<{
    token: string,
    expires_in: number,
  }>("/user/mobilelogin", {
    mobile, captcha
  });
  return {
    token,
    expiresIn: expires_in
  } as AccessToken;
}

export async function signUp(info: {
  mobile: string;
  captcha: string;
  password: string;
  name: string;
  email: string;
}) {
  const {
    token,
    expires_in
  } = await api.post<{
    token: string,
    expires_in: number,
  }>("/user/register", info);
  return {
    token,
    expiresIn: expires_in
  } as AccessToken;
}




export async function signOut() {
  return api.get("/user/logout")
}