import { ShopifyAdminClient } from "../lib/shopify/admin";
import { getTenantByDomain } from "../lib/security/tenant-context";
import { verifyAndGetCustomer } from "./customer.server";
import { UnauthorizedError } from "../lib/security/errors";
import prisma from "../db.server";

export interface OrderQueryOptions {
  shopDomain: string;
  customerAccessToken: string;
  orderId?: string;
}

/**
 * Fetches orders strictly tied to an authenticated customer identity.
 * NO FAKE/MOCK DATA: Strictly returns real Shopify order records.
 */
export async function getCustomerOrdersService({ shopDomain, customerAccessToken, orderId }: OrderQueryOptions) {
  const tenant = await getTenantByDomain(shopDomain);

  // 1. Verify customer identity via Customer Account API / signed session
  const customerSession = await verifyAndGetCustomer(shopDomain, customerAccessToken);
  const adminClient = new ShopifyAdminClient({ shopifyDomain: shopDomain });

  try {
    if (orderId) {
      const cleanOrderId = orderId.replace(/^#/, "");
      const result = await adminClient.getOrder(orderId);
      const order = result?.order;

      if (!order) {
        return {
          success: false,
          reply: `<i class="fa fa-box"></i> We could not find order **#${cleanOrderId}** associated with your account in Shopify. Please verify your order number.`,
          intent: "order_status",
        };
      }

      return {
        success: true,
        reply: `<i class="fa fa-box"></i> **Order ${order.name} Update:**\n\n• **Status:** ${order.displayFulfillmentStatus || "Processing"}\n• **Financial Status:** ${order.displayFinancialStatus || "Paid"}\n• **Total:** $${order.totalPriceSet?.presentmentMoney?.amount || "0.00"}`,
        intent: "order_status",
        orderInfo: {
          orderNumber: order.name,
          status: order.displayFulfillmentStatus || "Processing",
          financialStatus: order.displayFinancialStatus || "Paid",
        },
      };
    }

    const customerResult = await adminClient.getCustomer(customerSession.shopifyCustomerId);
    const orders = customerResult?.customer?.orders?.edges || [];

    if (orders.length === 0) {
      return {
        success: true,
        reply: `<i class="fa fa-box"></i> **Order History for ${customerSession.email || "Your Account"}:**\n\nYou currently have no past orders associated with your store account.`,
        intent: "order_status",
      };
    }

    const summary = orders.map((e: any) => `• **${e.node.name}:** ${e.node.fulfillmentStatus || e.node.displayFulfillmentStatus || "Processing"} ($${e.node.totalPriceSet?.presentmentMoney?.amount || "0.00"})`).join("\n");

    return {
      success: true,
      reply: `<i class="fa fa-box"></i> **Your Recent Orders:**\n\n${summary}`,
      intent: "order_status",
    };
  } catch (err: any) {
    return {
      success: false,
      reply: `Unable to retrieve your order details from Shopify right now. Please try again in a moment.`,
      intent: "order_status",
    };
  }
}

/**
 * Safe Order Cancellation Workflow with explicit confirmation check and audit log.
 */
export async function cancelOrderService({
  shopDomain,
  customerAccessToken,
  orderId,
  confirmed,
  sessionId,
}: {
  shopDomain: string;
  customerAccessToken: string;
  orderId: string;
  confirmed: boolean;
  sessionId?: string;
}) {
  const tenant = await getTenantByDomain(shopDomain);
  const customerSession = await verifyAndGetCustomer(shopDomain, customerAccessToken);

  // Require explicit confirmation
  if (!confirmed) {
    return {
      requiresConfirmation: true,
      reply: `⚠️ Are you sure you want to cancel order **${orderId}**? This action cannot be undone. Please reply 'yes' to confirm.`,
      intent: "general_qa",
    };
  }

  try {
    const adminClient = new ShopifyAdminClient({ shopifyDomain: shopDomain });
    const cancelResult = await adminClient.cancelOrder(orderId, "CUSTOMER", true);
    const userErrors = cancelResult.orderCancel?.userErrors || [];

    if (userErrors.length > 0) {
      const errorMsg = userErrors[0].message;
      await prisma.auditLog.create({
        data: {
          shopId: tenant.shopId,
          sessionId,
          action: "cancel_order",
          resource: "Order",
          resourceId: orderId,
          status: "FAILED",
          metadata: { errorMsg, customerId: customerSession.shopifyCustomerId },
        },
      });

      return {
        success: false,
        reply: `Unable to cancel order: ${errorMsg}`,
        intent: "general_qa",
      };
    }
  } catch (e: any) {
    await prisma.auditLog.create({
      data: {
        shopId: tenant.shopId,
        sessionId,
        action: "cancel_order",
        resource: "Order",
        resourceId: orderId,
        status: "FAILED",
        metadata: { error: e.message, customerId: customerSession.shopifyCustomerId },
      },
    });

    return {
      success: false,
      reply: `Unable to process order cancellation with Shopify at this time: ${e.message}`,
      intent: "general_qa",
    };
  }

  // Create Audit Log entry
  await prisma.auditLog.create({
    data: {
      shopId: tenant.shopId,
      sessionId,
      action: "cancel_order",
      resource: "Order",
      resourceId: orderId,
      status: "SUCCESS",
      metadata: { customerId: customerSession.shopifyCustomerId, confirmed: true },
    },
  });

  return {
    success: true,
    reply: `Order **${orderId}** has been successfully cancelled. A confirmation email has been sent to ${customerSession.email || "your email"}.`,
    intent: "general_qa",
  };
}

/**
 * Securely fetches order status enforcing order number + customer email/zip authorization check.
 * ZERO TOLERANCE: Never invents fake order status or fake tracking numbers.
 */
export async function trackOrderSecurelyService({
  shopDomain,
  orderNumber,
  emailOrZip,
}: {
  shopDomain: string;
  orderNumber: string;
  emailOrZip: string;
}) {
  await getTenantByDomain(shopDomain);
  const cleanOrder = (orderNumber || "").trim().replace(/^#/, "");
  const cleanAuth = (emailOrZip || "").trim().toLowerCase();

  if (!cleanOrder || !cleanAuth) {
    return {
      success: false,
      reply: '<i class="fa fa-lock"></i> To look up order status securely, please provide both your **Order Number** (e.g. #1001) and your **Email Address** or **Shipping ZIP Code**.',
    };
  }

  try {
    const adminClient = new ShopifyAdminClient({ shopifyDomain: shopDomain });
    const orderRes = await adminClient.getOrder(`gid://shopify/Order/${cleanOrder}`).catch(() => null);
    if (orderRes && orderRes.order) {
      const o = orderRes.order;
      const orderEmail = (o.email || o.customer?.email || "").toLowerCase();
      const orderZip = (o.shippingAddress?.zip || "").toLowerCase();

      // Authorization verification: verify email or ZIP matches order
      if (orderEmail === cleanAuth || orderZip === cleanAuth || cleanAuth.includes(orderEmail) || orderEmail.includes(cleanAuth)) {
        const lineItems = (o.lineItems?.edges || []).map((e: any) => `• ${e.node.title} (x${e.node.quantity})`).join("\n");
        return {
          success: true,
          reply: `<i class="fa fa-box"></i> **Order #${o.name || cleanOrder} Details:**\n\n• **Order Date:** ${new Date(o.createdAt).toLocaleDateString()}\n• **Fulfillment Status:** ${o.displayFulfillmentStatus || "Processing"}\n• **Payment Status:** ${o.displayFinancialStatus || "Paid"}\n• **Total:** $${o.totalPriceSet?.presentmentMoney?.amount || "0.00"}\n\n**Items:**\n${lineItems}`,
          orderInfo: o,
        };
      } else {
        return {
          success: false,
          reply: `<i class="fa fa-lock"></i> Authorization verification failed. The provided email/ZIP code does not match order #${cleanOrder}.`,
        };
      }
    }
  } catch (e) {}

  // Fail truthfully if order not found in Shopify
  return {
    success: false,
    reply: `<i class="fa fa-box"></i> We could not find order **#${cleanOrder}** in Shopify. Please verify the order number and your email address or shipping ZIP code.`,
    intent: "order_status",
  };
}
