import { z } from "zod";
import { createRouter, publicQuery } from "../middleware";
import { getDb } from "../queries/connection";
import { orders, orderItems, carts, products, activityLogs } from "@db/schema";
import { eq } from "drizzle-orm";

function getSessionId(headers: Headers): string {
  let sessionId = headers.get("x-session-id");
  if (!sessionId) {
    sessionId = `sess_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
  }
  return sessionId;
}

function generateOrderNumber(): string {
  return `SH-${Math.floor(100000 + Math.random() * 900000)}`;
}

export const orderRouter = createRouter({
  create: publicQuery
    .input(
      z.object({
        customerName: z.string().min(1),
        customerEmail: z.string().email(),
        customerPhone: z.string().min(5),
        checkoutMethod: z.enum(["whatsapp", "telegram"]),
        checkoutNotes: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const db = getDb();
      const sessionId = getSessionId(ctx.req.headers);

      const cartItems = await db
        .select({
          cartId: carts.id,
          productId: carts.productId,
          plan: carts.plan,
          quantity: carts.quantity,
          priceAtAdd: carts.priceAtAdd,
          productName: products.name,
        })
        .from(carts)
        .leftJoin(products, eq(carts.productId, products.id))
        .where(eq(carts.sessionId, sessionId));

      if (cartItems.length === 0) {
        throw new Error("Cart is empty");
      }

      const totalAmount = cartItems.reduce(
        (sum, item) => sum + Number(item.priceAtAdd) * (item.quantity ?? 1),
        0
      );

      const orderNumber = generateOrderNumber();

      const [orderResult] = await db.insert(orders).values({
        orderNumber,
        sessionId,
        customerName: input.customerName,
        customerEmail: input.customerEmail,
        customerPhone: input.customerPhone,
        totalAmount: String(totalAmount.toFixed(2)),
        checkoutMethod: input.checkoutMethod,
        checkoutNotes: input.checkoutNotes || null,
      });

      const orderId = Number(orderResult.insertId);

      for (const item of cartItems) {
        const qty = item.quantity ?? 1;
        await db.insert(orderItems).values({
          orderId,
          productId: item.productId,
          productName: item.productName || "Unknown Product",
          plan: item.plan || "Default",
          quantity: qty,
          unitPrice: item.priceAtAdd,
          totalPrice: String((Number(item.priceAtAdd) * qty).toFixed(2)),
        });

        await db.insert(activityLogs).values({
          type: "sale",
          productName: item.productName || "Unknown",
          customerName: input.customerName.split(" ")[0],
          location: "Online",
          amount: item.priceAtAdd,
        });
      }

      // Clear cart
      await db.delete(carts).where(eq(carts.sessionId, sessionId));

      // Build message
      const itemsList = cartItems
        .map((item) => {
          const qty = item.quantity ?? 1;
          return `- ${item.productName} (${item.plan}) x${qty} = $${(Number(item.priceAtAdd) * qty).toFixed(2)}`;
        })
        .join("\n");

      const message = encodeURIComponent(
        `*New Order - ${orderNumber}*\n\n*Customer:* ${input.customerName}\n*Email:* ${input.customerEmail}\n*Phone:* ${input.customerPhone}\n\n*Items:*\n${itemsList}\n\n*Total: $${totalAmount.toFixed(2)}*\n\n*Notes:* ${input.checkoutNotes || "N/A"}`
      );

      const redirectUrl =
        input.checkoutMethod === "whatsapp"
          ? `https://wa.me/917038146526?text=${message}`
          : `https://t.me/mfatool?text=${message}`;

      return { orderId, orderNumber, redirectUrl, totalAmount: totalAmount.toFixed(2) };
    }),

  getByNumber: publicQuery
    .input(z.object({ orderNumber: z.string() }))
    .query(async ({ input }) => {
      const db = getDb();
      const [order] = await db
        .select()
        .from(orders)
        .where(eq(orders.orderNumber, input.orderNumber))
        .limit(1);

      if (!order) return null;

      const items = await db
        .select()
        .from(orderItems)
        .where(eq(orderItems.orderId, order.id));

      return { ...order, items };
    }),
});
