import { ORDER_STATUS } from "@/config/app.config";

export type OrderStatusValue =
  (typeof ORDER_STATUS)[keyof typeof ORDER_STATUS];

export type OrderStatusActionId =
  | "mark_ready_to_fulfill"
  | "mark_processing"
  | "mark_shipped"
  | "mark_delivered"
  | "cancel_order";

/**
 * A permitted transition out of the current status.
 *
 * Deliberately carries no display copy: this module is imported by the API
 * routes that validate transitions, so any label here would be an English
 * string rendered into a localized UI. Menus translate by id instead
 * (`admin.orderDetails.statusAction.<id>`).
 */
export interface OrderStatusActionDefinition {
  id: OrderStatusActionId;
  to: OrderStatusValue;
  destructive?: boolean;
}

export const ORDER_STATUS_ACTIONS: Record<
  OrderStatusActionId,
  OrderStatusActionDefinition
> = {
  // Releases a preorder into normal fulfillment.
  mark_ready_to_fulfill: {
    id: "mark_ready_to_fulfill",
    to: ORDER_STATUS.PROCESSING,
  },
  mark_processing: {
    id: "mark_processing",
    to: ORDER_STATUS.PROCESSING,
  },
  mark_shipped: {
    id: "mark_shipped",
    to: ORDER_STATUS.SHIPPED,
  },
  mark_delivered: {
    id: "mark_delivered",
    to: ORDER_STATUS.DELIVERED,
  },
  // Cancels the order and restores inventory when possible.
  cancel_order: {
    id: "cancel_order",
    to: ORDER_STATUS.CANCELLED,
    destructive: true,
  },
};

export const ORDER_STATUS_WORKFLOW: Record<
  OrderStatusValue,
  OrderStatusActionId[]
> = {
  [ORDER_STATUS.PREORDERED]: ["mark_ready_to_fulfill", "cancel_order"],
  [ORDER_STATUS.PENDING]: ["mark_processing", "cancel_order"],
  [ORDER_STATUS.PROCESSING]: ["mark_shipped", "cancel_order"],
  [ORDER_STATUS.SHIPPED]: ["mark_delivered"],
  [ORDER_STATUS.DELIVERED]: [],
  [ORDER_STATUS.CANCELLED]: [],
};

export function getOrderStatusActions(
  status: string,
): OrderStatusActionDefinition[] {
  const actionIds =
    ORDER_STATUS_WORKFLOW[status as OrderStatusValue] ??
    ORDER_STATUS_WORKFLOW[ORDER_STATUS.PENDING];
  return actionIds.map((id) => ORDER_STATUS_ACTIONS[id]);
}

export function getOrderStatusActionByTarget(
  currentStatus: string,
  nextStatus: string,
): OrderStatusActionDefinition | null {
  return (
    getOrderStatusActions(currentStatus).find(
      (action) => action.to === nextStatus,
    ) ?? null
  );
}

export function canTransitionOrderStatus(
  currentStatus: string,
  nextStatus: string,
): boolean {
  return Boolean(getOrderStatusActionByTarget(currentStatus, nextStatus));
}

export function getOrderStatusTimestampUpdates(
  nextStatus: string,
  changedAt = new Date(),
): Record<string, Date> {
  if (nextStatus === ORDER_STATUS.PROCESSING) {
    return { processingAt: changedAt };
  }
  if (nextStatus === ORDER_STATUS.SHIPPED) {
    return { shippedAt: changedAt };
  }
  if (nextStatus === ORDER_STATUS.DELIVERED) {
    return { deliveredAt: changedAt };
  }
  if (nextStatus === ORDER_STATUS.CANCELLED) {
    return { cancelledAt: changedAt };
  }
  return {};
}

export function shouldRestoreInventoryForStatusTransition(
  currentStatus: string,
  nextStatus: string,
) {
  return (
    nextStatus === ORDER_STATUS.CANCELLED &&
    currentStatus !== ORDER_STATUS.CANCELLED
  );
}
