import { AIProvider, AgentRunParams, AIProviderResponse } from "./types";
import { searchProductsService, parseProductSearchQuery } from "../../services/product.server";
import { getTenantByDomain } from "../security/tenant-context";
import { formatCurrency } from "../currency";
import { logger } from "../security/logger";
import { parseWidgetSettings } from "../../services/widget-settings.server";
import prisma from "../../db.server";

export async function runLocalShopifyFallback({
  shopDomain,
  sessionId,
  userMessage,
  customerAccessToken,
}: AgentRunParams): Promise<AIProviderResponse> {
  try {
    const tenant = await getTenantByDomain(shopDomain);
    const msgLower = (userMessage || "").toLowerCase().trim();
    const rawClean = msgLower.replace(/[^\w\s]/g, " ");
    const words = rawClean
      .split(/\s+/)
      .filter((w) => w.length >= 3 && !["what", "when", "where", "which", "your", "this", "that", "have", "with", "from", "does", "will", "would", "could", "should"].includes(w));

    // Intent 1: Contact / Support / Store Help
    const isContactQuery =
      msgLower.includes("contact") ||
      msgLower.includes("email") ||
      msgLower.includes("phone") ||
      msgLower.includes("number") ||
      msgLower.includes("call") ||
      msgLower.includes("tel") ||
      msgLower.includes("support") ||
      msgLower.includes("address") ||
      msgLower.includes("reach") ||
      msgLower.includes("location") ||
      msgLower.includes("helpdesk") ||
      msgLower.includes("helpline") ||
      msgLower.includes("toll free") ||
      msgLower.includes("customer care") ||
      msgLower.includes("human");

    if (isContactQuery) {
      let storeSettings = null;
      try {
        storeSettings = await prisma.chatbotSettings.findUnique({
          where: { shopId: tenant.shopId },
        });
      } catch (e) {}

      const { widgetTexts } = parseWidgetSettings(storeSettings);
      const storePhone = widgetTexts.storeSupportPhone?.trim() || "";
      const storeEmail = widgetTexts.storeSupportEmail?.trim() || "";
      const storeHours = widgetTexts.storeSupportHours?.trim() || "Mon - Fri: 9:00 AM - 6:00 PM";
      const storeAddress = widgetTexts.storeAddress?.trim() || "";
      const storeContactUrl = widgetTexts.storeContactUrl?.trim() || "/pages/contact";

      let contactDoc = null;
      try {
        contactDoc = await prisma.knowledgeBase.findFirst({
          where: {
            shopId: tenant.shopId,
            enabled: true,
            OR: [
              { title: { contains: "contact" } },
              { content: { contains: "contact" } },
              { title: { contains: "email" } },
              { content: { contains: "email" } },
              { title: { contains: "support" } },
              { content: { contains: "support" } },
              { title: { contains: "phone" } },
              { content: { contains: "phone" } },
              { title: { contains: "address" } },
              { content: { contains: "address" } },
            ],
          },
        });
      } catch (e) {}

      let merchantUser = null;
      if (!storeEmail) {
        try {
          merchantUser = await prisma.merchantUser.findFirst({
            where: { shopId: tenant.shopId },
            orderBy: { createdAt: "asc" },
          });
        } catch (e) {}
      }

      const finalEmail = storeEmail || merchantUser?.email || "";

      let reply = "";
      if (storePhone || finalEmail || storeAddress) {
        const details: string[] = [];
        if (storePhone) {
          const cleanPhone = storePhone.replace(/[^\d+]/g, "");
          const phoneLink = cleanPhone ? `[${storePhone}](tel:${cleanPhone})` : storePhone;
          details.push(`• 📞 **Phone / WhatsApp:** ${phoneLink}`);
        }
        if (finalEmail) {
          details.push(`• ✉️ **Support Email:** [${finalEmail}](mailto:${finalEmail})`);
        }
        if (storeHours) {
          details.push(`• ⏰ **Operating Hours:** ${storeHours}`);
        }
        if (storeAddress) {
          details.push(`• 📍 **Store Address:** ${storeAddress}`);
        }

        let extraDoc = "";
        if (contactDoc) {
          extraDoc = `\n\n📌 **${contactDoc.title}:** ${contactDoc.content}`;
        }

        reply = `Here is our store's customer support and contact information:\n\n${details.join("\n")}${extraDoc}\n\n🌐 You can also visit our store [Contact Us Page](${storeContactUrl}). How else can I assist you today?`;
      } else if (contactDoc) {
        reply = `📧 **${contactDoc.title}:** ${contactDoc.content}\n\n🌐 You can also visit our store [Contact Us Page](${storeContactUrl}). How else can I help you today?`;
      } else {
        reply = `📧 You can reach our customer support team or visit our store [Contact Us Page](${storeContactUrl}) for assistance. How else can I help you today?`;
      }

      return {
        provider: "local",
        model: "local-catalog-engine",
        reply,
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 2: Order Tracking & Status Request
    const isOrderQuery =
      msgLower.includes("order") ||
      msgLower.includes("track") ||
      msgLower.includes("status") ||
      msgLower.includes("package") ||
      msgLower.includes("shipment");

    if (isOrderQuery) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: `📦 To track your order, please reply with your **Order Number** (e.g. #1001) and your email or ZIP code.`,
        intent: "order_status",
        products: undefined,
      };
    }

    // Intent 3: Knowledge Base / Policy Search (Multi-word matching)
    let knowledgeDocs: any[] = [];
    try {
      const orConditions: any[] = [
        { title: { contains: msgLower } },
        { content: { contains: msgLower } },
      ];
      for (const w of words) {
        orConditions.push({ title: { contains: w } });
        orConditions.push({ content: { contains: w } });
      }

      knowledgeDocs = await prisma.knowledgeBase.findMany({
        where: {
          shopId: tenant.shopId,
          enabled: true,
          sourceType: { not: "blog" },
          OR: orConditions,
        },
        take: 2,
      });
    } catch (kErr) {
      logger.warn("Knowledge base lookup skipped during local fallback", { error: String(kErr) });
    }

    if (knowledgeDocs.length > 0) {
      const reply = knowledgeDocs.map((d) => `• **${d.title}:** ${d.content}`).join("\n\n");
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply,
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 3b: Store Blog Posts, Guides, How-Tos & Advice
    const isBlogQuery =
      msgLower.includes("blog") ||
      msgLower.includes("article") ||
      msgLower.includes("guide") ||
      msgLower.includes("sizing") ||
      msgLower.includes("size chart") ||
      msgLower.includes("fit") ||
      msgLower.includes("measurement") ||
      msgLower.includes("care") ||
      msgLower.includes("wash") ||
      msgLower.includes("clean") ||
      msgLower.includes("maintenance") ||
      msgLower.includes("how to") ||
      msgLower.includes("tips") ||
      msgLower.includes("story") ||
      msgLower.includes("craftsmanship") ||
      msgLower.includes("sustainable") ||
      msgLower.includes("tutorial");

    let matchedArticles: any[] = [];
    try {
      const artOrConditions: any[] = [
        { title: { contains: msgLower } },
        { summary: { contains: msgLower } },
        { content: { contains: msgLower } },
        { blogTitle: { contains: msgLower } },
      ];
      for (const w of words) {
        artOrConditions.push({ title: { contains: w } });
        artOrConditions.push({ summary: { contains: w } });
        artOrConditions.push({ content: { contains: w } });
      }

      matchedArticles = await prisma.articleCache.findMany({
        where: {
          shopId: tenant.shopId,
          OR: artOrConditions,
        },
        take: 10,
      });

      // If empty in DB, auto-seed and query again
      if (matchedArticles.length === 0 && isBlogQuery) {
        const { syncStoreArticles } = await import("../../services/article.server");
        await syncStoreArticles(shopDomain);
        matchedArticles = await prisma.articleCache.findMany({
          where: {
            shopId: tenant.shopId,
            OR: artOrConditions,
          },
          take: 10,
        });
      }

      // Sort by relevance: title matches > summary matches > content matches
      matchedArticles.sort((a, b) => {
        const aTitleMatch = words.filter(w => a.title.toLowerCase().includes(w)).length;
        const bTitleMatch = words.filter(w => b.title.toLowerCase().includes(w)).length;
        if (bTitleMatch !== aTitleMatch) return bTitleMatch - aTitleMatch;

        const aFull = ((a.title || "") + " " + (a.summary || "")).toLowerCase();
        const bFull = ((b.title || "") + " " + (b.summary || "")).toLowerCase();
        const aScore = words.filter(w => aFull.includes(w)).length;
        const bScore = words.filter(w => bFull.includes(w)).length;
        return bScore - aScore;
      });

      matchedArticles = matchedArticles.slice(0, 3);
    } catch (artErr) {
      logger.warn("Article cache lookup skipped during local fallback", { error: String(artErr) });
    }

    if (matchedArticles.length > 0 && (isBlogQuery || matchedArticles.some(a => a.title.toLowerCase().includes(msgLower) || msgLower.includes(a.title.toLowerCase())))) {
      const topArticle = matchedArticles[0];
      const articleList = matchedArticles.map((a) => ({
        id: a.id,
        shopifyArticleId: a.shopifyArticleId,
        blogHandle: a.blogHandle || "news",
        blogTitle: a.blogTitle || "Store Blog",
        title: a.title,
        handle: a.handle,
        summary: a.summary || "",
        content: a.content || "",
        image: a.image || "",
        imageUrl: a.image || "",
        author: a.author || "",
        url: a.url || `/blogs/${a.blogHandle || 'news'}/${a.handle}`,
        publishedAt: a.publishedAt,
      }));

      const reply = `📖 **${topArticle.title}**\n\n${topArticle.summary || topArticle.content?.substring(0, 250) + '...'}\n\nHere are relevant store guides and articles:`;

      return {
        provider: "local",
        model: "local-catalog-engine",
        reply,
        intent: "general_qa",
        articles: articleList,
        products: undefined,
      };
    }

    // Intent 4: Cart Operations (Starter Tier)
    if (msgLower.includes("cart") || msgLower.includes("add to") || msgLower.includes("quantity") || msgLower.includes("empty cart")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "🛒 You can review, update quantities, and manage items in your [Shopping Cart](/cart). To add products, choose your desired variant on any product card.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 5: Checkout & Purchase (Starter Tier)
    if (msgLower.includes("checkout") || msgLower.includes("ready to buy") || msgLower.includes("purchase") || msgLower.includes("take me to checkout") || msgLower.includes("proceed to checkout")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "⚡ Ready to complete your order? You can [Proceed to Checkout](/checkout) to enter shipping details, apply discounts, and pay securely.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 6: Discount Codes & Promo Validation (Starter Tier)
    if (msgLower.includes("discount") || msgLower.includes("coupon") || msgLower.includes("promo") || msgLower.includes("code") || msgLower.includes("save20")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "🏷️ You can enter your promo or discount code on the [Checkout Page](/checkout) or directly in your [Cart](/cart) to apply savings to your order.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 7: Shipping Rates & Calculation (Starter Tier)
    if (msgLower.includes("ship") || msgLower.includes("delivery") || msgLower.includes("dispatch") || msgLower.includes("freight")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "🚚 We calculate live shipping rates at checkout based on your address. Free shipping and expedited options will appear automatically if eligible during [Checkout](/checkout).",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 8: Returns & Refunds Policy
    if (msgLower.includes("return") || msgLower.includes("refund") || msgLower.includes("exchange") || msgLower.includes("warranty")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "🔄 We want you to love your purchase! If you need to request a return or exchange, please reach out with your order number and our team will be happy to assist.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 9: Payment Methods
    if (msgLower.includes("pay") || msgLower.includes("card") || msgLower.includes("cod") || msgLower.includes("payment")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "💳 We support standard secure payment methods at checkout including all major credit cards, debit cards, and Shopify Pay.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 10: Plan & Feature Inquiries (Strict match to avoid matching words like 'product')
    const isExplicitPlanQuery = /\b(what plan|current plan|subscription plan|pricing tier|upgrade plan|my plan)\b/i.test(msgLower);
    if (isExplicitPlanQuery && !msgLower.includes("product") && !msgLower.includes("item")) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "ℹ️ Our Starter plan includes live Shopify product catalog search, item variant details, cart management, and seamless direct checkout. Upgrade to Pro for full AI shopping assistant capabilities.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 11: Recommendation Requests (Rule 1 & Rule 4)
    const parsedQuery = parseProductSearchQuery(userMessage);
    const isRecommendationQuery =
      msgLower.includes("recommend") ||
      msgLower.includes("suggestion") ||
      msgLower.includes("suggest") ||
      msgLower.includes("gift");

    // Intent 11b: Comparisons (e.g. "Which one is better? blue or black")
    const isComparison =
      /\b(which (?:one )?is (?:better|cheaper|best)|compare|difference between|better.*or|which should i choose)\b/i.test(msgLower);

    if (isComparison) {
      if (msgLower.includes("blue") && msgLower.includes("black")) {
        return {
          provider: "local",
          model: "local-catalog-engine",
          reply: "Both are great choices! Black offers a classic, versatile look for any occasion, while blue adds a fresh, vibrant pop of color. Which style fits your preference best?",
          intent: "general_qa",
          products: undefined,
        };
      }
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "Both are great options! The best choice depends on your personal style and needs. If you're looking for everyday versatility, our popular staples are hard to beat.",
        intent: "general_qa",
        products: undefined,
      };
    }

    // Intent 11c: Gift assistance
    const isGiftQuery =
      /\b(gift|gifts|birthday|anniversary|present|for my friend|for my wife|for my husband)\b/i.test(msgLower) &&
      parsedQuery.keywords.length === 0;

    if (isGiftQuery) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "Finding a great gift is easy! Could you share your budget or what kind of styles/items the recipient likes most?",
        intent: "product_search",
        products: undefined,
      };
    }

    // Intent 11d: Active Item On-Sale Inquiry (e.g. "its sale?", "is it on sale?", "is this on sale?")
    const cleanNoPunct = msgLower.replace(/[^\w\s]/g, " ").trim();
    const isItemSaleCheck =
      /^(is (it|this|that|the product)|its|it's|this is|it is) (on )?sale\??$/i.test(cleanNoPunct) ||
      cleanNoPunct === "its sale" ||
      cleanNoPunct === "it is sale" ||
      cleanNoPunct === "is it sale" ||
      cleanNoPunct === "is this sale" ||
      cleanNoPunct === "is that on sale" ||
      cleanNoPunct === "is it on sale";

    if (isItemSaleCheck) {
      const searchResult = await searchProductsService(shopDomain, "");
      const firstProduct = searchResult.products[0];
      if (firstProduct) {
        const variants = firstProduct.variants || [];
        const onSaleVariant = variants.find((v: any) => v.compareAtPrice && v.compareAtPrice > v.price);
        if (onSaleVariant) {
          return {
            provider: "local",
            model: "local-catalog-engine",
            reply: `Yes, "${firstProduct.title}" is currently on sale! It is discounted down to ${formatCurrency(onSaleVariant.price ?? firstProduct.minPrice, firstProduct.currency)}.`,
            intent: "product_search",
            products: [firstProduct],
          };
        } else {
          return {
            provider: "local",
            model: "local-catalog-engine",
            reply: `"${firstProduct.title}" is currently available at its regular price of ${formatCurrency(firstProduct.minPrice, firstProduct.currency)}.`,
            intent: "product_search",
            products: [firstProduct],
          };
        }
      }
    }

    const isExplicitRecommendationPhrase =
      /^(i want (to find )?)?(products? (and|or) )?recommendations?$/i.test(msgLower) ||
      /^(can you )?(give me |make )?(a )?recommendations?$/i.test(msgLower) ||
      /^(what do you |can you )?recommend( something)?$/i.test(msgLower) ||
      msgLower === "i want product recommendations" ||
      msgLower === "i want to find products and recommendations" ||
      msgLower === "recommendations" ||
      msgLower === "what would you recommend" ||
      msgLower === "what would you recommend?" ||
      msgLower === "what should i buy" ||
      msgLower === "what should i buy?" ||
      msgLower === "help me choose" ||
      msgLower === "help me choose a product" ||
      msgLower === "recommend something";

    const isBroadRecommendation =
      parsedQuery.maxPrice === undefined &&
      parsedQuery.minPrice === undefined &&
      !parsedQuery.isOnSale &&
      !parsedQuery.isLatest &&
      !msgLower.includes("popular") &&
      !msgLower.includes("top pick") &&
      !msgLower.includes("sale") &&
      isExplicitRecommendationPhrase;

    if (isBroadRecommendation) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "Sure! What kind of products are you looking for? Do you have a specific category in mind or any preferences?",
        intent: "product_search",
        products: undefined,
      };
    }

    // Intent 12: Product Search & Browsing (Rule 2, 3, 5, 6, 10)
    const isPopularOrTopPick =
      /\b(popular|top pick|top picks|best seller|bestseller|what'?s popular|whats popular|best product|best recommendation|top recommendation)\b/i.test(msgLower);

    const isLatestQuery =
      Boolean(parsedQuery.isLatest) ||
      /\b(latest|newest|recent|recently added|new arrivals?|new products?|fresh)\b/i.test(msgLower);

    const isSaleQuery =
      Boolean(parsedQuery.isOnSale) ||
      /\b(sale|on sale|discounted|deals?|discount)\b/i.test(msgLower);

    const isBroadBrowse =
      isPopularOrTopPick ||
      isSaleQuery ||
      /^(products?|show products?|browse products?|what do you have\??|show me (your |all |some )?products?|show me everything|all products?|catalog|shop|browse|latest products?|new products?|recent products?|new arrivals?|latest|popular|top pick|top picks|sale products?|discounted products?|sale)$/i.test(
        cleanNoPunct
      ) ||
      (parsedQuery.isBrowseAll && (msgLower.includes("product") || msgLower.includes("show") || msgLower.includes("browse") || msgLower.includes("catalog") || msgLower.includes("everything") || isLatestQuery || isPopularOrTopPick || isSaleQuery));

    const isExplicitProductQuery =
      isBroadBrowse ||
      isLatestQuery ||
      isSaleQuery ||
      parsedQuery.keywords.length > 0 ||
      parsedQuery.maxPrice !== undefined ||
      msgLower.includes("product") ||
      msgLower.includes("buy") ||
      msgLower.includes("search") ||
      msgLower.includes("find") ||
      msgLower.includes("looking for") ||
      msgLower.includes("price") ||
      msgLower.includes("cost") ||
      msgLower.includes("show") ||
      msgLower.includes("catalog") ||
      msgLower.includes("recommend") ||
      msgLower.includes("item") ||
      msgLower.includes("all products") ||
      msgLower.includes("store products") ||
      msgLower.includes("under") ||
      msgLower.includes("cheapest") ||
      msgLower.includes("between") ||
      msgLower.includes("gift") ||
      msgLower.includes("wife") ||
      msgLower.includes("shirt") ||
      msgLower.includes("shoe") ||
      msgLower.includes("dress") ||
      msgLower.includes("hoodie") ||
      msgLower.includes("available") ||
      msgLower.includes("do you have") ||
      msgLower.includes("what do you have") ||
      msgLower.includes("everything") ||
      msgLower.includes("sale");

    if (isExplicitProductQuery) {
      const searchResult = await searchProductsService(shopDomain, (isBroadBrowse || ((isLatestQuery || isSaleQuery) && parsedQuery.keywords.length === 0)) ? "" : userMessage);
      const shopUrl = shopDomain.startsWith("http") ? shopDomain : `https://${shopDomain}/collections/all`;

      if (searchResult.status === "TECHNICAL_ERROR") {
        return {
          provider: "local",
          model: "local-catalog-engine",
          reply: "I'm having trouble connecting to the store catalog right now. Please try again in a moment.",
          intent: "general_qa",
          products: undefined,
        };
      }

      if (searchResult.status === "NO_MATCH" || searchResult.products.length === 0) {
        return {
          provider: "local",
          model: "local-catalog-engine",
          reply: searchResult.message || `I couldn't find any products matching "${parsedQuery.rawKeywordsString || userMessage}". Would you like me to try another style, color, or price range?`,
          intent: "product_search",
          products: undefined,
        };
      }

      const formattedProducts = searchResult.products.slice(0, 4).map((p) => {
        const rawVariants = Array.isArray(p.variants) ? p.variants : [];
        const formattedVariants = rawVariants.map((v: any) => ({
          id: String(v.shopifyVariantId || v.id || v.variantId || ""),
          title: v.title || "Default Title",
          price: formatCurrency(v.price ?? p.minPrice, p.currency),
          numericPrice: v.price ?? p.minPrice,
          compareAtPrice: v.compareAtPrice ? formatCurrency(v.compareAtPrice, p.currency) : null,
          available: v.available !== false,
        }));

        const firstAvailable = formattedVariants.find((v: any) => v.available) || formattedVariants[0];

        return {
          id: String(p.shopifyProductId || p.id),
          title: p.title,
          price: formatCurrency(p.minPrice, p.currency),
          handle: p.handle,
          url: `/products/${p.handle}`,
          imageUrl: p.image || "https://cdn.shopify.com/s/files/1/0533/2089/files/placeholder-images-product-1.png",
          variantId: firstAvailable?.id || "",
          variants: formattedVariants,
          available: formattedVariants.some((v: any) => v.available),
        };
      });

      const reply = isSaleQuery
        ? `✨ Here are the discounted products currently on sale in the store:\n\n[Shop All Products](${shopUrl})`
        : isLatestQuery
        ? `✨ Here are the latest products recently added to the store:\n\n[Shop All Products](${shopUrl})`
        : isPopularOrTopPick
        ? `✨ Here are our top featured and popular picks in the store:\n\n[Shop All Products](${shopUrl})`
        : isBroadBrowse
        ? "Sure! Here are some products currently available in the store."
        : `✨ Here are products matching your request:\n\n[Shop All Products](${shopUrl})`;

      return {
        provider: "local",
        model: "local-catalog-engine",
        reply,
        intent: "product_search",
        products: formattedProducts,
      };
    }

    // Default polite basic response if answer not explicitly found
    const greetings = ["hi", "hello", "hey", "good morning", "good afternoon", "good evening", "howdy", "sup"];
    const isGreeting = greetings.some((g) => msgLower === g || msgLower.startsWith(`${g} `) || msgLower.startsWith(`${g},`));

    if (isGreeting) {
      return {
        provider: "local",
        model: "local-catalog-engine",
        reply: "Hi! 👋 How can I help you find products or track orders today?",
        intent: "general_qa",
        products: undefined,
      };
    }

    return {
      provider: "local",
      model: "local-catalog-engine",
      reply: "How can I assist you with products, orders, or store questions today? You can search for products, view pricing, or ask about our store policies.",
      intent: "general_qa",
      products: undefined,
    };
  } catch (err) {
    logger.error("Error in runLocalShopifyFallback", err);
    return {
      provider: "local",
      model: "local-catalog-engine",
      reply: "Welcome to our store! Please explore our products or let us know how we can help.",
      intent: "general_qa",
      products: undefined,
    };
  }
}

export class LocalFallbackProvider implements AIProvider {
  name: "local" = "local";

  async generateResponse(params: AgentRunParams): Promise<AIProviderResponse> {
    // Pure local catalog & FAQ execution without external AI APIs
    return runLocalShopifyFallback(params);
  }
}
