// lib/utils/newsletter.ts
import { db } from '@/lib/db';
import { newsletterSubscribers } from '@/shared/schema';
import { eq, and } from 'drizzle-orm';

// Site isolation — matches shared DB pattern
const SITE_ID = 'ten-sura-game.com';

// Email validation regex (RFC 5322 simplified)
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

/**
 * Validate email format
 * @param email - Email address to validate
 * @returns Boolean indicating if email is valid
 */
export function isValidEmail(email: string): boolean {
  if (!email || typeof email !== 'string') {
    return false;
  }
  
  // Basic length check
  if (email.length < 5 || email.length > 255) {
    return false;
  }
  
  // Regex validation
  return EMAIL_REGEX.test(email.trim().toLowerCase());
}

/**
 * Sanitize email address
 * Trims whitespace and converts to lowercase
 * @param email - Email address to sanitize
 * @returns Sanitized email address
 */
export function sanitizeEmail(email: string): string {
  return email.trim().toLowerCase();
}

/**
 * Check if an email already exists in the database
 * @param email - Email address to check
 * @returns Object with exists flag and subscriber data if found
 */
export async function checkDuplicateEmail(email: string): Promise<{
  exists: boolean;
  subscriber?: {
    id: number;
    email: string;
    isActive: boolean;
    subscribedAt: Date | null;
    unsubscribedAt: Date | null;
  };
}> {
  try {
    const sanitizedEmail = sanitizeEmail(email);
    
    const result = await db
      .select()
      .from(newsletterSubscribers)
      .where(and(
        eq(newsletterSubscribers.email, sanitizedEmail),
        eq(newsletterSubscribers.siteId, SITE_ID)
      ))
      .limit(1);
    
    if (result.length === 0) {
      return { exists: false };
    }
    
    return {
      exists: true,
      subscriber: result[0],
    };
  } catch (error) {
    console.error('Error checking duplicate email:', error);
    throw error;
  }
}

/**
 * Subscribe an email to the newsletter
 * @param email - Email address to subscribe
 * @returns The created subscription or null if already exists
 */
export async function subscribeToNewsletter(email: string) {
  try {
    const normalizedEmail = email.toLowerCase().trim();
    
    // Check if email already exists
    const existing = await db
      .select()
      .from(newsletterSubscribers)
      .where(and(
        eq(newsletterSubscribers.email, normalizedEmail),
        eq(newsletterSubscribers.siteId, SITE_ID)
      ))
      .limit(1);

    if (existing.length > 0) {
      return { success: false, message: 'Email already subscribed', alreadyExists: true };
    }

    // Insert new subscription
    const [subscription] = await db
      .insert(newsletterSubscribers)
      .values({
        email: normalizedEmail,
        siteId: SITE_ID,
      })
      .returning();

    return { success: true, message: 'Successfully subscribed', data: subscription };
  } catch (error) {
    console.error('Error subscribing to newsletter:', error);
    return { success: false, message: 'Failed to subscribe', error };
  }
}

/**
 * Check if an email is already subscribed
 * @param email - Email address to check
 * @returns Boolean indicating if email exists
 */
export async function isEmailSubscribed(email: string): Promise<boolean> {
  try {
    const normalizedEmail = email.toLowerCase().trim();
    const result = await db
      .select()
      .from(newsletterSubscribers)
      .where(and(
        eq(newsletterSubscribers.email, normalizedEmail),
        eq(newsletterSubscribers.siteId, SITE_ID)
      ))
      .limit(1);

    return result.length > 0;
  } catch (error) {
    console.error('Error checking email subscription:', error);
    return false;
  }
}

/**
 * Get total number of newsletter subscribers
 * @returns Count of subscribers
 */
export async function getSubscriberCount(): Promise<number> {
  try {
    const result = await db
      .select()
      .from(newsletterSubscribers)
      .where(eq(newsletterSubscribers.siteId, SITE_ID));
    return result.length;
  } catch (error) {
    console.error('Error getting subscriber count:', error);
    return 0;
  }
}

/**
 * Unsubscribe an email from the newsletter
 * @param email - Email address to unsubscribe
 * @returns Success status
 */
export async function unsubscribeFromNewsletter(email: string) {
  try {
    const normalizedEmail = email.toLowerCase().trim();
    
    const result = await db
      .delete(newsletterSubscribers)
      .where(and(
        eq(newsletterSubscribers.email, normalizedEmail),
        eq(newsletterSubscribers.siteId, SITE_ID)
      ))
      .returning();

    if (result.length === 0) {
      return { success: false, message: 'Email not found' };
    }

    return { success: true, message: 'Successfully unsubscribed' };
  } catch (error) {
    console.error('Error unsubscribing from newsletter:', error);
    return { success: false, message: 'Failed to unsubscribe', error };
  }
}
