"use server";

import { redirect } from "next/navigation";
import { eq } from "drizzle-orm";
import { z } from "zod";
import { db } from "@/lib/db/client";
import {
  storeOrders,
  storeOrderLines,
  users,
} from "@/lib/db/schema";
import { requireUser } from "@/lib/auth/admin-guard";
import { loadCartSummary, clearCart } from "@/lib/store/cart";
import { nextOrderNumber } from "@/lib/store/queries";
import { sendTemplatedEmail } from "@/lib/email/send";
import { loadEnv } from "@/lib/env";

export type CheckoutState = {
  ok: boolean;
  message?: string;
  fieldErrors?: Record<string, string>;
};

const checkoutSchema = z.object({
  customerName: z.string().trim().min(2).max(200),
  customerEmail: z.string().trim().toLowerCase().email().max(200),
  customerPhone: z.string().trim().max(30).optional().default(""),
  shippingAddress: z.string().trim().min(10).max(1000),
  shippingCountry: z.string().trim().min(2).max(80),
  notes: z.string().trim().max(1000).optional().default(""),
});

/**
 * Creates a pending-invoice order from the current cart. Clears the cart
 * on success and redirects to the confirmation page. Payment isn't taken
 * here — admin issues an invoice separately.
 */
export async function placeOrder(
  _prev: CheckoutState,
  formData: FormData,
): Promise<CheckoutState> {
  const session = await requireUser();
  const userId = (session.user as { id?: string }).id ?? null;

  const parsed = checkoutSchema.safeParse({
    customerName: formData.get("customerName") ?? "",
    customerEmail: formData.get("customerEmail") ?? "",
    customerPhone: formData.get("customerPhone") ?? "",
    shippingAddress: formData.get("shippingAddress") ?? "",
    shippingCountry: formData.get("shippingCountry") ?? "",
    notes: formData.get("notes") ?? "",
  });
  if (!parsed.success) {
    const fieldErrors: Record<string, string> = {};
    for (const issue of parsed.error.issues) {
      fieldErrors[issue.path.join(".")] = issue.message;
    }
    return {
      ok: false,
      fieldErrors,
      message: "Please correct the highlighted fields.",
    };
  }
  const data = parsed.data;

  const cart = await loadCartSummary();
  if (cart.items.length === 0) {
    return { ok: false, message: "Your cart is empty." };
  }

  const shippingMinor = cart.subtotalMinor >= 100_00 ? 0 : 7_00;
  const totalMinor = cart.subtotalMinor + shippingMinor;
  const orderNumber = await nextOrderNumber();

  const [order] = await db
    .insert(storeOrders)
    .values({
      orderNumber,
      userId,
      customerName: data.customerName,
      customerEmail: data.customerEmail,
      customerPhone: data.customerPhone || null,
      shippingAddress: data.shippingAddress,
      shippingCountry: data.shippingCountry,
      notes: data.notes,
      subtotalMinor: cart.subtotalMinor,
      shippingMinor,
      totalMinor,
      currency: cart.currency,
      status: "pending_invoice",
    })
    .returning({ id: storeOrders.id, orderNumber: storeOrders.orderNumber });

  await db.insert(storeOrderLines).values(
    cart.items.map((i, idx) => ({
      orderId: order.id,
      productId: i.productId,
      productTitle: i.title,
      productSlug: i.slug,
      unitPriceMinor: i.priceMinor,
      quantity: i.quantity,
      lineTotalMinor: i.lineTotalMinor,
      position: idx,
    })),
  );

  await clearCart();

  // Hydrate email blocks.
  const env = loadEnv();
  const currency = cart.currency;
  const fmt = (n: number) =>
    new Intl.NumberFormat("en-GB", { style: "currency", currency }).format(n / 100);
  const itemsBlock = cart.items
    .map(
      (i) =>
        `  ${i.quantity}× ${i.title} — ${fmt(i.priceMinor)} each = ${fmt(i.lineTotalMinor)}`,
    )
    .join("\n");
  const orderUrl = `${env.nextAuthUrl}/products/store/orders/${order.id}`;
  const reviewUrl = `${env.nextAuthUrl}/admin/store/orders/${order.id}`;

  try {
    await sendTemplatedEmail({
      to: data.customerEmail,
      templateSlug: "store-order-received",
      variables: {
        name: data.customerName,
        orderNumber: order.orderNumber,
        itemsBlock,
        subtotal: fmt(cart.subtotalMinor),
        shipping: shippingMinor === 0 ? "Free" : fmt(shippingMinor),
        total: fmt(totalMinor),
        orderUrl,
      },
    });
    await sendTemplatedEmail({
      to: env.adminNotifyEmails,
      templateSlug: "store-order-admin-notify",
      variables: {
        name: data.customerName,
        email: data.customerEmail,
        orderNumber: order.orderNumber,
        shippingAddress: `${data.shippingAddress}\n${data.shippingCountry}`,
        itemsBlock,
        total: fmt(totalMinor),
        reviewUrl,
      },
    });
  } catch (err) {
    console.error("[store-order] email failed", err);
  }

  // Keep the default name/address on file for next time.
  if (userId && !session.user?.name) {
    await db
      .update(users)
      .set({ name: data.customerName })
      .where(eq(users.id, userId));
  }

  redirect(`/products/store/orders/${order.id}`);
}
