const args = Object.fromEntries(
    process.argv.slice(2)
        .map(arg => arg.replace(/^--/, '').split('='))
        .map(([k, v]) => [k, v ?? 'true'])
);
const BASE_URL = args.baseUrl || process.env.BASE_URL || 'http://localhost:5000/api';
const PASSWORD = 'Admin@123';
const STEP_DELAY_MS = Number(args.delayMs || 500);

const EMAILS = {
    DD_ADMIN: 'lince@royalenfield.com',
    DEALER: args.dealerEmail,
    ASM: args.asmEmail || 'abhishek@royalenfield.com',
    RBM_L1: 'manish@royalenfield.com',
    ZBH: 'manav@royalenfield.com',
    DD_LEAD: 'jaya@royalenfield.com',
    DD_HEAD: 'ganesh@royalenfield.com',
    NBH: 'yashwin@royalenfield.com',
    LEGAL: 'legal@royalenfield.com',
    SALES: 'sales@royalenfield.com',
    SERVICE: 'service@royalenfield.com',
    SPARES: 'spares@royalenfield.com',
    FINANCE: 'finance@royalenfield.com',
    ACCOUNTS: 'accounts@royalenfield.com',
    WARRANTY: 'warranty@royalenfield.com',
    MARKETING: 'marketing@royalenfield.com',
    HR: 'hr@royalenfield.com',
    IT: 'it@royalenfield.com',
    LOGISTICS: 'logistics@royalenfield.com',
    QUALITY: 'quality@royalenfield.com',
    APPAREL: 'apparel@royalenfield.com',
    DMS: 'dms@royalenfield.com'
};

async function resolveDealerAsmEmail(adminToken, dealerEmail) {
    try {
        const res = await apiRequest('/master/dealer-asm-mappings', 'GET', null, adminToken);
        const rows = res?.data?.dealers || [];
        const match = rows.find((d) => String(d?.dealerUser?.email || '').toLowerCase() === String(dealerEmail || '').toLowerCase());
        return match?.assignedAsm?.email || null;
    } catch (e) {
        return null;
    }
}

async function apiRequest(endpoint, method = 'GET', body = null, token = null) {
    const headers = { 'Content-Type': 'application/json' };
    if (token) headers['Authorization'] = `Bearer ${token}`;

    const config = { method, headers };
    if (body) config.body = JSON.stringify(body);

    const response = await fetch(`${BASE_URL}${endpoint}`, config);
    const data = await response.json();

    if (!response.ok) {
        throw new Error(`API Error ${method} ${endpoint}: ${JSON.stringify(data)}`);
    }
    return data;
}

async function login(email) {
    if (!login.cache) login.cache = {};
    if (login.cache[email]) return login.cache[email];
    const data = await apiRequest('/auth/login', 'POST', { email, password: PASSWORD });
    login.cache[email] = data.token;
    return login.cache[email];
}

const delay = (ms = STEP_DELAY_MS) => new Promise(res => setTimeout(res, ms));

async function run() {
    try {
        console.log('--- STARTING CONSTITUTIONAL CHANGE E2E FLOW ---');
        if (!EMAILS.DEALER) {
            throw new Error('Missing --dealerEmail. This script requires an existing dealer user email.');
        }

        console.log(`[STEP 0] Logging in as Dealer: ${EMAILS.DEALER}...`);
        const dealerToken = await login(EMAILS.DEALER);
        
        let requestId = args.requestId;
        if (!requestId) {
            console.log('[STEP 1] Dealer Submitting Constitutional Change...');
            const createRes = await apiRequest('/self-service/constitutional', 'POST', {
                changeType: args.changeType || 'LLP Conversion',
                reason: args.reason || 'Converting to LLP for better operational governance.',
                currentConstitution: 'Proprietorship',
                newPartnersDetails: 'John Doe, Jane Smith',
                shareholdingPattern: '60/40'
            }, dealerToken);
            requestId = createRes.requestId; 
            console.log(`[STEP 1] Request Created. RequestID: ${requestId}`);
        } else {
            console.log(`[STEP 1] Resuming request: ${requestId}`);
        }

        // Sequence of users taking actions to advance stages
        const approvalSequence = [
            { name: 'ASM', email: EMAILS.ASM },
            { name: 'ZM/RBM', email: EMAILS.RBM_L1 },
            { name: 'ZBH', email: EMAILS.ZBH },
            { name: 'DD Lead', email: EMAILS.DD_LEAD },
            { name: 'DD Head', email: EMAILS.DD_HEAD },
            { name: 'NBH', email: EMAILS.NBH },
            { name: 'Legal Review', email: EMAILS.LEGAL },
            { name: 'Legal Finalize', email: EMAILS.LEGAL }
        ];

        const adminToken = await login(EMAILS.DD_ADMIN);
        const asmFromMapping = args.asmEmail || await resolveDealerAsmEmail(adminToken, EMAILS.DEALER);
        if (asmFromMapping) {
            EMAILS.ASM = asmFromMapping;
            console.log(`[INFO] Using ASM approver: ${EMAILS.ASM}`);
        } else {
            console.log(`[WARN] Dealer-level ASM not found. Falling back to default ASM email: ${EMAILS.ASM}`);
        }
        const current = await apiRequest(`/self-service/constitutional/${requestId}`, 'GET', null, adminToken);
        const currentStage = current?.request?.currentStage;
        const stageOrder = ['Submitted', 'ASM Review', 'ZM/RBM Review', 'ZBH Review', 'DD Lead Review', 'DD Head Review', 'NBH Approval', 'Legal Review', 'Completed'];
        const startIndex = Math.max(0, stageOrder.indexOf(currentStage));

        let currentStep = 2 + startIndex;
        for (let i = startIndex; i < approvalSequence.length; i++) {
            const actor = approvalSequence[i];
            console.log(`[STEP ${currentStep}] ${actor.name} (${actor.email}) processing approval...`);
            const token = await login(actor.email);
            const res = await apiRequest(`/self-service/constitutional/${requestId}/action`, 'POST', {
                action: 'Approve',
                comments: `${actor.name} verified the request.`
            }, token);
            console.log(`[STEP ${currentStep}] ${actor.name} Result: ${res.message}`);
            currentStep++;
            await delay(500);
        }

        console.log('[FINAL STEP] Verifying Completion Status...');
        const finalDetails = await apiRequest(`/self-service/constitutional/${requestId}`, 'GET', null, adminToken);
        
        if (finalDetails.request.status === 'Completed' || finalDetails.request.currentStage === 'Completed') {
            console.log(`[STEP ${currentStep}] SUCCESS: Request reached COMPLETED state.`);
        } else {
            console.error(`Verification Failed: Final stage is ${finalDetails.request.currentStage}. Status: ${finalDetails.request.status}`);
            throw new Error('Constitutional change completion check failed.');
        }

        console.log('\n--- VERIFICATION RESULTS ---');
        console.log('Outcome: CONSTITUTIONAL CHANGE FLOW COMPLETED SUCCESSFULLY');
        process.exit(0);

    } catch (error) {
        console.error('Workflow failed:', error.message);
        process.exit(1);
    }
}

run();
