// app/api/newsletter/subscribe/route.ts
// API endpoint for newsletter subscription
import { NextRequest, NextResponse } from 'next/server';
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';

// Rate limiting map (in-memory, simple implementation)
// In production, use Redis or similar
const rateLimitMap = new Map<string, { count: number; resetTime: number }>();
const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute
const RATE_LIMIT_MAX_REQUESTS = 5; // 5 requests per minute

// CORS headers
const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'POST, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type',
};

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

// Validate email format
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
function sanitizeEmail(email: string): string {
  return email.trim().toLowerCase();
}

// Rate limiting check
function checkRateLimit(identifier: string): { allowed: boolean; remaining: number } {
  const now = Date.now();
  const record = rateLimitMap.get(identifier);
  
  // Clean up old entries periodically
  if (rateLimitMap.size > 10000) {
    const entries = Array.from(rateLimitMap.entries());
    for (const [key, value] of entries) {
      if (value.resetTime < now) {
        rateLimitMap.delete(key);
      }
    }
  }
  
  if (!record || record.resetTime < now) {
    // New window
    rateLimitMap.set(identifier, {
      count: 1,
      resetTime: now + RATE_LIMIT_WINDOW,
    });
    return { allowed: true, remaining: RATE_LIMIT_MAX_REQUESTS - 1 };
  }
  
  if (record.count >= RATE_LIMIT_MAX_REQUESTS) {
    return { allowed: false, remaining: 0 };
  }
  
  record.count++;
  return { allowed: true, remaining: RATE_LIMIT_MAX_REQUESTS - record.count };
}

// Handle OPTIONS (preflight)
export async function OPTIONS() {
  return new Response(null, { status: 204, headers: corsHeaders });
}

// Handle POST (subscribe)
export async function POST(request: NextRequest) {
  console.log('📧 Newsletter Subscribe API called');
  console.log('Time:', new Date().toISOString());
  
  try {
    // Rate limiting
    const clientIp = request.headers.get('x-forwarded-for') || 
                     request.headers.get('x-real-ip') || 
                     'unknown';
    const rateLimit = checkRateLimit(clientIp);
    
    if (!rateLimit.allowed) {
      console.log('❌ Rate limit exceeded for IP:', clientIp);
      return NextResponse.json(
        { 
          success: false, 
          message: 'リクエストが多すぎます。しばらくしてからもう一度お試しください。'
        },
        { 
          status: 429, 
          headers: {
            ...corsHeaders,
            'X-RateLimit-Remaining': '0',
            'Retry-After': '60',
          }
        }
      );
    }
    
    // Parse request body
    let body: { email?: string };
    try {
      body = await request.json();
    } catch (parseError) {
      console.error('❌ JSON parse error:', parseError);
      return NextResponse.json(
        { 
          success: false, 
          message: '有効なメールアドレスを入力してください。'
        },
        { status: 400, headers: corsHeaders }
      );
    }
    
    const { email } = body;
    
    // Validate email format
    if (!email || !isValidEmail(email)) {
      console.log('❌ Invalid email format:', email);
      return NextResponse.json(
        { 
          success: false, 
          message: '有効なメールアドレスを入力してください。'
        },
        { status: 400, headers: corsHeaders }
      );
    }
    
    // Sanitize email
    const sanitizedEmail = sanitizeEmail(email);
    console.log('✓ Email validated and sanitized:', sanitizedEmail);
    
    // Check for duplicate email
    const existing = await db
      .select({ id: newsletterSubscribers.id, isActive: newsletterSubscribers.isActive })
      .from(newsletterSubscribers)
      .where(and(
        eq(newsletterSubscribers.email, sanitizedEmail),
        eq(newsletterSubscribers.siteId, SITE_ID)
      ))
      .limit(1);
    
    if (existing.length > 0) {
      // Email already exists
      if (existing[0].isActive) {
        console.log('❌ Email already subscribed:', sanitizedEmail);
        return NextResponse.json(
          { 
            success: false, 
            message: 'このメールアドレスは既に登録されています。'
          },
          { status: 400, headers: corsHeaders }
        );
      } else {
        // Reactivate subscription
        console.log('✓ Reactivating subscription for:', sanitizedEmail);
        await db
          .update(newsletterSubscribers)
          .set({ 
            isActive: true, 
            subscribedAt: new Date(),
            unsubscribedAt: null 
          })
          .where(and(
            eq(newsletterSubscribers.email, sanitizedEmail),
            eq(newsletterSubscribers.siteId, SITE_ID)
          ));
        
        console.log('✓ Subscription reactivated successfully');
        return NextResponse.json(
          { 
            success: true, 
            message: 'ご登録ありがとうございます！'
          },
          { 
            status: 200, 
            headers: {
              ...corsHeaders,
              'X-RateLimit-Remaining': rateLimit.remaining.toString(),
            }
          }
        );
      }
    }
    
    // Insert new subscriber
    console.log('✓ Creating new subscription for:', sanitizedEmail);
    await db
      .insert(newsletterSubscribers)
      .values({
        email: sanitizedEmail,
        siteId: SITE_ID,
        subscribedAt: new Date(),
        isActive: true,
      });
    
    console.log('✓ Newsletter subscription created successfully');
    
    return NextResponse.json(
      { 
        success: true, 
        message: 'ご登録ありがとうございます！'
      },
      { 
        status: 200, 
        headers: {
          ...corsHeaders,
          'X-RateLimit-Remaining': rateLimit.remaining.toString(),
        }
      }
    );
    
  } catch (error) {
    console.error('=== Newsletter Subscribe API Error ===');
    console.error('Error:', error);
    console.error('Message:', error instanceof Error ? error.message : 'Unknown error');
    console.error('Stack:', error instanceof Error ? error.stack : undefined);
    
    return NextResponse.json(
      { 
        success: false, 
        message: 'エラーが発生しました。もう一度お試しください。'
      },
      { status: 500, headers: corsHeaders }
    );
  }
}
