/**
 * Review Reminder Service
 *
 * Handles follow-up reminders for pending review requests and
 * expiration of stale requests. Designed to be called by a cron job.
 *
 * Reminder schedule:
 *   - 1st reminder: 3 days after initial send (reminderCount 0 → 1, next at +7 days)
 *   - 2nd reminder: 7 days after 1st (reminderCount 1 → 2, no more reminders)
 */

import { prisma } from '@/lib/db';
import { logger } from '@/lib/logger';
import { queueEmail } from '@/lib/queue/email-queue';
import { twilioWhatsAppService } from '@/lib/services/twilio-whatsapp.service';

export interface ReminderResult {
  reminded: number;
  expired: number;
  errors: number;
}

/**
 * Attempt to resend a review request via WhatsApp.
 */
async function resendWhatsApp(
  phone: string,
  customerName: string,
  reviewUrl: string,
  language: string,
  userId: string,
): Promise<boolean> {
  if (!phone) return false;

  try {
    // Get org membership for this user to find WhatsApp credentials
    const member = await prisma.organization_members.findFirst({
      where: { userId },
      select: { organizationId: true },
    });

    if (!member?.organizationId) return false;

    const credentials = await twilioWhatsAppService.getCredentialsForOrg(member.organizationId);
    if (!credentials) return false;

    const body =
      language === 'ar'
        ? `تذكير: نود سماع رأيك! يرجى مشاركة تقييمك هنا: ${reviewUrl}`
        : `Reminder: We'd love your feedback! Please share your review here: ${reviewUrl}`;

    const to = phone.startsWith('whatsapp:') ? phone : `whatsapp:${phone}`;
    const result = await twilioWhatsAppService.sendTextMessage(credentials, to, body);
    return result.success;
  } catch (error) {
    const msg = error instanceof Error ? error.message : 'Unknown error';
    logger.error('review-reminder: WhatsApp resend failed', { phone, error: msg });
    return false;
  }
}

/**
 * Process review reminders for requests that are due.
 *
 * Finds SENT requests where nextReminderAt <= now, reminderCount < 2, and not expired.
 * Resends via email + WhatsApp, increments counter, sets next reminder date.
 */
export async function processReviewReminders(): Promise<ReminderResult> {
  const result: ReminderResult = { reminded: 0, expired: 0, errors: 0 };
  const now = new Date();

  logger.info('review-reminder: starting batch', { now: now.toISOString() });

  // First expire stale requests
  const expiredCount = await expireStaleRequests();
  result.expired = expiredCount;

  let dueRequests;
  try {
    dueRequests = await prisma.review_requests.findMany({
      where: {
        status: 'SENT',
        nextReminderAt: { lte: now },
        reminderCount: { lt: 2 },
        expiresAt: { gt: now },
      },
      select: {
        id: true,
        userId: true,
        customerName: true,
        customerEmail: true,
        customerPhone: true,
        token: true,
        language: true,
        reminderCount: true,
      },
    });
  } catch (error) {
    const msg = error instanceof Error ? error.message : 'Unknown error';
    logger.error('review-reminder: failed to query due requests', { error: msg });
    throw error;
  }

  logger.info('review-reminder: found due reminders', { count: dueRequests.length });

  for (const request of dueRequests) {
    try {
      const reviewUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'https://mawidi.com'}/review/${request.token}`;

      // Send email reminder
      let emailSent = false;
      if (request.customerEmail) {
        try {
          const subject =
            request.language === 'ar'
              ? 'تذكير: نود سماع رأيك!'
              : 'Reminder: We\'d love your feedback!';

          const html =
            request.language === 'ar'
              ? `<p>مرحبًا ${request.customerName}،</p><p>لم نسمع منك بعد! نود حقًا سماع رأيك.</p><p><a href="${reviewUrl}">شاركنا تقييمك</a></p>`
              : `<p>Hi ${request.customerName},</p><p>We haven't heard from you yet! We'd really appreciate your feedback.</p><p><a href="${reviewUrl}">Share your review</a></p>`;

          const text =
            request.language === 'ar'
              ? `تذكير: نود سماع رأيك! شاركنا تقييمك: ${reviewUrl}`
              : `Reminder: We'd love your feedback! Share your review: ${reviewUrl}`;

          await queueEmail({
            to: request.customerEmail,
            subject,
            html,
            text,
            category: 'review_reminder',
            metadata: { reviewRequestId: request.id, reminderCount: request.reminderCount + 1 },
          });
          emailSent = true;
        } catch (emailError) {
          const msg = emailError instanceof Error ? emailError.message : 'Unknown error';
          logger.error('review-reminder: email failed', {
            requestId: request.id,
            error: msg,
          });
        }
      }

      // Send WhatsApp reminder
      let whatsAppSent = false;
      if (request.customerPhone) {
        whatsAppSent = await resendWhatsApp(
          request.customerPhone,
          request.customerName,
          reviewUrl,
          request.language,
          request.userId,
        );
      }

      // Calculate next reminder
      const newCount = request.reminderCount + 1;
      const nextReminderAt =
        newCount < 2
          ? new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000) // 7 days from now
          : null; // No more reminders after 2nd

      await prisma.review_requests.update({
        where: { id: request.id },
        data: {
          reminderCount: newCount,
          lastReminderAt: now,
          nextReminderAt,
          reminderStatus: emailSent || whatsAppSent ? 'SENT' : 'FAILED',
        },
      });

      result.reminded++;
      logger.info('review-reminder: reminder sent', {
        requestId: request.id,
        reminderNumber: newCount,
        emailSent,
        whatsAppSent,
        nextReminderAt: nextReminderAt?.toISOString() || null,
      });
    } catch (itemError) {
      result.errors++;
      const msg = itemError instanceof Error ? itemError.message : 'Unknown error';
      logger.error('review-reminder: failed to process request', {
        requestId: request.id,
        error: msg,
      });
    }
  }

  logger.info('review-reminder: batch complete', { ...result });
  return result;
}

/**
 * Expire stale review requests.
 *
 * Marks requests as EXPIRED when status is PENDING or SENT and expiresAt <= now.
 * Returns the count of expired requests.
 */
export async function expireStaleRequests(): Promise<number> {
  const now = new Date();

  try {
    const { count } = await prisma.review_requests.updateMany({
      where: {
        status: { in: ['PENDING', 'SENT'] },
        expiresAt: { lte: now },
      },
      data: {
        status: 'EXPIRED',
        nextReminderAt: null,
      },
    });

    if (count > 0) {
      logger.info('review-reminder: expired stale requests', { count });
    }

    return count;
  } catch (error) {
    const msg = error instanceof Error ? error.message : 'Unknown error';
    logger.error('review-reminder: failed to expire stale requests', { error: msg });
    return 0;
  }
}
