import { json, type ActionFunctionArgs, type LoaderFunctionArgs } from "@remix-run/node";
import { v4 as uuidv4 } from "uuid";
import { authenticate, unauthenticated } from "../shopify.server";
import { runActivityCheck } from "../services/activity.server";
import { getActivityConfig } from "../services/config.server";
import { callPush, callStatus } from "../services/dreame-client.server";
import { findSuccessfulPush, recordSuccessfulPush } from "../services/idempotency.server";
import { logActivityPush } from "../services/logger.server";
import { getOrderDetails } from "../services/order.server";

const CORS_HEADERS = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers": "Authorization, Content-Type",
  "Access-Control-Allow-Methods": "POST, OPTIONS",
};

type ActivityRequestBody = {
  orderId?: string;
  orderNumber?: string;
  locale?: string;
};

export async function loader({ request }: LoaderFunctionArgs) {
  if (request.method === "OPTIONS") {
    return new Response(null, { status: 204, headers: CORS_HEADERS });
  }

  return json({ success: false }, { status: 405, headers: CORS_HEADERS });
}

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

  if (request.method !== "POST") {
    return json({ success: false }, { status: 405, headers: CORS_HEADERS });
  }

  try {
    const checkoutAuth = (authenticate as unknown as { public?: { checkout?: (request: Request) => Promise<unknown> } })
      .public?.checkout;
    if (!checkoutAuth) {
      throw new Error("Shopify checkout authentication is unavailable");
    }

    const authResult = (await checkoutAuth(request)) as {
      shop?: string;
      admin?: unknown;
      sessionToken?: { dest?: string; iss?: string };
      session?: { shop?: string };
    };
    const shop = authResult.shop || authResult.session?.shop || shopFromSessionToken(authResult.sessionToken);
    const adminResult = authResult.admin ? { admin: authResult.admin } : shop ? await unauthenticated.admin(shop) : null;
    const admin = adminResult?.admin as {
      graphql: (query: string, options?: { variables?: Record<string, unknown> }) => Promise<Response>;
    };
    if (!shop || !admin) {
      throw new Error("Invalid Shopify checkout session");
    }

    const body = (await request.json()) as ActivityRequestBody;
    if (!body.orderId) {
      return json({ success: false }, { headers: CORS_HEADERS });
    }

    const result = await runActivityCheck(
      {
        shop,
        orderId: body.orderId,
        orderNumber: body.orderNumber,
        locale: body.locale,
      },
      {
        nowMs: () => Date.now(),
        uuid: uuidv4,
        getOrder: (_shop, orderId) => getOrderDetails(admin, orderId),
        getConfig: () => getActivityConfig(admin),
        findSuccess: findSuccessfulPush,
        recordSuccess: recordSuccessfulPush,
        log: logActivityPush,
        callStatus,
        callPush,
      },
    );

    return json(result, { headers: CORS_HEADERS });
  } catch {
    return json({ success: false }, { headers: CORS_HEADERS });
  }
}

function shopFromSessionToken(sessionToken: { dest?: string; iss?: string } | undefined): string | undefined {
  const source = sessionToken?.dest || sessionToken?.iss;
  if (!source) {
    return undefined;
  }

  try {
    return new URL(source).hostname;
  } catch {
    return source.replace(/^https?:\/\//, "").split("/")[0];
  }
}
