'use client';

/**
 * API Key Context Provider
 *
 * Centralized state management for API key functionality across demo pages.
 * Provides:
 * - API key validation and storage
 * - UI state management (expanded, visibility)
 * - Focus method for external components
 * - Automatic validation of stored keys on mount
 *
 * Phase 1 of centralizing apikey functionality (previously duplicated across demo pages)
 */

import React, { createContext, useContext, useState, useEffect, useRef, useCallback } from 'react';
import {
  validateApiKeyRequest,
  getStoredKey,
  setStoredKey,
  clearStoredKey,
  type ApiKeyContextValue,
  type ApiKeyProviderProps,
  type ApiKeyInfo,
} from '@/lib/apikey';

// Create context with undefined default (will error if used outside provider)
const ApiKeyContext = createContext<ApiKeyContextValue | undefined>(undefined);

/**
 * API Key Provider Component
 *
 * Wraps the application to provide global API key state and actions
 */
export function ApiKeyProvider({ children, onValidationSuccess }: ApiKeyProviderProps) {
  // Data State
  const [apiKey, setApiKeyState] = useState('');
  const [apiKeyValidated, setApiKeyValidated] = useState(false);
  const [apiKeyInfo, setApiKeyInfo] = useState<ApiKeyInfo | null>(null);
  const [apiKeyError, setApiKeyError] = useState('');
  const [validatingKey, setValidatingKey] = useState(false);
  const [isReady, setIsReady] = useState(false);

  // UI State (grouped)
  const [expanded, setExpandedState] = useState(false);
  const [keyVisible, setKeyVisible] = useState(false);

  // Refs
  const inputRef = useRef<HTMLInputElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  /**
   * Validate stored API key on mount
   */
  const validateStoredApiKey = useCallback(
    async (keyToValidate: string) => {
      setValidatingKey(true);
      setApiKeyError('');

      const result = await validateApiKeyRequest(keyToValidate);

      if (result.success && result.keyInfo) {
        setApiKeyValidated(true);
        setApiKeyInfo(result.keyInfo);
        setApiKeyState(keyToValidate);

        // Call optional success callback
        onValidationSuccess?.(result.keyInfo);
      } else {
        // Stored key is invalid, clear it
        clearStoredKey();
        setApiKeyError(result.error || 'Stored API key is invalid or expired');
        setApiKeyValidated(false);
      }

      setValidatingKey(false);
      setIsReady(true);
    },
    [onValidationSuccess]
  );

  /**
   * Initialize: check for stored API key
   */
  useEffect(() => {
    const storedKey = getStoredKey();
    if (storedKey) {
      validateStoredApiKey(storedKey);
    } else {
      setIsReady(true);
    }
  }, [validateStoredApiKey]);

  /**
   * Validate API key (user-triggered)
   */
  const validateApiKey = useCallback(async () => {
    setValidatingKey(true);
    setApiKeyError('');

    const result = await validateApiKeyRequest(apiKey);

    if (result.success && result.keyInfo) {
      setApiKeyValidated(true);
      setApiKeyInfo(result.keyInfo);
      setStoredKey(apiKey);

      // Collapse widget after successful validation
      setExpandedState(false);

      // Call optional success callback
      onValidationSuccess?.(result.keyInfo);
    } else {
      setApiKeyError(result.error || 'Validation failed');
      setApiKeyValidated(false);
    }

    setValidatingKey(false);
  }, [apiKey, onValidationSuccess]);

  /**
   * Revoke API key
   * Optionally accepts a cleanup function for page-specific state
   */
  const revokeApiKey = useCallback((clearPageState?: () => void) => {
    clearStoredKey();
    setApiKeyState('');
    setApiKeyValidated(false);
    setApiKeyInfo(null);
    setApiKeyError('');
    setExpandedState(true); // Expand to show input after revoke

    // Call optional page-specific cleanup
    clearPageState?.();
  }, []);

  /**
   * Toggle API key visibility
   */
  const toggleKeyVisibility = useCallback(() => {
    setKeyVisible((prev) => !prev);
  }, []);

  /**
   * Set expanded state
   */
  const setExpanded = useCallback((value: boolean) => {
    setExpandedState(value);
  }, []);

  /**
   * Set API key value
   */
  const setApiKey = useCallback((key: string) => {
    setApiKeyState(key);
    setApiKeyError(''); // Clear error when user types
  }, []);

  /**
   * Focus method - for external components to trigger focus
   * Expands widget, focuses input, and scrolls into view
   */
  const focus = useCallback(() => {
    setExpandedState(true);

    // Wait for expansion animation, then focus
    setTimeout(() => {
      inputRef.current?.focus();
      // TODO: don't need because it's always visible
      // containerRef.current?.scrollIntoView({
      //   behavior: 'smooth',
      //   block: 'center',
      // });
    }, 100);
  }, []);

  const value: ApiKeyContextValue = {
    // Data State
    apiKey,
    apiKeyValidated,
    apiKeyInfo,
    apiKeyError,
    validatingKey,
    isReady,

    // UI State
    ui: {
      expanded,
      keyVisible,
    },

    // Actions
    setApiKey,
    validateApiKey,
    revokeApiKey,
    toggleKeyVisibility,
    setExpanded,

    // Focus method
    focus,
    inputRef,
    containerRef,
  };

  return (
    <ApiKeyContext.Provider value={value}>
      <div ref={containerRef}>{children}</div>
    </ApiKeyContext.Provider>
  );
}

/**
 * useApiKey Hook
 *
 * Access API key context values and actions
 * Must be used within ApiKeyProvider
 *
 * @example
 * const { apiKey, apiKeyValidated, validateApiKey, focus } = useApiKey();
 */
export function useApiKey(): ApiKeyContextValue {
  const context = useContext(ApiKeyContext);

  if (context === undefined) {
    throw new Error('useApiKey must be used within an ApiKeyProvider');
  }

  return context;
}

// Export inputRef for ApiKeyWidget to use
export { ApiKeyContext };
