import { SubscriberArgs, SubscriberConfig } from "@medusajs/framework";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";
import { createOrderFulfillmentWorkflow } from "@medusajs/medusa/core-flows";
import orderMondialRelayShipmentSubscriber from "./order-mondialrelay-shipment";

type EventData = {
  id?: string;
  order_id?: string;
};

type OrderRecord = {
  id: string;
  shipping_methods?: Array<{
    shipping_option_id?: string | null;
    data?: Record<string, unknown> | null;
  }>;
  items?: Array<{
    id: string;
    quantity?: number | null;
  }>;
  fulfillments?: Array<{
    id: string;
    canceled_at?: string | Date | null;
  }>;
};

function asString(value: unknown) {
  return typeof value === "string" ? value.trim() : "";
}

function parseMondialRelayOptionIdsFromEnv() {
  return asString(process.env.MONDIAL_RELAY_SHIPPING_OPTION_IDS)
    .split(",")
    .map((id) => id.trim())
    .filter(Boolean);
}

function hasOpenFulfillment(order: OrderRecord) {
  return (order.fulfillments || []).some((fulfillment) => !fulfillment.canceled_at);
}

function isMondialRelayShippingMethod(order: OrderRecord) {
  const shippingMethod = (order.shipping_methods || [])[0];
  if (!shippingMethod) {
    return false;
  }

  const shippingOptionId = asString(shippingMethod.shipping_option_id);
  const configuredIds = parseMondialRelayOptionIdsFromEnv();
  if (configuredIds.length && shippingOptionId) {
    return configuredIds.includes(shippingOptionId);
  }

  const data = (shippingMethod.data || {}) as Record<string, unknown>;
  const metadata = (data.metadata || {}) as Record<string, unknown>;
  const metadataId = asString(metadata.id).toLowerCase();
  const optionName = asString(data.shipping_option_name).toLowerCase();
  const hasRelayPoint = Boolean(
    asString(data.parcel_shop_id) || asString(data.relay_point_id) || asString(data.parcelShopId),
  );

  if (hasRelayPoint) {
    return true;
  }

  if (metadataId.includes("mondial") || metadataId.includes("relay")) {
    return true;
  }

  return optionName.includes("mondial") || optionName.includes("relay");
}

function getFulfillmentItems(order: OrderRecord) {
  return (order.items || [])
    .map((item) => ({
      id: item.id,
      quantity: Math.max(1, Number(item.quantity || 1)),
    }))
    .filter((item) => Boolean(item.id));
}

export default async function orderMondialRelayAutoFulfillmentSubscriber({
  event,
  container,
}: SubscriberArgs<EventData>) {
  const logger = container.resolve(ContainerRegistrationKeys.LOGGER);
  const query = container.resolve(ContainerRegistrationKeys.QUERY);

  const orderId = asString(event.data?.id || event.data?.order_id);
  if (!orderId) {
    return;
  }

  try {
    const response = await query.graph({
      entity: "order",
      fields: [
        "id",
        "shipping_methods.shipping_option_id",
        "shipping_methods.data",
        "items.id",
        "items.quantity",
        "fulfillments.id",
        "fulfillments.canceled_at",
      ],
      filters: { id: orderId },
    });

    const order = (response.data?.[0] || null) as OrderRecord | null;
    if (!order) {
      logger.warn(`[mondial-relay] order ${orderId}: not found.`);
      return;
    }

    if (!isMondialRelayShippingMethod(order)) {
      return;
    }

    if (hasOpenFulfillment(order)) {
      logger.info(`[mondial-relay] order ${order.id}: fulfillment already exists, skip auto-create.`);
      return;
    }

    const shippingMethod = (order.shipping_methods || [])[0];
    const shippingOptionId = asString(shippingMethod?.shipping_option_id);
    const items = getFulfillmentItems(order);
    if (!shippingOptionId || !items.length) {
      logger.warn(`[mondial-relay] order ${order.id}: missing shipping option or shippable items.`);
      return;
    }

    const { result } = await createOrderFulfillmentWorkflow(container).run({
      input: {
        order_id: order.id,
        shipping_option_id: shippingOptionId,
        items,
        no_notification: false,
      },
    });

    logger.info(`[mondial-relay] order ${order.id}: auto fulfillment created (${result?.id || "unknown"}).`);

    const createdFulfillmentId = asString(result?.id);
    if (createdFulfillmentId) {
      await orderMondialRelayShipmentSubscriber({
        container,
        event: {
          name: "order.fulfillment_created",
          data: {
            id: order.id,
            order_id: order.id,
            fulfillment_id: createdFulfillmentId,
          },
          metadata: {},
          options: {},
          source: "order-mondialrelay-auto-fulfillment",
        },
      } as any);
    }
  } catch (error: any) {
    const message = error?.message ? String(error.message) : "unknown error";
    logger.error(`[mondial-relay] order ${orderId}: auto fulfillment failed - ${message}`);
  }
}

export const config: SubscriberConfig = {
  event: ["order.placed", "order.completed"],
  context: {
    subscriberId: "order-mondialrelay-auto-fulfillment",
  },
};
