import { useCallback } from 'react';
import { usePersSDK } from '../providers/PersSDKProvider';
/**
 * React hook for token operations in the PERS SDK
 *
 * Provides methods for fetching various types of tokens including credit, reward, and status tokens.
 * Supports both general token queries and specific contract-based token retrieval.
 *
 * @returns Token hook with methods for token management
 *
 * @example
 * ```typescript
 * function TokensComponent() {
 *   const { getTokens, getActiveCreditToken, getRewardTokens } = useTokens();
 *
 *   const loadTokens = async () => {
 *     try {
 *       const tokens = await getTokens();
 *       const creditToken = await getActiveCreditToken();
 *       console.log('Loaded tokens:', tokens);
 *       console.log('Active credit token:', creditToken);
 *     } catch (error) {
 *       console.error('Failed to load tokens:', error);
 *     }
 *   };
 *
 *   return <button onClick={loadTokens}>Load Tokens</button>;
 * }
 * ```
 */
export const useTokens = () => {
    const { sdk, isInitialized, isAuthenticated } = usePersSDK();
    if (!isAuthenticated && isInitialized) {
        console.warn('SDK not authenticated. Some token operations may fail.');
    }
    /**
     * Retrieves all tokens available to the current user
     *
     * @returns Promise resolving to array of tokens
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getTokens } = useTokens();
     * const tokens = await getTokens();
     * console.log('Available tokens:', tokens);
     * ```
     */
    const getTokens = useCallback(async () => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getTokens();
            return result;
        }
        catch (error) {
            console.error('Failed to fetch tokens:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    /**
     * Retrieves the currently active credit token
     *
     * @returns Promise resolving to active credit token
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getActiveCreditToken } = useTokens();
     * const creditToken = await getActiveCreditToken();
     * console.log('Active credit token:', creditToken.name);
     * ```
     */
    const getActiveCreditToken = useCallback(async () => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getActiveCreditToken();
            return result;
        }
        catch (error) {
            console.error('Failed to fetch active credit token:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    /**
     * Retrieves all reward tokens available in the system
     *
     * @returns Promise resolving to array of reward tokens
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getRewardTokens } = useTokens();
     * const rewardTokens = await getRewardTokens();
     * console.log('Reward tokens:', rewardTokens);
     * ```
     */
    const getRewardTokens = useCallback(async () => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getRewardTokens();
            return result;
        }
        catch (error) {
            console.error('Failed to fetch reward tokens:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    /**
     * Retrieves all available token types in the system
     *
     * @returns Promise resolving to array of token types
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getTokenTypes } = useTokens();
     * const types = await getTokenTypes();
     * console.log('Token types:', types);
     * ```
     */
    const getTokenTypes = useCallback(async () => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getTokenTypes();
            return result;
        }
        catch (error) {
            console.error('Failed to fetch token types:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    /**
     * Retrieves all status tokens (tokens that represent user status/achievements)
     *
     * @returns Promise resolving to array of status tokens
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getStatusTokens } = useTokens();
     * const statusTokens = await getStatusTokens();
     * console.log('Status tokens:', statusTokens);
     * ```
     */
    const getStatusTokens = useCallback(async () => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getStatusTokens();
            return result;
        }
        catch (error) {
            console.error('Failed to fetch status tokens:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    /**
     * Retrieves a specific token by its contract address and optional token ID
     *
     * @param contractAddress - The contract address of the token
     * @param contractTokenId - Optional specific token ID within the contract
     * @returns Promise resolving to the token data
     * @throws Error if SDK is not initialized
     *
     * @example
     * ```typescript
     * const { getTokenByContract } = useTokens();
     * const token = await getTokenByContract('0x123...', 'token-1');
     * console.log('Token from contract:', token);
     * ```
     */
    const getTokenByContract = useCallback(async (contractAddress, contractTokenId) => {
        if (!isInitialized || !sdk) {
            throw new Error('SDK not initialized. Call initialize() first.');
        }
        try {
            const result = await sdk.tokens.getTokenByContract(contractAddress, contractTokenId);
            return result;
        }
        catch (error) {
            console.error('Failed to fetch token by contract:', error);
            throw error;
        }
    }, [sdk, isInitialized]);
    return {
        getTokens,
        getActiveCreditToken,
        getRewardTokens,
        getTokenTypes,
        getStatusTokens,
        getTokenByContract,
        isAvailable: isInitialized && !!sdk?.tokens,
    };
};
