import type { ActionFunctionArgs } from "react-router";
import { authenticate } from "../shopify.server";
import db from "../db.server";
import {
  generateAndEmailInvoice,
  isManualPaymentOrder,
} from "../services/invoice/automations.server";
import { isDuplicateWebhook } from "../services/webhooks/dedupe.server";
import { runWebhookInBackground } from "../services/webhooks/background.server";

/**
 * orders/create — Automation 1: when a wire-transfer (manual-payment-gateway)
 * order is placed, immediately generate and email the invoice (which includes
 * the bank details + GiroCode) so the customer can pay. Other orders are
 * ignored here; they're handled by orders/fulfilled (Automation 2).
 */
export const action = async ({ request }: ActionFunctionArgs) => {
  const { shop, topic, payload, session, admin } = await authenticate.webhook(request);
  console.log(`Received ${topic} webhook for ${shop}`);

  // Drop Shopify retries we've already processed (prevents the duplicate
  // invoice email we saw when the first delivery exceeded Shopify's 5s ack
  // timeout — the work still completed, but Shopify resent the webhook).
  if (await isDuplicateWebhook(request, shop, topic)) return new Response();

  if (!session || !admin) return new Response();

  const orderId = payload?.id;
  if (orderId == null) return new Response();

  const customerLocale =
    typeof payload?.customer_locale === "string" ? payload.customer_locale : undefined;

  // Respond 200 immediately and run the (slow) PDF + email work in the
  // background — keeps us well under Shopify's ~5s ack timeout. Dedupe
  // above guarantees we don't double-process a retry while the first
  // delivery is still working.
  runWebhookInBackground(`${topic} order=${orderId} shop=${shop}`, async () => {
    const settings = await db.shopSettings.findUnique({ where: { shopDomain: shop } });
    if (!settings?.autoEmailOnWireTransferPlaced) return;

    const orderGid = `gid://shopify/Order/${String(orderId).replace(/^.*\//, "")}`;
    if (!(await isManualPaymentOrder(admin, orderGid))) return;

    const result = await generateAndEmailInvoice({
      shopDomain: shop,
      admin,
      orderId,
      customerLocale,
    });
    if (!result.ok) {
      console.warn(
        `auto-email (wire-transfer placed) failed for order ${orderId} on ${shop}: ${result.reason}`,
      );
    }
  });

  return new Response();
};
