import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import { getTenantByDomain } from "../lib/security/tenant-context";
import { canUseFeature } from "../lib/billing-plans";
import { parseWidgetSettings } from "../services/widget-settings.server";
import {
  loginCustomer,
  registerCustomer,
  recoverCustomerPassword,
  logoutCustomer,
  getCustomerProfile,
} from "../services/customer.server";
import { logger } from "../lib/security/logger";
import { AppError } from "../lib/security/errors";
import prisma from "../db.server";
import { getDefaultStoreDomainSync } from "../services/platform-settings.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 });
  }

  const url = new URL(request.url);
  const shop = (url.searchParams.get("shop") || getDefaultStoreDomainSync()).toLowerCase().trim();
  const token = url.searchParams.get("token") || request.headers.get("Authorization")?.replace("Bearer ", "");

  try {
    const tenant = await getTenantByDomain(shop);
    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 canUseCustomerAuth = canUseFeature(planTier, "shopify.customer_auth");
    const { widgetTexts } = parseWidgetSettings(settings);
    const customerAuthEnabled = canUseCustomerAuth && (widgetTexts.customerAuthEnabled === true);

    if (!canUseCustomerAuth || !customerAuthEnabled) {
      return new Response(
        JSON.stringify({
          success: false,
          code: "CUSTOMER_AUTH_DISABLED",
          error: "Customer Login & Registration is unavailable or inactive.",
          canUseCustomerAuth,
          customerAuthEnabled: false,
        }),
        { status: 403, headers: corsHeaders }
      );
    }

    if (token) {
      const profile = await getCustomerProfile(shop, token);
      return new Response(
        JSON.stringify({
          success: true,
          authenticated: true,
          customer: profile.customer,
        }),
        { headers: corsHeaders }
      );
    }

    return new Response(
      JSON.stringify({
        success: true,
        canUseCustomerAuth: true,
        customerAuthEnabled: true,
        status: "Customer authentication service active",
      }),
      { headers: corsHeaders }
    );
  } catch (error: any) {
    return new Response(
      JSON.stringify({ success: false, error: error.message || "Failed to check customer status" }),
      { status: 500, 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 {
      return new Response(
        JSON.stringify({ success: false, error: "Invalid JSON body payload" }),
        { status: 400, headers: corsHeaders }
      );
    }

    const {
      action: authAction,
      shop: bodyShop,
      email,
      password,
      firstName,
      lastName,
      customerAccessToken,
    } = body || {};

    const shop = (bodyShop || queryShop || getDefaultStoreDomainSync()).toLowerCase().trim();

    // 1. Resolve tenant shop
    const tenant = await getTenantByDomain(shop);

    // 2. Enforce Backend Plan Capability & Active/Inactive Toggle Check
    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 canUseCustomerAuth = canUseFeature(planTier, "shopify.customer_auth");
    const { widgetTexts } = parseWidgetSettings(settings);
    const customerAuthEnabled = canUseCustomerAuth && (widgetTexts.customerAuthEnabled === true);

    // Free plan or inactive status strictly forbidden
    if (!canUseCustomerAuth || !customerAuthEnabled) {
      logger.warn("Customer auth operation blocked by plan restriction or inactive toggle", {
        shop,
        planTier,
        canUseCustomerAuth,
        customerAuthEnabled,
      });

      return new Response(
        JSON.stringify({
          success: false,
          code: "CUSTOMER_AUTH_DISABLED",
          error: !canUseCustomerAuth
            ? "Customer Login & Registration is only available on Starter and Pro plans."
            : "Customer Login & Registration is currently set to Inactive by the store merchant.",
          canUseCustomerAuth,
          customerAuthEnabled: false,
        }),
        { status: 403, headers: corsHeaders }
      );
    }

    // 3. Dispatch Auth Operation
    switch (authAction) {
      case "login": {
        const result = await loginCustomer(shop, email, password);
        return new Response(JSON.stringify(result), {
          status: result.success ? 200 : 400,
          headers: corsHeaders,
        });
      }

      case "register": {
        const result = await registerCustomer(shop, {
          firstName,
          lastName,
          email,
          password,
        });
        return new Response(JSON.stringify(result), {
          status: result.success ? 200 : 400,
          headers: corsHeaders,
        });
      }

      case "forgot_password":
      case "recover": {
        const result = await recoverCustomerPassword(shop, email);
        return new Response(JSON.stringify(result), {
          status: result.success ? 200 : 400,
          headers: corsHeaders,
        });
      }

      case "logout": {
        const result = await logoutCustomer(shop, customerAccessToken);
        return new Response(JSON.stringify(result), {
          status: 200,
          headers: corsHeaders,
        });
      }

      case "profile":
      case "get_profile": {
        const token = customerAccessToken || request.headers.get("Authorization")?.replace("Bearer ", "");
        const result = await getCustomerProfile(shop, token || "");
        return new Response(JSON.stringify(result), {
          status: result.success ? 200 : 401,
          headers: corsHeaders,
        });
      }

      default: {
        return new Response(
          JSON.stringify({
            success: false,
            error: `Unsupported authentication action: '${authAction}'. Valid actions are: login, register, forgot_password, logout, profile.`,
          }),
          { status: 400, headers: corsHeaders }
        );
      }
    }
  } catch (error: any) {
    if (error instanceof AppError) {
      return new Response(
        JSON.stringify({ success: false, error: error.message, code: error.code }),
        { status: error.statusCode, headers: corsHeaders }
      );
    }

    logger.error("Customer authentication API error", error);
    return new Response(
      JSON.stringify({
        success: false,
        error: error.message || "An error occurred while processing authentication.",
      }),
      { status: 500, headers: corsHeaders }
    );
  }
};
