import { openStore } from "@/lib/data/store";

/**
 * Sends a text message through whichever provider the admin configured.
 *
 * Returns why it didn't send rather than throwing, so a failed message
 * never breaks the thing that triggered it.
 */
export async function sendSms(opts: {
  to: string;
  text: string;
}): Promise<{ sent: boolean; reason?: string }> {
  const store = await openStore();
  const s = await store.settings();

  if (s.smsEnabled !== true) return { sent: false, reason: "SMS is turned off" };

  // A daily cap, so a loop can't run up a bill.
  const cap = Number(s.smsLimit ?? 0);
  if (cap > 0) {
    const since = Date.now() - 86400_000;
    const log = await store.small<{ at: number }[]>("smsLog", []);
    const sentToday = log.filter((r) => r.at > since).length;
    if (sentToday >= cap) {
      return { sent: false, reason: `Daily limit of ${cap} messages reached` };
    }
  }

  const provider = String(s.smsProvider ?? "Twilio");
  const to = opts.to.trim();
  if (!to) return { sent: false, reason: "No number to send to" };

  try {
    let ok = false;

    if (provider === "Twilio") {
      const sid = String(s.twilioSid ?? "").trim();
      const token = String(s.twilioToken ?? "").trim();
      const from = String(s.twilioPhone ?? "").trim();
      if (!sid || !token || !from) {
        return { sent: false, reason: "Twilio isn't fully configured" };
      }

      const res = await fetch(
        `https://api.twilio.com/2010-04-01/Accounts/${sid}/Messages.json`,
        {
          method: "POST",
          headers: {
            Authorization: `Basic ${Buffer.from(`${sid}:${token}`).toString("base64")}`,
            "Content-Type": "application/x-www-form-urlencoded",
          },
          body: new URLSearchParams({ To: to, From: from, Body: opts.text }),
        }
      );
      ok = res.ok;
    } else if (provider === "BulkSMS") {
      const user = String(s.bulksmsUsername ?? "").trim();
      const pass = String(s.bulksmsPassword ?? "").trim();
      if (!user || !pass) return { sent: false, reason: "BulkSMS isn't configured" };

      const res = await fetch("https://api.bulksms.com/v1/messages", {
        method: "POST",
        headers: {
          Authorization: `Basic ${Buffer.from(`${user}:${pass}`).toString("base64")}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ to, body: opts.text }),
      });
      ok = res.ok;
    } else if (provider === "Infobip") {
      const user = String(s.infobipUsername ?? "").trim();
      const pass = String(s.infobipPassword ?? "").trim();
      if (!user || !pass) return { sent: false, reason: "Infobip isn't configured" };

      const res = await fetch("https://api.infobip.com/sms/2/text/advanced", {
        method: "POST",
        headers: {
          Authorization: `Basic ${Buffer.from(`${user}:${pass}`).toString("base64")}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          messages: [{ destinations: [{ to }], text: opts.text }],
        }),
      });
      ok = res.ok;
    } else if (provider === "Msg91") {
      const key = String(s.msg91AuthKey ?? "").trim();
      const template = String(s.msg91TemplateId ?? "").trim();
      if (!key || !template) return { sent: false, reason: "Msg91 isn't configured" };

      const res = await fetch("https://control.msg91.com/api/v5/flow/", {
        method: "POST",
        headers: { authkey: key, "Content-Type": "application/json" },
        body: JSON.stringify({
          template_id: template,
          recipients: [{ mobiles: to.replace(/\D/g, ""), OTP: opts.text }],
        }),
      });
      ok = res.ok;
    } else {
      return { sent: false, reason: `${provider} isn't supported yet` };
    }

    if (ok) {
      const sent = await store.small<{ at: number }[]>("smsLog", []);
      sent.push({ at: Date.now() });
      // Only the last day matters for the cap.
      await store.putSmall(
        "smsLog",
        sent.filter((r) => r.at > Date.now() - 86400_000)
      );
      await store.save();
      return { sent: true };
    }

    return { sent: false, reason: `${provider} refused the message` };
  } catch {
    return { sent: false, reason: `Couldn't reach ${provider}` };
  }
}
