import {
	BlockchainFunction,
	BlockchainFunctionParams,
	InvalidateTicket,
	TickedIds,
} from './types'

/**
 * Extracts IDs from the format E(someNumber)TC(someNumber)T(someNumber)
 */
export function parseTicketId(ticketId: string): TickedIds {
	const ticketIdRegex = /E(\d+)TC(\d+)T(\d+)/
	const groups = ticketId.match(ticketIdRegex)
	if (groups?.length !== 4) {
		throw new Error(`Invalid ticket ID format: ${ticketId}`)
	}
	const eventId = Number.parseInt(groups[1])
	const ticketConfigId = Number.parseInt(groups[2])
	const sequenceNumber = Number.parseInt(groups[3])

	return {
		eventId,
		ticketConfigId,
		sequenceNumber,
	}
}

/**
 * Construct the payload for the ticket invalidation from the ticket ID found in the QR code
 *
 * @param ticketId string in the format E(someNumber)TC(someNumber)T(someNumber)
 * @param invalidationTime the point in time at which the ticket was scanned
 * @returns args for the blockchain function
 */
export function createInvalidatePayload(
	ticketId: string,
	invalidationTime: Date
): InvalidateTicket {
	const ids = parseTicketId(ticketId)
	// As specified by the blockchain TICKET.INVALIDATE function
	// https://dev.azure.com/BAMTicketingGmbH/MVP/_wiki/wikis/BAM---MVP.wiki/80/Chaincode-API
	return {
		seq_num: ids.sequenceNumber,
		ticket_config: {
			id: ids.ticketConfigId,
			event: {
				id: ids.eventId,
			},
		},
		validation_time: invalidationTime.toISOString(),
	}
}

/**
 * Function which returns the function call for ticket invalidation
 *
 * @param payload acquired through the `createInvalidatePayload` function
 * @returns function call to be sent to the blockchain
 */
export function createInvalidateCall(
	payload: InvalidateTicket
): BlockchainFunctionParams<InvalidateTicket> {
	return {
		fcn: BlockchainFunction.InvalidateTicket,
		args: payload,
	}
}
