import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import {
  getNotifications,
  getUnreadCount,
  markNotificationAsRead,
  markAllNotificationsAsRead,
  createNotification,
} from "../services/notification.server";
import { authenticateMerchantOrAdmin } from "../services/admin-auth.server";
import { assertTenantScope } from "../lib/security/tenant-context";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const auth = await authenticateMerchantOrAdmin(request);

  if (!auth.isAuthenticated) {
    return new Response(JSON.stringify({ error: "Unauthorized: Merchant or Admin authentication required" }), {
      status: 401,
      headers: { "Content-Type": "application/json" },
    });
  }

  const url = new URL(request.url);
  const requestedShopId = url.searchParams.get("shopId");
  const countOnly = url.searchParams.get("countOnly") === "true";
  const page = parseInt(url.searchParams.get("page") || "1", 10);
  const pageSize = parseInt(url.searchParams.get("pageSize") || "20", 10);
  const isReadParam = url.searchParams.get("isRead");
  const isRead = isReadParam !== null ? isReadParam === "true" : undefined;

  // Determine effective shopId
  let effectiveShopId: string;
  if (auth.isSaaSAdmin) {
    effectiveShopId = requestedShopId || "global";
  } else {
    effectiveShopId = auth.shopId!;
    // If merchant explicitly requests a different shopId, block IDOR
    if (requestedShopId && requestedShopId !== "global") {
      try {
        assertTenantScope(requestedShopId, effectiveShopId);
      } catch (e: any) {
        return new Response(JSON.stringify({ error: "Cross-tenant access violation blocked" }), {
          status: 403,
          headers: { "Content-Type": "application/json" },
        });
      }
    }
  }

  if (countOnly) {
    const count = await getUnreadCount(effectiveShopId);
    return new Response(JSON.stringify({ count }), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  }

  const data = await getNotifications({
    shopId: effectiveShopId,
    page,
    pageSize,
    isRead,
  });

  const unreadCount = await getUnreadCount(effectiveShopId);

  return new Response(JSON.stringify({ ...data, unreadCount }), {
    status: 200,
    headers: {
      "Content-Type": "application/json",
      "Cache-Control": "no-cache, no-store, must-revalidate",
    },
  });
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const auth = await authenticateMerchantOrAdmin(request);

  if (!auth.isAuthenticated) {
    return new Response(JSON.stringify({ error: "Unauthorized: Merchant or Admin authentication required" }), {
      status: 401,
      headers: { "Content-Type": "application/json" },
    });
  }

  const url = new URL(request.url);
  let body: any = {};
  const contentType = request.headers.get("content-type") || "";

  if (contentType.includes("application/json")) {
    body = await request.json().catch(() => ({}));
  } else if (contentType.includes("form-data") || contentType.includes("urlencoded")) {
    const formData = await request.formData();
    body = Object.fromEntries(formData.entries());
  }

  const requestedShopId = url.searchParams.get("shopId") || body.shopId;
  let effectiveShopId: string;

  if (auth.isSaaSAdmin) {
    effectiveShopId = requestedShopId || "global";
  } else {
    effectiveShopId = auth.shopId!;
    if (requestedShopId && requestedShopId !== "global") {
      try {
        assertTenantScope(requestedShopId, effectiveShopId);
      } catch (e: any) {
        return new Response(JSON.stringify({ error: "Cross-tenant access violation blocked" }), {
          status: 403,
          headers: { "Content-Type": "application/json" },
        });
      }
    }
  }

  const intent = body._intent || body.intent || url.searchParams.get("intent");

  try {
    if (intent === "mark_read" || intent === "read") {
      const id = String(body.id || body.notificationId || "");
      if (!id) {
        return new Response(JSON.stringify({ error: "Missing notification ID" }), { status: 400 });
      }
      const updated = await markNotificationAsRead(id, effectiveShopId);
      const unreadCount = await getUnreadCount(effectiveShopId);
      return new Response(JSON.stringify({ success: true, notification: updated, unreadCount }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    if (intent === "mark_all_read" || intent === "read_all") {
      await markAllNotificationsAsRead(effectiveShopId);
      return new Response(JSON.stringify({ success: true, unreadCount: 0 }), {
        status: 200,
        headers: { "Content-Type": "application/json" },
      });
    }

    if (intent === "create_notification") {
      const newNotif = await createNotification({
        shopId: effectiveShopId === "global" ? null : effectiveShopId,
        type: body.type || "SYSTEM_ALERT",
        title: body.title || "Notification",
        message: body.message || "",
        actionUrl: body.actionUrl,
        metadata: body.metadata,
      });
      const unreadCount = await getUnreadCount(effectiveShopId);
      return new Response(JSON.stringify({ success: true, notification: newNotif, unreadCount }), {
        status: 201,
        headers: { "Content-Type": "application/json" },
      });
    }

    return new Response(JSON.stringify({ error: "Unknown action intent" }), { status: 400 });
  } catch (error: any) {
    return new Response(JSON.stringify({ success: false, error: error.message || "Failed processing request" }), {
      status: 500,
      headers: { "Content-Type": "application/json" },
    });
  }
};
