import db from '../../database/models/index.js';
import { Op } from 'sequelize';

/**
 * Centralized utility for ID generation and nomenclature across all modules.
 * This ensures consistency and makes it easy to alter naming patterns globally.
 */
export class NomenclatureService {
    /**
     * Generic helper for generating sequential IDs with Month/Year prefix
     */
    private static async generateSequentialId(modelName: string, fieldName: string, modulePrefix: string) {
        const now = new Date();
        const year = now.getFullYear();
        const monthNames = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
        const month = monthNames[now.getMonth()];
        const prefix = `${modulePrefix}-${year}-${month}-`;

        try {
            const Model = (db as any)[modelName];
            if (!Model) {
                throw new Error(`Model ${modelName} not found in database indexed models.`);
            }

            // Find the last ID with this prefix to increment
            const lastRecord = await Model.findOne({
                where: {
                    [fieldName]: {
                        [Op.like]: `${prefix}%`
                    }
                },
                order: [['createdAt', 'DESC']],
                attributes: [fieldName]
            });

            let nextNumber = 1;
            if (lastRecord && lastRecord[fieldName]) {
                const parts = lastRecord[fieldName].split('-');
                const lastNumStr = parts[parts.length - 1];
                const lastNum = parseInt(lastNumStr, 10);
                if (!isNaN(lastNum)) {
                    nextNumber = lastNum + 1;
                }
            }

            return `${prefix}${nextNumber.toString().padStart(5, '0')}`;
        } catch (error) {
            console.error(`Error generating sequential ID for ${modulePrefix}:`, error);
            // Fallback to random if DB fetch fails
            return `${prefix}${Math.floor(10000 + Math.random() * 90000)}`;
        }
    }

    /**
     * Generates an Onboarding Application ID (e.g., DD-2026-FEB-00001)
     */
    static async generateApplicationId() {
        return this.generateSequentialId('Application', 'applicationId', 'DD');
    }

    /**
     * Generates a Resignation ID (e.g., RES-2026-FEB-00001)
     */
    static async generateResignationId() {
        return this.generateSequentialId('Resignation', 'resignationId', 'RES');
    }

    /**
     * Generates a Termination Request ID (e.g., TER-2026-FEB-00001)
     */
    static async generateTerminationId() {
        return this.generateSequentialId('TerminationRequest', 'requestId', 'TER');
    }

    /**
     * Generates a Constitutional Change ID (e.g., CC-2026-FEB-00001)
     */
    static async generateConstitutionalChangeId() {
        return this.generateSequentialId('ConstitutionalChange', 'requestId', 'CC');
    }

    /**
     * Generates a Relocation Request ID (e.g., REL-2026-FEB-00001)
     */
    static async generateRelocationId() {
        return this.generateSequentialId('RelocationRequest', 'requestId', 'REL');
    }

    /**
     * Generates a Settlement/FnF ID (e.g., FNF-2026-FEB-00001)
     */
    static async generateFnFId() {
        return this.generateSequentialId('FnF', 'settlementId', 'FNF');
    }
}
