// packages/functions/src/shared/utils.ts

/**
 * @fileoverview Shared utilities for Firebase and Vercel functions
 * @description Common utilities that can be used by both Firebase and Vercel function implementations
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

import Stripe from 'stripe';

import { DoNotDevError } from '@donotdev/core/server';
import {
  getFirebaseAdminAuth,
  getFirebaseAdminFirestore,
  initFirebaseAdmin,
} from '@donotdev/firebase/server';

// Re-export DoNotDevError for external use
export { DoNotDevError };
import type { OAuthPartnerId } from '@donotdev/core/server';

/**
 * Get Firestore instance using @donotdev/firebase/server
 * Provider handles initialization and caching
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function getFirestore() {
  return getFirebaseAdminFirestore();
}

/**
 * Get Auth instance using @donotdev/firebase/server
 * Provider handles initialization and caching
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function getAuth() {
  return getFirebaseAdminAuth();
}

// Lazy initialization of Stripe to avoid errors during Firebase analysis
let _stripe: Stripe | null = null;

/**
 * Get Stripe instance with lazy initialization
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function getStripe(): Stripe {
  if (!_stripe) {
    const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
    if (!STRIPE_SECRET_KEY) {
      throw new Error('STRIPE_SECRET_KEY environment variable is required');
    }

    const STRIPE_API_VERSION = process.env.STRIPE_API_VERSION;
    if (!STRIPE_API_VERSION) {
      throw new Error('STRIPE_API_VERSION environment variable is required');
    }

    _stripe = new Stripe(STRIPE_SECRET_KEY, {
      apiVersion: STRIPE_API_VERSION as any,
    });
  }
  return _stripe;
}

/**
 * Lazy-initialized Stripe instance proxy
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export const stripe = new Proxy({} as Stripe, {
  get(target, prop) {
    return getStripe()[prop as keyof Stripe];
  },
});

/**
 * Assert that a user is authenticated
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function assertAuthenticated(auth: any): string {
  if (!auth || !auth.uid) {
    throw new Error('User must be authenticated');
  }
  return auth.uid;
}

/**
 * Validates that required Stripe environment variables are set
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function validateStripeEnvironment(): void {
  const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
  if (!STRIPE_SECRET_KEY) {
    throw new Error('Missing STRIPE_SECRET_KEY environment variable');
  }
}

/**
 * Creates a standardized success response
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function createSuccessResponse<T>(data: T): { success: true; data: T } {
  return {
    success: true,
    data,
  };
}

/**
 * Creates a standardized error response
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function createErrorResponse(error: unknown): {
  success: false;
  error: {
    code: string;
    message: string;
    details?: any;
  };
} {
  if (error instanceof DoNotDevError) {
    return {
      success: false,
      error: {
        code: error.code,
        message: error.message,
        details: error.details,
      },
    };
  }

  if (error instanceof Error) {
    return {
      success: false,
      error: {
        code: 'internal',
        message: error.message,
      },
    };
  }

  return {
    success: false,
    error: {
      code: 'internal',
      message: 'An unexpected error occurred',
    },
  };
}

/**
 * Updates user subscription in Firebase
 * TODO: Implement this function based on your Firebase setup
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export async function updateUserSubscription(
  firebaseUid: string,
  subscription: any
): Promise<void> {
  // TODO: Implement subscription update logic
  console.log('Updating subscription for user:', firebaseUid, subscription.id);
}

/**
 * Gets user subscription from Firebase
 * TODO: Implement this function based on your Firebase setup
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export async function getUserSubscription(firebaseUid: string): Promise<any> {
  // TODO: Implement subscription retrieval logic
  console.log('Getting subscription for user:', firebaseUid);
  return null;
}

/**
 * Cancels user subscription
 * TODO: Implement this function based on your Firebase setup
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export async function cancelUserSubscription(
  firebaseUid: string,
  subscription: any
): Promise<void> {
  // TODO: Implement subscription cancellation logic
  console.log('Canceling subscription for user:', firebaseUid, subscription.id);
}

/**
 * Handles subscription cancellation
 * TODO: Implement this function based on your Firebase setup
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export async function handleSubscriptionCancellation(
  firebaseUid: string,
  subscription: any
): Promise<void> {
  // TODO: Implement subscription cancellation handling
  console.log(
    'Handling subscription cancellation for user:',
    firebaseUid,
    subscription.id
  );
}

/**
 * Asserts that a user has admin privileges
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function assertAdmin(uid: string): string {
  if (!uid) {
    throw new Error('Authentication required');
  }

  // TODO: Implement admin check logic
  // For now, just return the uid
  return uid;
}

/**
 * Validates document data
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function validateDocument(data: any, schema?: any): void {
  if (!data || typeof data !== 'object') {
    throw new Error('Invalid document data');
  }

  if (Array.isArray(data)) {
    throw new Error('Document data cannot be an array');
  }
}

/**
 * Verifies Firebase auth token
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export async function verifyFirebaseAuthToken(token: string): Promise<string> {
  // TODO: Implement Firebase token verification
  // For now, just return a mock uid
  return 'mock-uid';
}

/**
 * Finds references to a document
 *
 * @version 0.0.1
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
export function findReferences(collection: string, docId: string): string[] {
  // TODO: Implement reference finding logic
  return [];
}
