import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { getTenantByDomain } from "../lib/security/tenant-context";
import { canUseFeature } from "../lib/billing-plans";
import { logger } from "../lib/security/logger";
import { AppError } from "../lib/security/errors";
import { syncStoreCatalog } from "../services/catalog.server";
import { parseWidgetSettings } from "../services/widget-settings.server";
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, { status: 204, headers: corsHeaders });
  }
  return new Response(JSON.stringify({ status: "Chat session endpoint ready" }), { headers: corsHeaders });
};

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

  try {
    const url = new URL(request.url);
    const queryShop = url.searchParams.get("shop");
    let body: any = {};

    try {
      const text = await request.text();
      if (text) {
        body = JSON.parse(text);
      }
    } catch (parseErr) {
      logger.warn("Validation failure in /api/chat/session: Malformed JSON body payload");
      return new Response(
        JSON.stringify({ success: false, error: "Invalid JSON body payload" }),
        { status: 400, headers: corsHeaders }
      );
    }

    const { shop: bodyShop, anonymousSessionId, liveProducts } = body || {};
    const shop = (bodyShop || queryShop || "quickstart-1a79b82e.myshopify.com").toLowerCase().trim();

    if (!shop) {
      logger.warn("Validation failure in /api/chat/session: Shop parameter is required");
      return new Response(
        JSON.stringify({ success: false, error: "Shop parameter is required" }),
        { status: 400, headers: corsHeaders }
      );
    }

    // 1. Validate tenant shop context safely
    const tenant = await getTenantByDomain(shop);

    // Sync live storefront products if provided by widget
    if (liveProducts && Array.isArray(liveProducts) && liveProducts.length > 0) {
      await syncStoreCatalog(shop, liveProducts).catch((err) => {
        logger.warn("Failed to auto-sync storefront products in session init", { error: err.message });
      });
    }

    // 2. Check Subscription & Monthly Usage Limits
    const subscription = await prisma.subscription.findFirst({
      where: { shopId: tenant.shopId, status: "ACTIVE" },
    });

    if (subscription && subscription.currentUsage >= subscription.monthlyLimit) {
      logger.warn(`Subscription usage limit reached for shop ${shop}`, { shopId: tenant.shopId });
      return new Response(
        JSON.stringify({
          success: false,
          error: "Monthly conversation limit reached for this store.",
          limitReached: true,
        }),
        { status: 429, headers: corsHeaders }
      );
    }

    const sessionIdKey = anonymousSessionId || `anon_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;

    // 3. Upsert / Create ChatSession
    const sessionRecord = await prisma.chatSession.upsert({
      where: { id: sessionIdKey },
      update: {
        updatedAt: new Date(),
      },
      create: {
        id: sessionIdKey,
        shopId: tenant.shopId,
        anonymousSessionId: sessionIdKey,
        status: "ACTIVE",
      },
    });

    // 4. Fetch Chatbot Branding Settings & Active Subscription
    const [settings, activeSub] = await Promise.all([
      prisma.chatbotSettings.findUnique({
        where: { shopId: tenant.shopId },
      }),
      prisma.subscription.findFirst({
        where: { shopId: tenant.shopId, status: "ACTIVE" },
        orderBy: { createdAt: "desc" },
      }),
    ]);

    const planTier = activeSub?.plan || "FREE";
    const isFreePlan = planTier === "FREE";
    const showPoweredBy = isFreePlan ? true : (settings?.showPoweredBy ?? true);
    const { widgetTexts } = parseWidgetSettings(settings);
    const isChatbotAdminDisabled = widgetTexts.adminDisabled === true;
    const isEnabled = isChatbotAdminDisabled ? false : (settings?.enabled ?? true);

    return new Response(
      JSON.stringify({
        success: true,
        sessionId: sessionRecord.id,
        botName: widgetTexts.botName || settings?.botName || "ConverseCart Assistant",
        headerSubtext: widgetTexts.headerSubtext,
        headerInputPlaceholder: widgetTexts.headerInputPlaceholder,
        startHeading: widgetTexts.startHeading,
        startSubheading: widgetTexts.startSubheading,
        starterPrompts: widgetTexts.starterPrompts,
        disclaimerText: widgetTexts.disclaimerText,
        disclaimerLinkText: widgetTexts.disclaimerLinkText,
        disclaimerUrl: widgetTexts.disclaimerUrl,
        chatInputPlaceholder: widgetTexts.chatInputPlaceholder,
        footerTermsText: widgetTexts.footerTermsText,
        supportMenuItemText: widgetTexts.supportMenuItemText,
        clearMenuItemText: widgetTexts.clearMenuItemText,
        welcomeMessage: settings?.welcomeMessage || "Hi 👋 How can I help you find products or track orders today?",
        primaryColor: settings?.primaryColor || "#4F46E5",
        secondaryColor: settings?.secondaryColor || "#4338CA",
        textColor: settings?.textColor || "#FFFFFF",
        botTextColor: settings?.botTextColor || "#1F2937",
        showPoweredBy,
        showCartSummary: widgetTexts.showCartSummary !== false,
        planTier,
        canUseProducts: canUseFeature(planTier, "shopify.products"),
        canUseCart: canUseFeature(planTier, "shopify.cart"),
        canUseCheckout: canUseFeature(planTier, "shopify.checkout"),
        canUseCustomerAuth: canUseFeature(planTier, "shopify.customer_auth"),
        customerAuthEnabled: canUseFeature(planTier, "shopify.customer_auth") && (widgetTexts.customerAuthEnabled === true),
        canUseAI: canUseFeature(planTier, "openai"),
        position: settings?.position || "bottom-right",
        isEnabled,
        adminDisabled: isChatbotAdminDisabled,
      }),
      { headers: corsHeaders }
    );
  } catch (error: any) {
    if (error instanceof AppError) {
      logger.warn(`Validation failure in /api/chat/session: ${error.message}`, {
        code: error.code,
        statusCode: error.statusCode,
      });
      const isUninstalled = error.statusCode === 403 || String(error.message).toLowerCase().includes("uninstalled");
      return new Response(
        JSON.stringify({
          success: false,
          isEnabled: !isUninstalled,
          isUninstalled,
          error: error.message,
        }),
        { status: error.statusCode, headers: corsHeaders }
      );
    }

    logger.error("Failed to initialize chat session", error);
    return new Response(
      JSON.stringify({ success: false, error: error.message || "Failed to initialize session" }),
      { status: 500, headers: corsHeaders }
    );
  }
};
