import { verifyTOTP } from "../utils/totp";
import { createSmsGatewayClient } from "../lib/sms-gateway";
import { isRateLimited, recordSubmission } from "../utils/rate-limiter.js";
import { normalizeAndValidatePhoneNumber } from "../utils/phone-validator.js";

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig(event);
  const {
    name,
    message: userMessage,
    phoneNumber: rawPhoneNumber,
    code,
    interactionData,
    website,
  } = await readBody(event);

  let phoneNumber;
  try {
    phoneNumber = normalizeAndValidatePhoneNumber(rawPhoneNumber);
  } catch (error) {
    throw createError({ statusCode: 400, statusMessage: error.message });
  }

  if (website) {
    throw createError({
      statusCode: 400,
      statusMessage: "Spam detected.",
    });
  }

  if (interactionData) {
    if (interactionData.timeSpent < 3000) {
      throw createError({
        statusCode: 400,
        statusMessage: "Submission too fast.",
      });
    }

    if (
      interactionData.mouseActivity === 0 &&
      interactionData.keyboardActivity === 0
    ) {
      throw createError({
        statusCode: 400,
        statusMessage: "No user interaction detected.",
      });
    }
  }

  if (!name || !userMessage || !code) {
    throw createError({
      statusCode: 400,
      statusMessage: "All fields are required.",
    });
  }

  const nameRegex = /^[a-zA-Z\s'-]{2,50}$/;
  if (!nameRegex.test(name.trim())) {
    throw createError({
      statusCode: 400,
      statusMessage: "Name contains invalid characters or format.",
    });
  }

  if (isRateLimited(phoneNumber)) {
    throw createError({
      statusCode: 429,
      statusMessage:
        "You have reached the maximum of 3 messages per week. Please try again later.",
    });
  }

  if (userMessage.length > 140) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message cannot be longer than 140 characters.",
    });
  }

  const printableAsciiRegex = /^[\x20-\x7E\n\r]*$/;
  if (!printableAsciiRegex.test(userMessage)) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message contains non-ASCII or non-printable characters.",
    });
  }

  if (userMessage.trim().length < 10) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message is too short.",
    });
  }

  const spamKeywords = [
    "viagra",
    "casino",
    "lottery",
    "winner",
    "click here",
    "free money",
    "urgent",
    "limited time",
  ];
  const hasSpamKeywords = spamKeywords.some((keyword) =>
    userMessage.toLowerCase().includes(keyword.toLowerCase()),
  );

  if (hasSpamKeywords) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message contains inappropriate content.",
    });
  }

  if (/([a-zA-Z])\1{4,}/.test(userMessage)) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message contains excessive repeated characters.",
    });
  }

  const uppercaseRatio =
    (userMessage.match(/[A-Z]/g) || []).length / userMessage.length;
  if (uppercaseRatio > 0.7 && userMessage.length > 10) {
    throw createError({
      statusCode: 400,
      statusMessage: "Message contains excessive uppercase text.",
    });
  }

  if (!config.myPhoneNumber || !config.superSecretSalt) {
    console.error(
      "Server is not fully configured. MY_PHONE_NUMBER and SUPER_SECRET_SALT are required.",
    );
    throw createError({
      statusCode: 500,
      statusMessage: "A server configuration error occurred.",
    });
  }

  const isVerified = verifyTOTP(phoneNumber, config.superSecretSalt, code);
  if (!isVerified) {
    throw createError({
      statusCode: 401,
      statusMessage:
        "Your verification code is invalid or has expired. Please try again.",
    });
  }

  try {
    const api = createSmsGatewayClient(config);
    const finalMessage = `New message from ${name} ( ${phoneNumber} ) via your portfolio:\n\n"${userMessage}"`;
    const message = {
      phoneNumbers: [config.myPhoneNumber],
      message: finalMessage,
    };

    const state = await api.send(message);

    recordSubmission(phoneNumber);

    return { success: true, messageId: state.id };
  } catch (error) {
    console.error("Failed to send message:", error);
    throw createError({
      statusCode: 500,
      statusMessage: "Failed to send message.",
    });
  }
});
