/**
 * Referral Invite System
 * Handles email/SMS invites with customizable messages and tracking
 */

import { invokeLLM } from './_core/llm.ts';

export type InviteChannel = 'email' | 'sms' | 'whatsapp';
export type InviteStatus = 'pending' | 'sent' | 'accepted' | 'expired';

export interface ReferralInvite {
  id: string;
  referrerId: number;
  referrerName: string;
  referrerEmail: string;
  inviteeEmail?: string;
  inviteePhone?: string;
  channel: InviteChannel;
  status: InviteStatus;
  customMessage?: string;
  inviteCode: string;
  inviteLink: string;
  createdAt: Date;
  expiresAt: Date;
  acceptedAt?: Date;
  acceptedByUserId?: number;
  trackingData: {
    sent: boolean;
    opened: boolean;
    clicked: boolean;
    converted: boolean;
  };
}

export interface InviteTemplate {
  id: string;
  name: string;
  subject: string;
  body: string;
  channel: InviteChannel;
  variables: string[];
}

/**
 * Generate unique invite code
 */
export function generateInviteCode(): string {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let code = 'INVITE_';
  for (let i = 0; i < 8; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return code;
}

/**
 * Create referral invite
 */
export async function createReferralInvite(
  referrerId: number,
  referrerName: string,
  referrerEmail: string,
  inviteeEmail: string | undefined,
  inviteePhone: string | undefined,
  channel: InviteChannel,
  customMessage?: string
): Promise<ReferralInvite> {
  const inviteCode = generateInviteCode();
  const inviteLink = `https://coinkrazy.com/join?ref=${inviteCode}`;

  const invite: ReferralInvite = {
    id: `invite_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
    referrerId,
    referrerName,
    referrerEmail,
    inviteeEmail,
    inviteePhone,
    channel,
    status: 'pending',
    customMessage,
    inviteCode,
    inviteLink,
    createdAt: new Date(),
    expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
    trackingData: {
      sent: false,
      opened: false,
      clicked: false,
      converted: false,
    },
  };

  return invite;
}

/**
 * Generate personalized invite message using LLM
 */
export async function generatePersonalizedInviteMessage(
  referrerName: string,
  customMessage?: string
): Promise<string> {
  const prompt = `Generate a friendly and engaging referral invite message for CoinKrazy (a sweepstakes social casino).
  
Referrer Name: ${referrerName}
${customMessage ? `Custom Message Template: ${customMessage}` : ''}

The message should:
- Be warm and personal
- Highlight the fun and excitement of CoinKrazy
- Mention the referral benefits
- Include a call-to-action
- Be concise (2-3 sentences)

Generate only the message text, no additional commentary.`;

  const response = await invokeLLM({
    messages: [
      {
        role: 'system',
        content: 'You are a friendly copywriter for a social casino app. Generate engaging referral messages.',
      },
      {
        role: 'user',
        content: prompt,
      },
    ],
  });

  return response.choices[0]?.message?.content || 'Join me on CoinKrazy and earn amazing rewards!';
}

/**
 * Send email invite
 */
export async function sendEmailInvite(invite: ReferralInvite): Promise<boolean> {
  if (!invite.inviteeEmail) {
    return false;
  }

  try {
    const message = invite.customMessage || 'Join me on CoinKrazy!';

    // In production, use email service (Brevo, SendGrid, etc.)
    console.log(`[Email] Sending invite to ${invite.inviteeEmail}`);
    console.log(`Subject: ${invite.referrerName} invited you to CoinKrazy`);
    console.log(`Message: ${message}`);
    console.log(`Link: ${invite.inviteLink}`);

    return true;
  } catch (error) {
    console.error('Failed to send email invite:', error);
    return false;
  }
}

/**
 * Send SMS invite
 */
export async function sendSMSInvite(invite: ReferralInvite): Promise<boolean> {
  if (!invite.inviteePhone) {
    return false;
  }

  try {
    const message = `${invite.referrerName} invited you to CoinKrazy! Join now: ${invite.inviteLink}`;

    // In production, use SMS service (Twilio, etc.)
    console.log(`[SMS] Sending to ${invite.inviteePhone}`);
    console.log(`Message: ${message}`);

    return true;
  } catch (error) {
    console.error('Failed to send SMS invite:', error);
    return false;
  }
}

/**
 * Send WhatsApp invite
 */
export async function sendWhatsAppInvite(invite: ReferralInvite): Promise<boolean> {
  if (!invite.inviteePhone) {
    return false;
  }

  try {
    const message = `Hey! 👋 ${invite.referrerName} invited me to CoinKrazy - an awesome social casino! 🎰✨\n\nJoin with my link and we both earn rewards: ${invite.inviteLink}`;

    // In production, use WhatsApp API
    console.log(`[WhatsApp] Sending to ${invite.inviteePhone}`);
    console.log(`Message: ${message}`);

    return true;
  } catch (error) {
    console.error('Failed to send WhatsApp invite:', error);
    return false;
  }
}

/**
 * Send invite through specified channel
 */
export async function sendInvite(invite: ReferralInvite): Promise<boolean> {
  let success = false;

  switch (invite.channel) {
    case 'email':
      success = await sendEmailInvite(invite);
      break;
    case 'sms':
      success = await sendSMSInvite(invite);
      break;
    case 'whatsapp':
      success = await sendWhatsAppInvite(invite);
      break;
  }

  if (success) {
    invite.status = 'sent';
    invite.trackingData.sent = true;
  }

  return success;
}

/**
 * Track invite open (for email)
 */
export function trackInviteOpen(invite: ReferralInvite): void {
  invite.trackingData.opened = true;
}

/**
 * Track invite click
 */
export function trackInviteClick(invite: ReferralInvite): void {
  invite.trackingData.clicked = true;
}

/**
 * Track invite acceptance
 */
export function trackInviteAcceptance(invite: ReferralInvite, newUserId: number): void {
  invite.status = 'accepted';
  invite.acceptedAt = new Date();
  invite.acceptedByUserId = newUserId;
  invite.trackingData.converted = true;
}

/**
 * Check if invite is expired
 */
export function isInviteExpired(invite: ReferralInvite): boolean {
  return new Date() > invite.expiresAt;
}

/**
 * Get invite templates
 */
export function getInviteTemplates(): InviteTemplate[] {
  return [
    {
      id: 'template_1',
      name: 'Casual Friend',
      subject: '{{referrerName}} invited you to CoinKrazy!',
      body: `Hey! {{referrerName}} thinks you'd love CoinKrazy. Join now and get exclusive rewards!

Click here: {{inviteLink}}

See you there!`,
      channel: 'email',
      variables: ['referrerName', 'inviteLink'],
    },
    {
      id: 'template_2',
      name: 'Exciting Opportunity',
      subject: 'Join {{referrerName}} on CoinKrazy - Win Big! 🎰',
      body: `You're invited to CoinKrazy by {{referrerName}}!

Experience the thrill of our sweepstakes social casino with:
✨ Amazing games and prizes
🎁 Generous referral rewards
💰 Exclusive bonuses

Join now: {{inviteLink}}`,
      channel: 'email',
      variables: ['referrerName', 'inviteLink'],
    },
    {
      id: 'template_3',
      name: 'SMS Short',
      subject: '',
      body: `{{referrerName}} invited you to CoinKrazy! 🎰 Join now: {{inviteLink}}`,
      channel: 'sms',
      variables: ['referrerName', 'inviteLink'],
    },
    {
      id: 'template_4',
      name: 'WhatsApp Fun',
      subject: '',
      body: `Hey! 👋 {{referrerName}} just invited me to CoinKrazy! 🎰✨

It's an awesome social casino with real prizes. Join with my link and we both get rewards:

{{inviteLink}}

Let's play together! 🎉`,
      channel: 'whatsapp',
      variables: ['referrerName', 'inviteLink'],
    },
  ];
}

/**
 * Apply template to invite
 */
export function applyTemplate(template: InviteTemplate, invite: ReferralInvite): string {
  let message = template.body;

  message = message.replace('{{referrerName}}', invite.referrerName);
  message = message.replace('{{inviteLink}}', invite.inviteLink);
  message = message.replace('{{inviteeEmail}}', invite.inviteeEmail || '');
  message = message.replace('{{inviteePhone}}', invite.inviteePhone || '');

  return message;
}

/**
 * Get invite statistics for referrer
 */
export interface InviteStats {
  totalInvites: number;
  sentInvites: number;
  acceptedInvites: number;
  pendingInvites: number;
  conversionRate: number;
  byChannel: Record<InviteChannel, number>;
}

export function calculateInviteStats(invites: ReferralInvite[]): InviteStats {
  const stats: InviteStats = {
    totalInvites: invites.length,
    sentInvites: invites.filter((i) => i.trackingData.sent).length,
    acceptedInvites: invites.filter((i) => i.status === 'accepted').length,
    pendingInvites: invites.filter((i) => i.status === 'pending').length,
    conversionRate: 0,
    byChannel: {
      email: 0,
      sms: 0,
      whatsapp: 0,
    },
  };

  // Calculate conversion rate
  if (stats.sentInvites > 0) {
    stats.conversionRate = (stats.acceptedInvites / stats.sentInvites) * 100;
  }

  // Count by channel
  invites.forEach((invite) => {
    stats.byChannel[invite.channel]++;
  });

  return stats;
}
