"use server";

import { revalidatePath } from "next/cache";
import { initDb } from "@/lib/db";
import { requireClientWorkspace } from "@/lib/auth/require-auth";
import { getScopedSurvey } from "@/lib/queries/survey-queries";
import { emailCampaignSchema } from "@/lib/validation/filler";
import { sendEmail } from "@/lib/email/mailer";
import { slugify, randomSlugSuffix } from "@/lib/utils/slugify";
import type { ActionResult } from "@/lib/actions/auth";

const MAX_EMAIL_RECIPIENTS = 50;

function parseEmails(raw: string): string[] {
  return raw
    .split(/[\n,;]+/)
    .map((e) => e.trim().toLowerCase())
    .filter((e) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e));
}

function escapeHtml(text: string): string {
  return text
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

/** Send survey link to a list of email addresses. */
export async function sendEmailCampaign(input: {
  surveyId: string;
  subject: string;
  body: string;
  recipients: string;
}): Promise<ActionResult<{ sent: number; failed: number }>> {
  const { userId, workspaceId } = await requireClientWorkspace();
  const parsed = emailCampaignSchema.safeParse(input);
  if (!parsed.success) {
    return { success: false, error: "Invalid input" };
  }

  const survey = await getScopedSurvey(parsed.data.surveyId, workspaceId);
  if (!survey) return { success: false, error: "Survey not found" };

  if (survey.status !== "active") {
    return { success: false, error: "Publish the survey before sending invites" };
  }

  const { Collector, AuditLog } = initDb();
  let collector = await Collector.findOne({
    where: { surveyId: parsed.data.surveyId, type: "web_link" },
  });

  if (!collector) {
    const baseSlug = slugify(survey.title) || "survey";
    collector = await Collector.create({
      surveyId: parsed.data.surveyId,
      type: "web_link",
      slug: `${baseSlug}-${randomSlugSuffix()}`,
      isActive: true,
      config: {},
    });
  }

  const baseUrl =
    process.env.NEXT_PUBLIC_APP_URL ??
    process.env.NEXTAUTH_URL ??
    "http://localhost:3000";
  const surveyUrl = `${baseUrl}/s/${collector.slug}`;

  const emails = parseEmails(parsed.data.recipients);
  if (emails.length === 0) {
    return { success: false, error: "No valid email addresses found" };
  }

  if (emails.length > MAX_EMAIL_RECIPIENTS) {
    return {
      success: false,
      error: `Maximum ${MAX_EMAIL_RECIPIENTS} recipients per campaign`,
    };
  }

  let sent = 0;
  let failed = 0;

  const htmlBody = `
    <p>${escapeHtml(parsed.data.body).replace(/\n/g, "<br>")}</p>
    <p><a href="${surveyUrl}">${surveyUrl}</a></p>
  `;

  for (const to of emails) {
    const result = await sendEmail({
      to,
      subject: parsed.data.subject,
      html: htmlBody,
    });
    if (result.ok) sent++;
    else failed++;
  }

  await Collector.findOrCreate({
    where: { surveyId: parsed.data.surveyId, type: "email_campaign" },
    defaults: {
      surveyId: parsed.data.surveyId,
      type: "email_campaign",
      slug: `${slugify(survey.title)}-email-${randomSlugSuffix(6)}`,
      isActive: true,
      config: {
        emailSubject: parsed.data.subject,
        emailBody: parsed.data.body,
      },
    },
  });

  await AuditLog.create({
    actorUserId: userId,
    workspaceId,
    action: "collector.email_campaign_sent",
    metadata: { surveyId: parsed.data.surveyId, sent, failed },
  });

  revalidatePath(`/app/surveys/${parsed.data.surveyId}/distribute`);
  return { success: true, data: { sent, failed } };
}
