/**
 * ScanForm utility functions for domestic/international grouping and label exclusion notices.
 *
 * The server is authoritative for domestic/international classification —
 * it populates `label.is_domestic` in the origins response. These helpers
 * just group by that flag; they do not re-apply USPS territory rules on
 * the client.
 */

import { getProtocol } from '@wordpress/url';
import { sprintf, _n } from '@wordpress/i18n';
import type { ScanFormLabel } from 'types';

const SAFE_URL_PROTOCOLS = [ 'http:', 'https:' ];

/**
 * Returns true when a URL uses http or https — safe to pass to window.open().
 * Rejects javascript:, data:, and any other protocol that could execute code.
 */
export const isSafePdfUrl = ( url: string ): boolean =>
	SAFE_URL_PROTOCOLS.includes( getProtocol( url ) ?? '' );

/**
 * Per-reason notice messages for labels excluded from SCAN Form eligibility.
 * Add a new entry here when a new exclusion reason is introduced server-side.
 * Unknown reasons fall back to the generic message in getExclusionNotice().
 */
const EXCLUSION_NOTICES: Record< string, ( count: number ) => string > = {
	missing_destination: ( count ) =>
		sprintf(
			/* translators: %d is number of labels excluded due to missing destination country */
			_n(
				'%d label was excluded because its destination country could not be determined and cannot be added to a SCAN Form.',
				'%d labels were excluded because their destination country could not be determined and cannot be added to a SCAN Form.',
				count,
				'woocommerce-shipping'
			),
			count
		),
	envelope_type: ( count ) =>
		sprintf(
			/* translators: %d is number of envelope labels excluded from SCAN Form */
			_n(
				'%d label is an envelope shipment and cannot be included in a SCAN Form.',
				'%d labels are envelope shipments and cannot be included in a SCAN Form.',
				count,
				'woocommerce-shipping'
			),
			count
		),
};

/**
 * Get a localized notice string for a given exclusion reason and label count.
 * Falls back to a generic message for unknown reasons.
 */
export const getExclusionNotice = ( reason: string, count: number ): string =>
	EXCLUSION_NOTICES[ reason ]?.( count ) ??
	sprintf(
		/* translators: %d is number of labels that could not be added */
		_n(
			'%d label could not be added to a SCAN Form.',
			'%d labels could not be added to a SCAN Form.',
			count,
			'woocommerce-shipping'
		),
		count
	);

/**
 * Check whether a label has been classified as a domestic USPS shipment.
 */
export const isDomesticShipment = ( label: ScanFormLabel ): boolean =>
	!! label.is_domestic;

/**
 * Split an array of label IDs into domestic and international batches
 * using the server-provided classification.
 *
 * @param labelIds Array of label IDs to split.
 * @param labels   Array of label objects carrying is_domestic.
 * @return Object with domestic and international label ID arrays.
 */
export const splitLabelsByDestination = (
	labelIds: number[],
	labels: ScanFormLabel[]
): { domestic: number[]; international: number[] } => {
	const labelMap = new Map( labels.map( ( l ) => [ l.label_id, l ] ) );
	const domestic: number[] = [];
	const international: number[] = [];

	for ( const labelId of labelIds ) {
		const label = labelMap.get( labelId );
		if ( ! label ) {
			continue;
		}
		if ( label.is_domestic ) {
			domestic.push( labelId );
		} else {
			international.push( labelId );
		}
	}

	return { domestic, international };
};