import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { generateAIResponse } from "../services/ai.server";
import { getTenantByDomain } from "../lib/security/tenant-context";
import { reserveAndConsumeCredits } from "../services/credit-ledger.server";
import { incrementUsage, checkUsageLimit } from "../services/billing.server";
import { canUseFeature } from "../lib/billing-plans";
import prisma from "../db.server";

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
  "Content-Type": "application/json",
  "Cache-Control": "no-cache, no-store, must-revalidate, max-age=0",
  "Pragma": "no-cache",
  "Expires": "0",
};

export const loader = async ({ request }: LoaderFunctionArgs) => {
  if (request.method === "OPTIONS") {
    return new Response(null, { headers: corsHeaders });
  }
  return new Response(JSON.stringify({ status: "AI Chat API active" }), { headers: corsHeaders });
};

export const action = async ({ request }: ActionFunctionArgs) => {
  if (request.method === "OPTIONS") {
    return new Response(null, { headers: corsHeaders });
  }

  try {
    const body = await request.json();
    const { message, shop } = body || {};

    if (!message) {
      return new Response(
        JSON.stringify({
          success: false,
          reply: "Please provide a message query.",
        }),
        { status: 400, headers: corsHeaders }
      );
    }

    const currentShop = shop || "quickstart-1a79b82e.myshopify.com";
    const tenant = await getTenantByDomain(currentShop);

    // 1. Enforce Plan Capability & AI Quota
    const usageCheck = await checkUsageLimit(tenant.shopId);
    const hasAIAccess = canUseFeature(usageCheck.plan, "openai");

    if (!hasAIAccess) {
      const { runLocalShopifyFallback } = await import("../lib/ai/local-provider");
      const localResult = await runLocalShopifyFallback({
        shopDomain: currentShop,
        sessionId: `session_${Date.now()}`,
        userMessage: message,
      });

      return new Response(
        JSON.stringify({
          success: true,
          reply: localResult.reply,
          intent: localResult.intent || "general_qa",
          products: localResult.products || [],
          articles: localResult.articles || [],
          orderInfo: localResult.orderInfo,
          botName: "ConverseCart Assistant",
        }),
        { headers: corsHeaders }
      );
    }

    if (usageCheck.limitReached) {
      const quotaMsg = `Your monthly AI usage limit (${usageCheck.monthlyLimit?.toLocaleString() || 25000} requests) has been reached. Please upgrade or purchase booster credits to continue using AI features.`;
      return new Response(
        JSON.stringify({
          success: false,
          code: "AI_USAGE_LIMIT_REACHED",
          limitReached: true,
          currentUsage: usageCheck.currentUsage,
          monthlyLimit: usageCheck.monthlyLimit,
          reply: `⚠️ ${quotaMsg}`,
          message: quotaMsg,
          products: [],
        }),
        { status: 403, headers: corsHeaders }
      );
    }

    // 1b. Enforce Credit Balance & Consumption (FEFO/FIFO)
    const creditResult = await reserveAndConsumeCredits({
      shopId: tenant.shopId,
      creditsNeeded: 1,
      eventType: "AI_CHAT_REQUEST",
    });

    if (!creditResult.success) {
      return new Response(
        JSON.stringify({
          success: false,
          limitReached: true,
          error: "usage_limit_reached",
          reply: "Your monthly usage limit or credit balance has been reached. Please purchase or upgrade your plan to continue using AI features.",
          products: [],
        }),
        { status: 403, headers: corsHeaders }
      );
    }

    // 2. Call AI Engine with store context (only if within usage limits)
    const aiResult = await generateAIResponse({
      userMessage: message,
      shop: currentShop,
    });

    const shopRecord = await prisma.shop.findUnique({
      where: { id: tenant.shopId },
      include: { chatbotSettings: true },
    });

    // 3. Atomically increment usage
    await incrementUsage(tenant.shopId);

    await prisma.usageRecord.create({
      data: {
        shopId: tenant.shopId,
        type: "ai_message",
        quantity: 1,
        metadata: { intent: aiResult.intent || "general_inquiry" },
      },
    });

    await prisma.auditLog.create({
      data: {
        shopId: tenant.shopId,
        action: "AI Chat Interaction",
        resource: `Intent: ${aiResult.intent || "general"}`,
        status: "SUCCESS",
      },
    });

    return new Response(
      JSON.stringify({
        success: true,
        reply: aiResult.reply,
        intent: aiResult.intent,
        products: aiResult.products || [],
        articles: aiResult.articles || [],
        orderInfo: aiResult.orderInfo,
        botName: shopRecord?.chatbotSettings?.botName || "ConverseCart Assistant",
      }),
      { headers: corsHeaders }
    );
  } catch (error: any) {
    console.error("[AI Chat API Error]:", error);
    const isForbidden = error?.statusCode === 403 || error?.name === "TenantAccessDeniedError" || String(error?.message || "").toLowerCase().includes("uninstalled");
    if (isForbidden) {
      return new Response(
        JSON.stringify({
          success: false,
          isUninstalled: true,
          error: "Store chatbot is uninstalled or inactive.",
          reply: "Chatbot service is disabled because this store is currently uninstalled or inactive.",
          products: [],
        }),
        { status: 403, headers: corsHeaders }
      );
    }
    return new Response(
      JSON.stringify({
        success: false,
        reply: "I'm having a little trouble connecting to the AI service. How else can I assist you with your shopping?",
        products: [],
      }),
      { status: 500, headers: corsHeaders }
    );
  }
};
