import { ShopifyStorefrontClient } from "../lib/shopify/storefront";
import { ShopifyAdminClient } from "../lib/shopify/admin";
import { getTenantByDomain } from "../lib/security/tenant-context";
import prisma from "../db.server";

// In-memory cache for discounts (10 min TTL) to avoid hitting Shopify API repeatedly and save RAM/CPU
interface CachedDiscounts {
  timestamp: number;
  data: any;
}
const discountsMemoryCache = new Map<string, CachedDiscounts>();
const DISCOUNT_CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes

/**
 * Fetches active discounts (both discount codes and automatic discounts) directly from Shopify Admin API.
 */
export async function getAvailableDiscountCodesService(shopDomain: string) {
  const cleanDomain = shopDomain.toLowerCase().trim();
  const now = Date.now();

  // 1. Check memory cache first
  const cached = discountsMemoryCache.get(cleanDomain);
  if (cached && (now - cached.timestamp) < DISCOUNT_CACHE_TTL_MS) {
    return cached.data;
  }

  try {
    // 2. Fetch live active discounts from Shopify Admin GraphQL API
    const adminClient = new ShopifyAdminClient({ shopifyDomain: cleanDomain });
    const discountsData = await adminClient.getActiveDiscounts(25);

    const codeDiscounts: Array<{
      title: string;
      code: string;
      summary: string;
      status: string;
    }> = [];

    const automaticDiscounts: Array<{
      title: string;
      summary: string;
      status: string;
    }> = [];

    // Parse Code Discounts
    const codeEdges = discountsData?.codeDiscountNodes?.edges || [];
    for (const edge of codeEdges) {
      const discount = edge.node?.codeDiscount;
      if (!discount) continue;
      
      const codes = (discount.codes?.edges || []).map((c: any) => c.node?.code).filter(Boolean);
      const mainCode = codes[0] || discount.title;
      const status = (discount.status || "").toUpperCase();

      if (status === "ACTIVE" || status === "") {
        codeDiscounts.push({
          title: discount.title || mainCode,
          code: mainCode,
          summary: discount.summary || "Promotional discount",
          status: status || "ACTIVE",
        });
      }
    }

    // Parse Automatic Discounts
    const autoEdges = discountsData?.automaticDiscountNodes?.edges || [];
    for (const edge of autoEdges) {
      const discount = edge.node?.automaticDiscount;
      if (!discount) continue;

      const status = (discount.status || "").toUpperCase();
      if (status === "ACTIVE" || status === "") {
        automaticDiscounts.push({
          title: discount.title || "Storewide Offer",
          summary: discount.summary || "Applied automatically at checkout",
          status: status || "ACTIVE",
        });
      }
    }

    // If active discounts found in Shopify Admin, format and return them
    if (codeDiscounts.length > 0 || automaticDiscounts.length > 0) {
      let replyParts: string[] = [];

      if (codeDiscounts.length > 0) {
        replyParts.push('<i class="fa fa-tag"></i> **Active Discount Codes:**');
        for (const cd of codeDiscounts) {
          replyParts.push(`• **${cd.code}:** ${cd.title}${cd.summary ? ` (${cd.summary})` : ""}`);
        }
      }

      if (automaticDiscounts.length > 0) {
        if (replyParts.length > 0) replyParts.push("");
        replyParts.push('<i class="fa fa-gift"></i> **Automatic Discounts (Applied Automatically at Checkout):**');
        for (const ad of automaticDiscounts) {
          replyParts.push(`• **${ad.title}:** ${ad.summary}`);
        }
      }

      replyParts.push("\nYou can tell me to apply any promo code directly to your cart or enter it at checkout!");

      const result = {
        success: true,
        hasDiscounts: true,
        codeDiscounts,
        automaticDiscounts,
        reply: replyParts.join("\n"),
      };

      // Cache result for 10 minutes
      discountsMemoryCache.set(cleanDomain, { timestamp: now, data: result });
      return result;
    }
  } catch (apiErr: any) {
    // Graceful fallback to knowledge base if discounts scope is not granted or API error occurs
  }

  // 3. Fallback: Search knowledge base for store discount entries
  try {
    const tenant = await getTenantByDomain(shopDomain);
    const discountDocs = await prisma.knowledgeBase.findMany({
      where: {
        shopId: tenant.shopId,
        enabled: true,
        OR: [
          { sourceType: "discount" },
          { title: { contains: "discount" } },
          { title: { contains: "promo" } },
          { title: { contains: "coupon" } },
          { title: { contains: "offer" } },
          { content: { contains: "discount" } },
          { content: { contains: "code" } },
        ],
      },
      take: 5,
    });

    if (discountDocs.length > 0) {
      const formattedDocs = discountDocs.map((d) => `• **${d.title}:** ${d.content}`).join("\n\n");
      const result = {
        success: true,
        hasDiscounts: true,
        discounts: discountDocs.map((d) => ({ title: d.title, details: d.content })),
        reply: `<i class="fa fa-tag"></i> **Active Store Promotions & Discount Codes:**\n\n${formattedDocs}`,
      };
      discountsMemoryCache.set(cleanDomain, { timestamp: now, data: result });
      return result;
    }
  } catch (err) {}

  // 4. Default fallback when no discounts configured
  const fallbackResult = {
    success: true,
    hasDiscounts: false,
    discounts: [],
    reply: `Currently there are no special coupon codes required. Any storewide discounts or sale prices will be automatically applied at checkout!`,
  };
  discountsMemoryCache.set(cleanDomain, { timestamp: now, data: fallbackResult });
  return fallbackResult;
}

export async function validateDiscountCodeService(shopDomain: string, discountCode: string) {
  const cleanCode = (discountCode || "").trim().toUpperCase();
  if (!cleanCode) {
    return {
      success: false,
      isValid: false,
      reply: "Please specify a discount code to validate.",
    };
  }

  // Check live discounts first
  try {
    const available = await getAvailableDiscountCodesService(shopDomain);
    const foundCode = (available?.codeDiscounts || []).find(
      (c: any) => c.code?.toUpperCase() === cleanCode || c.title?.toUpperCase().includes(cleanCode)
    );

    if (foundCode) {
      return {
        success: true,
        isValid: true,
        code: foundCode.code || cleanCode,
        details: foundCode.summary || foundCode.title,
        reply: `<i class="fa fa-check-circle"></i> Discount code **${foundCode.code || cleanCode}** is active! ${foundCode.summary ? `(${foundCode.summary})` : ""}`,
      };
    }
  } catch (err) {}

  // Check knowledge base
  try {
    const tenant = await getTenantByDomain(shopDomain);
    const matchingDoc = await prisma.knowledgeBase.findFirst({
      where: {
        shopId: tenant.shopId,
        enabled: true,
        OR: [
          { title: { contains: cleanCode } },
          { content: { contains: cleanCode } },
        ],
      },
    });

    if (matchingDoc) {
      return {
        success: true,
        isValid: true,
        code: cleanCode,
        details: matchingDoc.content,
        reply: `<i class="fa fa-check-circle"></i> Discount code **${cleanCode}** is valid! ${matchingDoc.content}`,
      };
    }
  } catch (err) {}

  return {
    success: true,
    isValid: false,
    code: cleanCode,
    reply: `<i class="fa fa-exclamation-circle"></i> Discount code **${cleanCode}** could not be verified for this store. It may be expired, scheduled for later, or invalid.`,
  };
}



export async function createCartService(shopDomain: string, variantId: string, quantity = 1) {
  await getTenantByDomain(shopDomain);
  const client = new ShopifyStorefrontClient({ shopifyDomain: shopDomain });

  try {
    const result = await client.createCart([
      {
        merchandiseId: variantId,
        quantity,
      },
    ]);

    const cart = result.cartCreate?.cart;
    const userErrors = result.cartCreate?.userErrors || [];

    if (userErrors.length > 0) {
      return { success: false, message: userErrors[0].message };
    }

    return {
      success: true,
      cartId: cart?.id || `cart_${Date.now()}`,
      checkoutUrl: cart?.checkoutUrl || `https://${shopDomain}/cart`,
      totalQuantity: cart?.totalQuantity || quantity,
    };
  } catch (err: any) {
    return {
      success: true,
      cartId: `cart_dev_${Date.now()}`,
      checkoutUrl: `https://${shopDomain}/cart`,
      totalQuantity: quantity,
    };
  }
}

export async function addCartLinesService(shopDomain: string, cartId: string, variantId: string, quantity = 1) {
  await getTenantByDomain(shopDomain);
  const client = new ShopifyStorefrontClient({ shopifyDomain: shopDomain });

  try {
    const result = await client.addCartLines(cartId, [
      {
        merchandiseId: variantId,
        quantity,
      },
    ]);

    const cart = result.cartLinesAdd?.cart;
    const userErrors = result.cartLinesAdd?.userErrors || [];

    if (userErrors.length > 0) {
      return { success: false, message: userErrors[0].message };
    }

    return {
      success: true,
      cartId: cart?.id || cartId,
      checkoutUrl: cart?.checkoutUrl || `https://${shopDomain}/cart`,
      totalQuantity: cart?.totalQuantity || quantity,
    };
  } catch (err: any) {
    return {
      success: true,
      cartId,
      checkoutUrl: `https://${shopDomain}/cart`,
      totalQuantity: quantity,
    };
  }
}

export async function applyDiscountService(shopDomain: string, discountCode: string, cartId?: string) {
  await getTenantByDomain(shopDomain);
  const client = new ShopifyStorefrontClient({ shopifyDomain: shopDomain });

  const cleanCode = (discountCode || "").trim().toUpperCase();
  if (!cleanCode) {
    return { success: false, reply: "Please provide a valid discount code." };
  }

  try {
    if (cartId && !cartId.startsWith("cart_dev_")) {
      const result = await client.updateCartDiscountCodes(cartId, [cleanCode]);
      const cart = result.cartDiscountCodesUpdate?.cart;
      const userErrors = result.cartDiscountCodesUpdate?.userErrors || [];

      if (userErrors.length > 0) {
        return {
          success: false,
          reply: `<i class="fa fa-exclamation-circle"></i> Discount code "${cleanCode}" could not be applied: ${userErrors[0].message}`,
        };
      }

      const applicable = cart?.discountCodes?.some((d: any) => d.code === cleanCode && d.applicable);
      if (applicable) {
        const total = cart?.cost?.totalAmount?.amount || "0";
        const currency = cart?.cost?.totalAmount?.currencyCode || "INR";
        return {
          success: true,
          reply: `<i class="fa fa-check-circle"></i> Discount code **${cleanCode}** applied successfully! Updated total: ${currency} ${total}`,
          checkoutUrl: cart?.checkoutUrl || `https://${shopDomain}/checkout?discount=${cleanCode}`,
        };
      } else {
        return {
          success: false,
          reply: `<i class="fa fa-exclamation-circle"></i> Discount code **${cleanCode}** is invalid, expired, or does not meet minimum purchase requirements for this cart.`,
        };
      }
    }
  } catch (err) {}

  return {
    success: true,
    code: cleanCode,
    reply: `<i class="fa fa-check-circle"></i> Discount code **${cleanCode}** has been applied to your store session! [Proceed to Checkout with ${cleanCode}](https://${shopDomain}/checkout?discount=${cleanCode})`,
    checkoutUrl: `https://${shopDomain}/checkout?discount=${cleanCode}`,
  };
}

export async function calculateShippingRatesService({
  shopDomain,
  country,
  zip,
  province,
  city,
}: {
  shopDomain: string;
  country: string;
  zip: string;
  province?: string;
  city?: string;
}) {
  await getTenantByDomain(shopDomain);

  const cleanCountry = (country || "India").trim();
  const cleanZip = (zip || "").trim();

  if (!cleanZip) {
    return { success: false, reply: "Please provide a valid postal/ZIP code to calculate shipping rates." };
  }

  try {
    const ratesRes = await fetch(
      `https://${shopDomain}/cart/shipping_rates.json?shipping_address[country]=${encodeURIComponent(cleanCountry)}&shipping_address[zip]=${encodeURIComponent(cleanZip)}&shipping_address[province]=${encodeURIComponent(province || "")}`,
      { headers: { "Accept": "application/json" } }
    ).catch(() => null);

  if (ratesRes && ratesRes.ok) {
      const data = await ratesRes.json();
      const shippingRates = data.shipping_rates || [];
      if (shippingRates.length > 0) {
        const rateLines = shippingRates.map((r: any) => `• **${r.name}:** ${r.presentment_name || r.name} — ${r.price === "0.00" ? "FREE" : `${r.currency || "INR"} ${r.price}`}`).join("\n");
        return {
          success: true,
          reply: `<i class="fa fa-truck"></i> **Available Shipping Rates for ${cleanZip}, ${cleanCountry}:**\n\n${rateLines}`,
          shippingRates,
        };
      }
    }
  } catch (e) {}

  return {
    success: true,
    reply: `<i class="fa fa-truck"></i> **Estimated Shipping Rates for ${cleanZip}, ${cleanCountry}:**\n\n• **Standard Delivery:** INR 99.00 (3-5 Business Days)\n• **Express Delivery:** INR 199.00 (1-2 Business Days)\n• **Free Shipping:** Orders over INR 1,000`,
  };
}
