import twilio, { type Twilio } from "twilio";

let client: Twilio;

function getEnvVars() {
  const accountSid = process.env.TWILIO_ACCOUNT_SID;
  const authToken = process.env.TWILIO_AUTH_TOKEN;
  const serviceSid = process.env.TWILIO_SERVICE_SID;

  if (!accountSid || !authToken || !serviceSid) {
    throw new Error(`Missing env vars. accountSid: ${!!accountSid}, authToken: ${!!authToken}, serviceSid: ${!!serviceSid}`);
  }

  return { accountSid, authToken, serviceSid };
}

function getTwilioClient() {
  if (!client) {
    const { accountSid, authToken } = getEnvVars();
    client = twilio(accountSid, authToken);
  }
  return client;
}


// Twilio Verify only accepts its documented language codes; anything else
// (e.g. sw) must be omitted so the send doesn't fail — Twilio falls back to
// the service default (English).
const TWILIO_VERIFY_LOCALES = new Set(["en", "es", "de", "ja"]);

export async function sendVerifyCode(
  phoneNumber: string,
  code: string,
  locale?: string
) {
  const { serviceSid } = getEnvVars();

  const twilioClient = getTwilioClient();

  const verifyLocale =
    locale && TWILIO_VERIFY_LOCALES.has(locale) ? locale : undefined;

  const verification = await twilioClient!.verify.v2
    .services(serviceSid)
    .verifications.create({
      channel: "sms",
      customCode: code,
      to: phoneNumber,
      ...(verifyLocale ? { locale: verifyLocale } : {}),
    });

  if (verification.status !== "pending") {
    throw new Error("Unknown error sending verification code");
  }

  return verification.sid;
}

export async function updateVerify(sid: string) {
  const { serviceSid } = getEnvVars();
  const twilioClient = getTwilioClient();

  const verification = await twilioClient!.verify.v2
    .services(serviceSid)
    .verifications(sid)
    .update({ status: "approved" });

  if (verification.status !== "approved") {
    throw new Error("Unknown error updating verification");
  }
}