import AsyncStorage from '@react-native-async-storage/async-storage';
import api from './api';
import { AuthUser, TokenResponse, LoginCredentials, RegisterCredentials } from '../types';

const TOKEN_KEY = '@tipsharks_token';

/**
 * Decode a JWT token's payload (base64) without verifying the signature.
 * Used for client-side expiry checks only — never trust the payload for auth decisions.
 */
function decodeTokenPayload(token: string): Record<string, unknown> | null {
  try {
    const parts = token.split('.');
    if (parts.length !== 3) return null;
    const payload = parts[1];
    const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
    return JSON.parse(decoded);
  } catch {
    return null;
  }
}

/**
 * Check whether a JWT token is expired by inspecting its `exp` claim.
 * Returns `true` if the token is missing, malformed, or past its expiry.
 */
export function isTokenExpired(token: string | null): boolean {
  if (!token) return true;
  const payload = decodeTokenPayload(token);
  if (!payload) return true;
  const exp = payload.exp as number | undefined;
  if (!exp) return true;
  // Add 30-second buffer to avoid edge cases
  return Date.now() >= (exp * 1000) - 30000;
}

/**
 * Store the JWT token in AsyncStorage.
 */
async function storeToken(token: string): Promise<void> {
  try {
    await AsyncStorage.setItem(TOKEN_KEY, token);
  } catch {
    // If AsyncStorage fails (e.g. web), fall back to memory
    // The auth store will still hold the token in state
  }
}

/**
 * Retrieve the JWT token from AsyncStorage.
 */
async function getStoredToken(): Promise<string | null> {
  try {
    return await AsyncStorage.getItem(TOKEN_KEY);
  } catch {
    return null;
  }
}

/**
 * Remove the stored JWT token from AsyncStorage.
 */
async function clearStoredToken(): Promise<void> {
  try {
    await AsyncStorage.removeItem(TOKEN_KEY);
  } catch {
    // ignore
  }
}

/**
 * Register a new user and return the token response.
 */
export async function register(credentials: RegisterCredentials): Promise<TokenResponse> {
  const response = await api.post<TokenResponse>('/auth/register', credentials);
  await storeToken(response.data.access_token);
  return response.data;
}

/**
 * Log in an existing user and return the token response.
 */
export async function login(credentials: LoginCredentials): Promise<TokenResponse> {
  const response = await api.post<TokenResponse>('/auth/login', credentials);
  await storeToken(response.data.access_token);
  return response.data;
}

/**
 * Get the currently authenticated user's profile.
 * Uses the JWT token from the Authorization header (set by interceptor).
 */
export async function getCurrentUser(): Promise<AuthUser> {
  const response = await api.get<AuthUser>('/auth/me');
  return response.data;
}

/**
 * Log out: clear the stored token.
 */
export async function logout(): Promise<void> {
  await clearStoredToken();
}

export { getStoredToken, clearStoredToken };
