import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
import {
  getNotifications,
  getUnreadCount,
  markNotificationAsRead,
  markAllNotificationsAsRead,
  createNotification,
} from "../services/notification.server";
import { authenticateAdminRequest } from "../services/admin-auth.server";
import prisma from "../db.server";

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const url = new URL(request.url);
  const shopDomain = url.searchParams.get("shop");
  let shopId = 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;

  if (!shopId && shopDomain) {
    const shop = await prisma.shop.findUnique({
      where: { shopifyDomain: shopDomain.toLowerCase().trim() },
      select: { id: true },
    });
    if (shop) shopId = shop.id;
  }

  if (shopId === "global") {
    const auth = authenticateAdminRequest(request);
    if (!auth.isAuthenticated) {
      return new Response(JSON.stringify({ error: "Unauthorized admin request" }), {
        status: 401,
        headers: { "Content-Type": "application/json" },
      });
    }
  }

  if (!shopId) {
    return new Response(JSON.stringify({ error: "Unauthorized: Valid shop or tenant shopId parameter is required" }), {
      status: 401,
      headers: { "Content-Type": "application/json" },
    });
  }

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

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

  const unreadCount = await getUnreadCount(shopId);

  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 url = new URL(request.url);
  let shopId = url.searchParams.get("shopId");
  const shopDomain = url.searchParams.get("shop");

  if (!shopId && shopDomain) {
    const shop = await prisma.shop.findUnique({
      where: { shopifyDomain: shopDomain.toLowerCase().trim() },
      select: { id: true },
    });
    if (shop) shopId = shop.id;
  }

  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 effectiveShopId = shopId || body.shopId;

  if (effectiveShopId === "global") {
    const auth = authenticateAdminRequest(request);
    if (!auth.isAuthenticated) {
      return new Response(JSON.stringify({ error: "Unauthorized admin request" }), {
        status: 401,
        headers: { "Content-Type": "application/json" },
      });
    }
  }

  if (!effectiveShopId) {
    return new Response(JSON.stringify({ error: "Unauthorized: Valid shopId context required" }), {
      status: 401,
      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, shopId || body.shopId);
      const unreadCount = await getUnreadCount(shopId || body.shopId);
      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(shopId || body.shopId);
      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: shopId || body.shopId,
        type: body.type || "SYSTEM_ALERT",
        title: body.title,
        message: body.message,
        actionUrl: body.actionUrl,
        metadata: body.metadata,
      });
      const unreadCount = await getUnreadCount(shopId || body.shopId);
      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" },
    });
  }
};
