import { ExecArgs } from "@medusajs/framework/types";
import { ContainerRegistrationKeys, Modules } from "@medusajs/framework/utils";
import {
  createShippingOptionsWorkflow,
  updateShippingOptionsWorkflow,
} from "@medusajs/medusa/core-flows";

const MONDIAL_RELAY_PROVIDER_ID = "manual_manual";
const MONDIAL_RELAY_TYPE_CODE = "mondial-relay";
const MONDIAL_RELAY_NAME = "Mondial Relay - Point Relais";

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

export default async function setupMondialRelayShippingOptions({ container }: ExecArgs) {
  const logger = container.resolve(ContainerRegistrationKeys.LOGGER);
  const query = container.resolve(ContainerRegistrationKeys.QUERY);
  const link = container.resolve(ContainerRegistrationKeys.LINK);

  const { data: stockLocations } = await query.graph({
    entity: "stock_location",
    fields: ["id"],
  });

  for (const location of stockLocations || []) {
    const stockLocationId = asString((location as { id?: string }).id);
    if (!stockLocationId) {
      continue;
    }

    try {
      await link.create({
        [Modules.STOCK_LOCATION]: {
          stock_location_id: stockLocationId,
        },
        [Modules.FULFILLMENT]: {
          fulfillment_provider_id: MONDIAL_RELAY_PROVIDER_ID,
        },
      });
    } catch {
      // Best effort, link may already exist.
    }
  }

  const { data: serviceZones } = await query.graph({
    entity: "service_zone",
    fields: ["id", "name"],
  });

  if (!serviceZones?.length) {
    throw new Error("No service zones found. Create a stock location/service zone first.");
  }

  const { data: shippingProfiles } = await query.graph({
    entity: "shipping_profile",
    fields: ["id", "name", "type"],
  });

  const defaultShippingProfile =
    (shippingProfiles || []).find((profile: { type?: string }) => profile.type === "default") ||
    shippingProfiles?.[0];

  if (!defaultShippingProfile?.id) {
    throw new Error("No shipping profile found.");
  }

  const { data: existingOptions } = await query.graph({
    entity: "shipping_option",
    fields: [
      "id",
      "name",
      "provider_id",
      "service_zone_id",
      "type.code",
      "shipping_profile_id",
      "data",
    ],
  });

  const byServiceZone = new Map<string, Record<string, unknown>>();
  for (const option of existingOptions || []) {
    const optionRecord = option as Record<string, unknown>;
    const serviceZoneId = asString(optionRecord.service_zone_id);
    if (!serviceZoneId || byServiceZone.has(serviceZoneId)) {
      continue;
    }

    const typeCode = asString((optionRecord.type as { code?: string } | undefined)?.code).toLowerCase();
    const optionName = asString(optionRecord.name).toLowerCase();
    const providerId = asString(optionRecord.provider_id).toLowerCase();
    const isMondialRelay =
      typeCode === MONDIAL_RELAY_TYPE_CODE ||
      optionName.includes("mondial relay") ||
      providerId.includes("mondialrelay");

    if (isMondialRelay) {
      byServiceZone.set(serviceZoneId, optionRecord);
    }
  }

  const toCreate: Array<Record<string, unknown>> = [];
  const toUpdate: Array<Record<string, unknown>> = [];

  for (const zone of serviceZones as Array<{ id: string }>) {
    const existing = byServiceZone.get(zone.id);
    const baseInput = {
      name: MONDIAL_RELAY_NAME,
      provider_id: MONDIAL_RELAY_PROVIDER_ID,
      shipping_profile_id: String(defaultShippingProfile.id),
      price_type: "flat" as const,
      data: {
        id: "mondialrelay-point-relais",
        name: MONDIAL_RELAY_NAME,
        type: "relay",
      },
      type: {
        label: "Mondial Relay",
        description: "Livraison en Point Relais.",
        code: MONDIAL_RELAY_TYPE_CODE,
      },
      rules: [
        {
          attribute: "enabled_in_store",
          value: "true",
          operator: "eq" as const,
        },
        {
          attribute: "is_return",
          value: "false",
          operator: "eq" as const,
        },
      ],
      prices: [
        { currency_code: "eur", amount: 0 },
        { currency_code: "usd", amount: 0 },
      ],
    };

    if (existing?.id) {
      toUpdate.push({
        id: String(existing.id),
        ...baseInput,
      });
    } else {
      toCreate.push({
        ...baseInput,
        service_zone_id: zone.id,
      });
    }
  }

  if (toUpdate.length) {
    await updateShippingOptionsWorkflow(container).run({
      input: toUpdate as any,
    });
    logger.info(`Updated ${toUpdate.length} Mondial Relay shipping option(s).`);
  }

  if (toCreate.length) {
    await createShippingOptionsWorkflow(container).run({
      input: toCreate as any,
    });
    logger.info(`Created ${toCreate.length} Mondial Relay shipping option(s).`);
  }

  if (!toCreate.length && !toUpdate.length) {
    logger.info("Mondial Relay shipping options already up to date.");
  }
}
