import { LabelPurchaseState } from '../../types';
import type { Label } from 'types';
import { mapKeys, mapValues } from 'lodash';
import { camelCaseKeysRecursive } from 'utils';
import { LABEL_PURCHASE_STATUS } from '../../constants';

/**
 * Helper to find the best label from an array of labels.
 * Prioritizes labels that are PURCHASED or PURCHASE_IN_PROGRESS over PURCHASE_ERROR.
 * This ensures that after a retry purchase, the new label is returned instead of the old error label.
 */
const findBestLabel = ( labels: Label[] ): Label | undefined => {
	// First, try to find a non-refunded label that is PURCHASED or PURCHASE_IN_PROGRESS
	const activeLabel = labels.find(
		( l ) =>
			! l.refund &&
			( l.status === LABEL_PURCHASE_STATUS.PURCHASED ||
				l.status === LABEL_PURCHASE_STATUS.PURCHASE_IN_PROGRESS )
	);
	if ( activeLabel ) {
		return activeLabel;
	}

	// Fallback: return the first non-refunded label (could be PURCHASE_ERROR or other status)
	return labels.find( ( l ) => ! l.refund );
};

export const getLabelByLabelId = (
	state: LabelPurchaseState,
	labelId: string | number
): Label | undefined => {
	const labels = state.labels;
	if ( ! labels ) {
		return undefined;
	}

	return Object.values( labels )
		.flat()
		.find( ( l ) => l.labelId === labelId );
};

export const getPurchasedLabel = (
	state: LabelPurchaseState,
	shipmentId: string | number
): Label | undefined => {
	const labels = state.labels?.[ shipmentId ] ?? [];
	return findBestLabel( labels );
};
export const getPurchasedLabels = ( state: LabelPurchaseState ) =>
	mapValues( state.labels, ( labels ) =>
		labels ? findBestLabel( labels ) : undefined
	);

export const getSelectedRates = ( state: LabelPurchaseState ) =>
	state.selectedRates
		? camelCaseKeysRecursive(
				mapKeys(
					state.selectedRates,
					( value, key ) => key.replace( 'shipment_', '' ) ?? key
				)
		  )
		: undefined;

export const getSelectedHazmatConfig = ( state: LabelPurchaseState ) =>
	state.selectedHazmatConfig
		? mapKeys(
				state.selectedHazmatConfig,
				( value, key ) => key.replace( 'shipment_', '' ) ?? key
		  )
		: undefined;

export const getPurchaseAPIError = (
	state: LabelPurchaseState,
	shipmentId: string | number
) => state.purchaseAPIErrors?.[ shipmentId ];

export const getRefundedLabel = (
	state: LabelPurchaseState,
	shipmentId: string | number
): Label | undefined => {
	const labels = state.labels?.[ shipmentId ] ?? [];
	return labels.find( ( l ) => l.refund );
};

export const getLabelOrigins = (
	state: LabelPurchaseState,
	shipmentId: string
) => state.selectedOrigins?.[ shipmentId ];

export const getLabelDestinations = (
	state: LabelPurchaseState,
	shipmentId: string
) => state.selectedDestinations?.[ shipmentId ];