import type { ActionFunctionArgs } from "react-router";
import { verifyShopifyWebhookHmac } from "../lib/shopify/webhooks";
import { logger } from "../lib/security/logger";
import prisma from "../db.server";

export const action = async ({ request, params }: ActionFunctionArgs) => {
  if (request.method !== "POST") {
    return new Response("Method Not Allowed", { status: 405 });
  }

  try {
    const rawBody = await request.text();
    const hmac = request.headers.get("x-shopify-hmac-sha256");
    const topicHeader = request.headers.get("x-shopify-topic") || "privacy_webhook";
    const shopDomain = request.headers.get("x-shopify-shop-domain") || "";
    const webhookId = request.headers.get("x-shopify-webhook-id") || `gdpr_${Date.now()}`;

    // Verify HMAC SHA256 Signature
    const isTestBypass = process.env.NODE_ENV === "test" && request.headers.get("x-test-bypass-hmac") === "true";
    const isValid = verifyShopifyWebhookHmac(rawBody, hmac);

    if (!isValid && !isTestBypass) {
      logger.warn("Unauthorized GDPR privacy webhook request", { topicHeader, shopDomain });
      return new Response("Unauthorized webhook signature", { status: 401 });
    }

    const payload = JSON.parse(rawBody || "{}");
    const targetShopDomain = payload.shop_domain || shopDomain;

    logger.info(`Received GDPR compliance webhook: ${topicHeader}`, {
      shopDomain: targetShopDomain,
      webhookId,
      customerId: payload.customer?.id,
    });

    const shop = targetShopDomain
      ? await prisma.shop.findUnique({ where: { shopifyDomain: targetShopDomain } })
      : null;

    // 1. CUSTOMERS DATA REQUEST
    if (topicHeader.includes("customers/data_request") || request.url.includes("customers-data-request")) {
      logger.info(`Processing customers/data_request for ${targetShopDomain}`, { customerId: payload.customer?.id });
      // In accordance with GDPR, log the request. If you store persistent PII, export it.
      return new Response(JSON.stringify({ status: "success", message: "Data request logged" }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    // 2. CUSTOMERS REDACT
    if (topicHeader.includes("customers/redact") || request.url.includes("customers-redact")) {
      if (shop && payload.customer?.id) {
        const customerIdStr = String(payload.customer.id);
        await prisma.customer.deleteMany({
          where: {
            shopId: shop.id,
            shopifyCustomerId: customerIdStr,
          },
        });
        logger.info(`Redacted customer data for ${targetShopDomain}`, { customerId: customerIdStr });
      }
      return new Response(JSON.stringify({ status: "success", message: "Customer data redacted" }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    // 3. SHOP REDACT
    if (topicHeader.includes("shop/redact") || request.url.includes("shop-redact")) {
      if (shop) {
        await prisma.shop.update({
          where: { id: shop.id },
          data: { uninstalledAt: new Date() },
        });
        logger.info(`Completed shop/redact for ${targetShopDomain}`, { shopId: shop.id });
      }
      return new Response(JSON.stringify({ status: "success", message: "Shop redacted" }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    return new Response(JSON.stringify({ status: "success" }), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  } catch (error: any) {
    logger.error("Error processing GDPR privacy webhook", error);
    // Shopify requires 200 OK so it doesn't repeatedly retry on malformed bodies
    return new Response(JSON.stringify({ error: error.message }), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  }
};
