import { getDb } from "../db.ts";
import { users, referrals, wallets } from "../../drizzle/schema.ts";
import { eq, and, isNull } from "drizzle-orm";

export interface SMSReferralCampaign {
  userId: number;
  phoneNumber: string;
  message: string;
  sentAt: Date;
  status: "pending" | "sent" | "failed";
}

const SMS_REFERRAL_TEMPLATES = {
  noReferrals: (referralCode: string) =>
    `🎉 Earn 1 SC per friend! Share your code ${referralCode} and start earning. Play CoinKrazy now! 🎰`,

  firstReferral: () =>
    `🎊 Congrats on your first referral! Keep sharing to earn more SC. 🎯`,

  milestone: (count: number) =>
    `🏆 Amazing! You've earned ${count} SC from referrals! Share more to reach Gold status. 💰`,
};

export async function getPlayersWithoutReferrals(): Promise<
  Array<{
    userId: number;
    email: string;
    phoneNumber: string | null;
    referralCode: string;
  }>
> {
  const db = await getDb();
  if (!db) return [];

  // Get all users
  const allUsers = await db.select().from(users);

  // Get all referrers
  const referrers = await db.select().from(referrals);
  const referrerIds = new Set(referrers.map((r) => r.referrerId));

  // Filter users who haven't referred anyone
  return allUsers
    .filter((user) => !referrerIds.has(user.id))
    .map((user) => ({
      userId: user.id,
      email: user.email || '',
      phoneNumber: null,
      referralCode: `REF${user.id}${Date.now().toString(36)}`.toUpperCase().slice(0, 12),
    }));
}

export async function getPlayersWithLowReferrals(): Promise<
  Array<{
    userId: number;
    email: string;
    phoneNumber: string | null;
    referralCount: number;
  }>
> {
  const db = await getDb();
  if (!db) return [];

  // Get all users
  const allUsers = await db.select().from(users);

  // Get referral counts per user
  const allReferrals = await db.select().from(referrals);
  const referralCounts: Record<number, number> = {};

  for (const ref of allReferrals) {
    if (!referralCounts[ref.referrerId]) {
      referralCounts[ref.referrerId] = 0;
    }
    if (ref.status === "completed") {
      referralCounts[ref.referrerId]++;
    }
  }

  // Return users with 1-5 completed referrals
  return allUsers
    .filter((user) => {
      const count = referralCounts[user.id] || 0;
      return count > 0 && count < 5;
    })
    .map((user) => ({
      userId: user.id,
      email: user.email || '',
      phoneNumber: null,
      referralCount: referralCounts[user.id] || 0,
    }));
}

export async function sendSMSReferralReminder(
  userId: number,
  phoneNumber: string,
  message: string
): Promise<{ success: boolean; messageId?: string; error?: string }> {
  try {
    // In production, this would call Twilio SMS API
    // For now, we'll just log it
    console.log(`[SMS] Sending to ${phoneNumber}: ${message}`);

    // Store campaign record
    const db = await getDb();
    if (db) {
      // You would insert into a campaigns table here
      // await db.insert(smsCampaigns).values({
      //   userId,
      //   phoneNumber,
      //   message,
      //   sentAt: new Date(),
      //   status: "sent",
      // });
    }

    return {
      success: true,
      messageId: `sms_${Date.now()}`,
    };
  } catch (error) {
    return {
      success: false,
      error: error instanceof Error ? error.message : "Unknown error",
    };
  }
}

export async function launchReferralReminders(): Promise<{
  sent: number;
  failed: number;
  errors: string[];
}> {
  let sent = 0;
  let failed = 0;
  const errors: string[] = [];

  // Get players with no referrals
  const noReferralPlayers = await getPlayersWithoutReferrals();

  for (const player of noReferralPlayers) {
    if (player.phoneNumber) {
      const message = SMS_REFERRAL_TEMPLATES.noReferrals(player.referralCode);
      const result = await sendSMSReferralReminder(
        player.userId,
        player.phoneNumber,
        message
      );

      if (result.success) {
        sent++;
      } else {
        failed++;
        errors.push(`User ${player.userId}: ${result.error}`);
      }
    }
  }

  // Get players with low referrals
  const lowReferralPlayers = await getPlayersWithLowReferrals();

  for (const player of lowReferralPlayers) {
    if (player.phoneNumber) {
      const message = SMS_REFERRAL_TEMPLATES.milestone(player.referralCount);
      const result = await sendSMSReferralReminder(
        player.userId,
        player.phoneNumber,
        message
      );

      if (result.success) {
        sent++;
      } else {
        failed++;
        errors.push(`User ${player.userId}: ${result.error}`);
      }
    }
  }

  return { sent, failed, errors };
}
