import { HttpTypes } from "@medusajs/types";
import { env } from "@/lib/env";

const MONDIAL_RELAY_METADATA_KEY = "mondial_relay_point";
const SHIPPING_METHOD_HINTS = ["mondial", "relay", "point relais", "locker", "inpost"];

export type MondialRelayPoint = {
  id: string;
  name: string;
  address1: string;
  address2?: string;
  postalCode: string;
  city: string;
  countryCode: string;
};

function asRecord(value: unknown): Record<string, unknown> | null {
  if (!value || typeof value !== "object") {
    return null;
  }

  return value as Record<string, unknown>;
}

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

function parseConfiguredOptionIds() {
  return new Set(
    env.mondialRelayShippingOptionIds
      .split(",")
      .map((value) => value.trim())
      .filter(Boolean),
  );
}

function methodMatchesMondialRelay(method: unknown) {
  const configuredOptionIds = parseConfiguredOptionIds();
  const methodRecord = asRecord(method);
  if (!methodRecord) {
    return false;
  }

  const optionId = asString(methodRecord.shipping_option_id);
  if (optionId && configuredOptionIds.has(optionId)) {
    return true;
  }

  const shippingOptionRecord = asRecord(methodRecord.shipping_option);
  const shippingOptionData = asRecord(shippingOptionRecord?.data);
  const labels = [
    asString(methodRecord.name),
    asString(shippingOptionRecord?.name),
    asString(shippingOptionRecord?.service_zone_name),
    asString(shippingOptionData?.provider_id),
  ]
    .map((value) => value.toLowerCase())
    .filter(Boolean);

  return labels.some((value) => SHIPPING_METHOD_HINTS.some((hint) => value.includes(hint)));
}

export function isMondialRelayShippingMethod(cart: HttpTypes.StoreCart) {
  const shippingMethods = (cart as { shipping_methods?: unknown[] }).shipping_methods;
  if (!Array.isArray(shippingMethods)) {
    return false;
  }

  return shippingMethods.some(methodMatchesMondialRelay);
}

function normalizePoint(input: Record<string, unknown>): MondialRelayPoint | null {
  const id = asString(input.id);
  const name = asString(input.name);
  const address1 = asString(input.address1);
  const postalCode = asString(input.postalCode);
  const city = asString(input.city);
  const countryCode = asString(input.countryCode || "FR").toUpperCase();

  if (!id || !name || !address1 || !postalCode || !city || !countryCode) {
    return null;
  }

  return {
    id,
    name,
    address1,
    address2: asString(input.address2) || undefined,
    postalCode,
    city,
    countryCode,
  };
}

export function getMondialRelayPointFromMetadata(metadata: unknown): MondialRelayPoint | null {
  const metadataRecord = asRecord(metadata);
  const pointRecord = asRecord(metadataRecord?.[MONDIAL_RELAY_METADATA_KEY]);

  if (!pointRecord) {
    return null;
  }

  return normalizePoint(pointRecord);
}

export function getMondialRelayPointFromCart(cart: HttpTypes.StoreCart) {
  const metadata = (cart as { metadata?: Record<string, unknown> | null }).metadata;
  return getMondialRelayPointFromMetadata(metadata);
}

export function upsertMondialRelayPointMetadata(
  metadata: Record<string, unknown> | null | undefined,
  point: MondialRelayPoint | null,
) {
  const nextMetadata = { ...(metadata || {}) };

  if (point) {
    nextMetadata[MONDIAL_RELAY_METADATA_KEY] = point;
  } else {
    nextMetadata[MONDIAL_RELAY_METADATA_KEY] = null;
  }

  return nextMetadata;
}

export function sanitizeMondialRelayPoint(input: Record<string, unknown>) {
  return normalizePoint(input);
}
