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

const OPTION_NAME = "Retrait sur place";
const OPTION_CODE = "local-pickup";
const OPTION_LABEL = "Retrait";
const OPTION_DESCRIPTION = "Retrait sur place sans frais de livraison.";

export default async function createLocalPickupShippingOption({ container }: ExecArgs) {
  const logger = container.resolve(ContainerRegistrationKeys.LOGGER);
  const query = container.resolve(ContainerRegistrationKeys.QUERY);
  const fulfillmentModuleService = container.resolve(Modules.FULFILLMENT);

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

  const eurRegion = (regions || []).find(
    (region: { currency_code?: string }) => String(region.currency_code || "").toLowerCase() === "eur",
  ) as { id: string } | undefined;

  if (!eurRegion?.id) {
    throw new Error("No EUR region found.");
  }

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

  const existing = (existingOptions || []).find((option: Record<string, unknown>) => {
    const typeCode = String((option.type as { code?: string } | undefined)?.code || "").toLowerCase();
    const name = String(option.name || "").toLowerCase();
    return typeCode === OPTION_CODE || name === OPTION_NAME.toLowerCase();
  }) as { id?: string; name?: string } | undefined;

  if (existing?.id) {
    logger.info(`Shipping option already exists: ${existing.id} (${existing.name || OPTION_NAME}).`);
    return;
  }

  const shippingProfiles = await fulfillmentModuleService.listShippingProfiles({ type: "default" });
  const shippingProfile = shippingProfiles[0];

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

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

  const fulfillmentSet = (fulfillmentSets || []).find((candidate: Record<string, unknown>) => {
    const serviceZones = ((candidate.service_zones as Array<{ id?: string }> | undefined) || []).filter((zone) => zone?.id);
    return serviceZones.length > 0;
  }) as { id?: string; name?: string; service_zones?: Array<{ id?: string }> } | undefined;

  const serviceZoneId = fulfillmentSet?.service_zones?.[0]?.id;

  if (!serviceZoneId) {
    throw new Error("No fulfillment set with service zone found.");
  }

  await createShippingOptionsWorkflow(container).run({
    input: [
      {
        name: OPTION_NAME,
        price_type: "flat",
        provider_id: "manual_manual",
        service_zone_id: serviceZoneId,
        shipping_profile_id: shippingProfile.id,
        data: {
          id: "local-pickup",
          name: OPTION_NAME,
          type: "pickup",
        },
        type: {
          label: OPTION_LABEL,
          description: OPTION_DESCRIPTION,
          code: OPTION_CODE,
        },
        prices: [
          { currency_code: "eur", amount: 0 },
          { currency_code: "usd", amount: 0 },
          { region_id: eurRegion.id, amount: 0 },
        ],
        rules: [
          {
            attribute: "enabled_in_store",
            value: "true",
            operator: "eq",
          },
          {
            attribute: "is_return",
            value: "false",
            operator: "eq",
          },
        ],
      },
    ],
  });

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

  const created = (createdOptions || []).find((option: Record<string, unknown>) => {
    const typeCode = String((option.type as { code?: string } | undefined)?.code || "").toLowerCase();
    return typeCode === OPTION_CODE;
  }) as { id?: string; name?: string } | undefined;

  logger.info(`Created shipping option: ${created?.id || "unknown"} (${created?.name || OPTION_NAME}).`);
}
