import sequelize from '#services/database/sequelize/sequelizeService';
import { QueryTypes } from 'sequelize';

/**
 * Generate unique bill code with format: HD-YYYYMM-XXXX
 * Example: HD-202605-0001, HD-202605-0002, etc.
 *
 * @returns Promise<string> Generated bill code
 */
export async function generateBillCode(): Promise<string> {
	try {
		// Format: HD-YYYYMM
		const today = new Date();
		const year = today.getFullYear();
		const month = String(today.getMonth() + 1).padStart(2, '0');
		const datePrefix = `HD-${year}${month}`;

		// Get the highest sequence number for this month
		const query = `
			SELECT 
				COALESCE(
					MAX(
						CAST(
							SUBSTRING(code, LENGTH(:datePrefix) + 2) AS INTEGER
						)
					),
					0
				) as max_sequence
			FROM bills
			WHERE code LIKE :codePattern
		`;

		const result = (await sequelize.query(query, {
			replacements: {
				datePrefix: datePrefix,
				codePattern: `${datePrefix}-%`,
			},
			type: QueryTypes.SELECT,
		})) as any[];

		const maxSequence = result[0]?.max_sequence || 0;
		const nextSequence = maxSequence + 1;
		const sequenceStr = String(nextSequence).padStart(4, '0');

		return `${datePrefix}-${sequenceStr}`;
	} catch (error) {
		console.error('Error generating bill code:', error);
		throw error;
	}
}

/**
 * Validate bill code format
 * Format: HD-YYYYMM-XXXX
 *
 * @param code Code to validate
 * @returns boolean True if valid format
 */
export function validateBillCode(code: string): boolean {
	const pattern = /^HD-\d{6}-\d{4}$/;
	return pattern.test(code);
}

/**
 * Parse bill code to extract date and sequence
 *
 * @param code Bill code to parse
 * @returns Object with year, month, sequence
 */
export function parseBillCode(code: string) {
	if (!validateBillCode(code)) {
		throw new Error('Invalid bill code format');
	}

	const yearStr = code.substring(3, 7);
	const monthStr = code.substring(7, 9);
	const sequenceStr = code.substring(10, 14);

	return {
		year: parseInt(yearStr, 10),
		month: parseInt(monthStr, 10),
		sequence: parseInt(sequenceStr, 10),
	};
}
