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

type TrackingStep = {
  id: string;
  label: string;
  date: string | null;
  state: "done" | "current" | "todo";
};

type TrackingInfo = {
  number: string | null;
  url: string | null;
  carrier: string | null;
};

function toDateString(value: unknown) {
  if (!value) return null;
  const date = new Date(String(value));
  if (Number.isNaN(date.getTime())) return null;
  return new Intl.DateTimeFormat("fr-FR", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date);
}

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

function getString(record: Record<string, unknown> | null, keys: string[]) {
  if (!record) return null;
  for (const key of keys) {
    const value = record[key];
    if (typeof value === "string" && value.trim()) {
      return value.trim();
    }
  }
  return null;
}

export function getOrderTrackingInfo(order: HttpTypes.StoreOrder): TrackingInfo {
  const fulfillments = order.fulfillments || [];

  for (const fulfillment of fulfillments) {
    const dataRecord = getRecord(fulfillment.data);
    const metadataRecord = getRecord(fulfillment.metadata);

    const number =
      getString(dataRecord, ["tracking_number", "trackingNumber", "number", "parcel_number"]) ||
      getString(metadataRecord, ["tracking_number", "trackingNumber", "number", "parcel_number"]);
    const url =
      getString(dataRecord, ["tracking_url", "trackingUrl", "url"]) ||
      getString(metadataRecord, ["tracking_url", "trackingUrl", "url"]);
    const carrier =
      getString(dataRecord, ["carrier", "provider", "provider_id"]) ||
      getString(metadataRecord, ["carrier", "provider", "provider_id"]) ||
      fulfillment.provider_id ||
      null;

    if (number || url) {
      return { number: number || null, url: url || null, carrier };
    }
  }

  return { number: null, url: null, carrier: null };
}

function hasFulfillmentDate(order: HttpTypes.StoreOrder, key: "packed_at" | "shipped_at" | "delivered_at") {
  return Boolean((order.fulfillments || []).some((fulfillment) => Boolean(fulfillment[key])));
}

function firstFulfillmentDate(order: HttpTypes.StoreOrder, key: "packed_at" | "shipped_at" | "delivered_at") {
  const fulfillment = (order.fulfillments || []).find((item) => Boolean(item[key]));
  return toDateString(fulfillment?.[key] || null);
}

export function getOrderStatusLabel(status: string | null | undefined) {
  switch (status) {
    case "not_fulfilled":
      return "Commande confirmée";
    case "partially_fulfilled":
      return "Préparation en cours";
    case "fulfilled":
      return "Prête à expédier";
    case "partially_shipped":
      return "Partiellement expédiée";
    case "shipped":
      return "Expédiée";
    case "partially_delivered":
      return "Partiellement livrée";
    case "delivered":
      return "Livrée";
    case "canceled":
      return "Annulée";
    default:
      return status || "-";
  }
}

export function getOrderTrackingSteps(order: HttpTypes.StoreOrder): TrackingStep[] {
  const status = order.fulfillment_status || "not_fulfilled";
  const packedDone = hasFulfillmentDate(order, "packed_at") || ["partially_fulfilled", "fulfilled", "partially_shipped", "shipped", "partially_delivered", "delivered"].includes(status);
  const shippedDone = hasFulfillmentDate(order, "shipped_at") || ["partially_shipped", "shipped", "partially_delivered", "delivered"].includes(status);
  const deliveredDone = hasFulfillmentDate(order, "delivered_at") || ["partially_delivered", "delivered"].includes(status);

  const steps: TrackingStep[] = [
    {
      id: "created",
      label: "Commande confirmée",
      date: toDateString(order.created_at),
      state: "done",
    },
    {
      id: "packed",
      label: "Préparation",
      date: firstFulfillmentDate(order, "packed_at"),
      state: packedDone ? "done" : "todo",
    },
    {
      id: "shipped",
      label: "Expedition",
      date: firstFulfillmentDate(order, "shipped_at"),
      state: shippedDone ? "done" : "todo",
    },
    {
      id: "delivered",
      label: "Livraison",
      date: firstFulfillmentDate(order, "delivered_at"),
      state: deliveredDone ? "done" : "todo",
    },
  ];

  if (status === "canceled") {
    return steps.map((step) =>
      step.id === "created" ? step : { ...step, state: "todo" as const },
    );
  }

  const firstTodoIndex = steps.findIndex((step) => step.state === "todo");
  if (firstTodoIndex > -1) {
    steps[firstTodoIndex] = { ...steps[firstTodoIndex], state: "current" };
  }

  return steps;
}

