import sgMail from '@sendgrid/mail';
import { User } from '@shared/schema';
import crypto from 'crypto';
import { storage } from './storage';

if (!process.env.SENDGRID_API_KEY) {
  throw new Error('SENDGRID_API_KEY environment variable is not set');
}

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

// Store activation tokens in memory (should be moved to database in production)
const activationTokens = new Map<string, { userId: number, expires: Date, isUsed: boolean }>();

export async function sendInvitationEmail(
  user: User,
  template: { subject: string; body: string },
  eventName: string
) {
  // Generate a unique token for the activation link
  const token = crypto.randomBytes(32).toString('hex');
  console.log(`Generated activation token for user ${user.id}:`, token);

  // Store the token with expiration (24 hours) and used status
  const expires = new Date();
  expires.setHours(expires.getHours() + 24);
  activationTokens.set(token, { userId: user.id, expires, isUsed: false });
  console.log(`Stored token data:`, { userId: user.id, expires });

  // Generate the activation link using REPLIT_DOMAINS
  const baseUrl = process.env.REPLIT_DOMAINS ? 
    `https://${process.env.REPLIT_DOMAINS.split(',')[0]}` : 
    'http://localhost:3000';
  const activationLink = `${baseUrl}/activate-account/${token}`;
  console.log(`Generated activation link:`, activationLink);

  // Replace template variables
  let emailBody = template.body
    .replace('[Name]', user.name)
    .replace('[ACTIVATION_LINK]', activationLink)
    .replace('[Event Name]', eventName);

  let emailSubject = template.subject
    .replace('[Name]', user.name)
    .replace('[Event Name]', eventName);

  const msg = {
    to: user.email,
    from: process.env.SENDGRID_FROM_EMAIL || 'noreply@yourdomain.com',
    subject: emailSubject,
    text: emailBody,
    html: emailBody.replace(/\n/g, '<br>'),
  };

  try {
    await sgMail.send(msg);
    console.log(`Successfully sent invitation email to ${user.email}`);
    return true;
  } catch (error) {
    console.error('Error sending email:', error);
    throw new Error('Failed to send invitation email');
  }
}

export function validateActivationToken(token: string): number | null {
  console.log('Validating token:', token);
  const tokenData = activationTokens.get(token);
  console.log('Found token data:', tokenData);

  if (!tokenData) {
    console.log('Token not found');
    return null;
  }

  if (tokenData.isUsed) {
    console.log('Token has already been used');
    return null;
  }

  if (tokenData.expires < new Date()) {
    console.log('Token expired');
    activationTokens.delete(token);
    return null;
  }

  // Don't delete the token after validation, only after successful activation
  console.log('Token valid, returning user ID:', tokenData.userId);
  return tokenData.userId;
}

export function markTokenAsUsed(token: string): void {
  const tokenData = activationTokens.get(token);
  if (tokenData) {
    tokenData.isUsed = true;
    activationTokens.set(token, tokenData);
    console.log(`Marked token ${token} as used`);
  }
}