import { test, expect } from './fixtures';
import { randomUUID } from 'crypto';

// Helper for setup
async function loginAndSetup(page: any, createUniqueUser: any) {
    const user = await createUniqueUser();
    await page.goto('/');
    await page.getByLabel('Email').fill(user.email);
    await page.getByLabel('Password').fill(user.password);
    await page.getByRole('button', { name: 'Login' }).click();

    try {
        const heading = page.getByRole('heading', { name: /Change Password/i });
        const dashboard = page.getByText('Free Workout');
        await expect(heading.or(dashboard)).toBeVisible({ timeout: 5000 });
        if (await heading.isVisible()) {
            await page.getByLabel('New Password').fill('StrongNewPass123!');
            await page.getByRole('button', { name: /Save|Change/i }).click();
            await expect(dashboard).toBeVisible();
        }
    } catch (e) {
        // Login might already be done
    }
    return user;
}

test.describe('IV. Data & Progress', () => {

    test('4.1. A. Session History - View Past Sessions', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        // Subtask 2.1: Complete a workout session
        const exNameSession = 'Hist View Session ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', {
            data: { name: exNameSession, type: 'STRENGTH' },
            headers: { 'Authorization': `Bearer ${user.token}` }
        });

        await page.getByRole('button', { name: /Free Workout|Start Empty/i }).click();

        await page.getByRole('textbox', { name: /Select Exercise/i }).click();
        await page.getByText(exNameSession).click();

        await page.getByLabel('Weight (kg)').first().fill('50');
        await page.getByLabel('Reps').first().fill('10');
        await page.getByRole('button', { name: /Log Set/i }).click();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Subtask 2.2: Log a sporadic set
        const exNameSporadic = 'Hist View Sporadic ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', {
            data: { name: exNameSporadic, type: 'STRENGTH' },
            headers: { 'Authorization': `Bearer ${user.token}` }
        });

        await page.getByRole('button', { name: 'Quick Log' }).click();
        await page.getByRole('textbox', { name: /Select Exercise/i }).click();
        await page.getByText(exNameSporadic).click();

        await page.getByLabel(/Reps/i).first().fill('12');
        await page.getByRole('button', { name: /Log Set/i }).click();

        await page.getByRole('button', { name: 'Quit' }).click();

        // 3. Navigate to History
        await page.getByRole('button', { name: 'History' }).click();

        // Verification
        await expect(page.getByRole('heading', { name: 'History' })).toBeVisible();

        // Check for Quick Log entry details
        await expect(page.getByText(/50\s*kg\s*x\s*12\s*reps/).or(page.getByText(/x 12 reps/))).toBeVisible();

        // Check for Workout Session entry (shows summary)
        await expect(page.getByText('No plan').first()).toBeVisible();
        await expect(page.getByText('Sets:').first()).toBeVisible();

        // Check for Quick Log heading
        await expect(page.getByRole('heading', { name: 'Quick Log' })).toBeVisible();
    });

    test('4.2. A. Session History - View Detailed Session', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Detail View ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', {
            data: { name: exName, type: 'STRENGTH' },
            headers: { 'Authorization': `Bearer ${user.token}` }
        });

        // Complete session
        await page.getByRole('button', { name: /Free Workout|Start Empty/i }).click();
        await page.getByRole('textbox', { name: /Select Exercise/i }).click();
        await page.getByRole('button', { name: exName }).click();

        await page.getByLabel('Weight (kg)').first().fill('50');
        await page.getByLabel('Reps').first().fill('10');
        await page.getByRole('button', { name: /Log Set/i }).click();

        await expect(page.getByText('50 kg x 10 reps')).toBeVisible();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Navigate to History
        await page.getByRole('button', { name: 'History' }).click();

        // Click on a workout session entry
        await page.getByText('No plan').first().click();

        // Verification
        await expect(page.getByRole('heading', { name: /Edit|Session Details/ })).toBeVisible();

        // Check details
        await expect(page.getByText('Start')).toBeVisible();
        await expect(page.getByText('End')).toBeVisible();
        await expect(page.getByText('Weight (kg)').first()).toBeVisible();

        // Verify set details
        await expect(page.getByRole('heading', { name: /Sets/ })).toBeVisible();
    });

    test('4.3. A. Session History - Edit Past Session Details', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Edit Sess ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();

        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        await page.getByRole('button', { name: 'History' }).click();

        // Open details
        await page.getByText('No plan').first().click();

        // Modify Body Weight (first spinbutton usually)
        await page.getByRole('spinbutton').first().fill('75.5');

        // Save
        await page.getByRole('button', { name: 'Save' }).click();

        // Verify
        await expect(page.getByText('75.5kg')).toBeVisible();
    });

    test('4.4. A. Session History - Edit Individual Set in Past Session', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Edit Set ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();

        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();

        await expect(page.getByText('50 kg x 10 reps')).toBeVisible();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        await page.getByRole('button', { name: 'History' }).click();

        // Open details
        await page.getByText('No plan').first().click();

        // Modify weight from 50 to 55
        // Be specific with locator if possible, or use first matching input
        await page.locator('input[value="50"]').fill('55');

        // Save
        await page.getByRole('button', { name: 'Save' }).click();

        // Verify
        await page.getByText('No plan').first().click();
        await expect(page.locator('input[value="55"]')).toBeVisible();
    });

    test('4.5. A. Session History - Delete Past Session', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Del Sess ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();

        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();

        await expect(page.getByText('50 kg x 10 reps')).toBeVisible();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        await page.getByRole('button', { name: 'History' }).click();
        await expect(page.getByText('No plan').first()).toBeVisible();

        // Delete (2nd button usually)
        await page.getByRole('main').getByRole('button').nth(1).click();

        // Confirm
        await expect(page.getByRole('heading', { name: 'Delete workout?' })).toBeVisible();
        await page.getByRole('button', { name: 'Delete' }).click();

        // Verify empty
        await expect(page.getByText('History is empty')).toBeVisible();
    });

    test('4.6. A. Session History - Edit Sporadic Set', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Spor Edit ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        await page.getByRole('button', { name: 'Quick Log' }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();

        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('12');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Quit' }).click();

        await page.getByRole('button', { name: 'History' }).click();
        await expect(page.getByRole('heading', { name: 'Quick Log' })).toBeVisible();

        // Edit (1st button for sporadic row)
        await page.getByRole('main').getByRole('button').nth(0).click();

        await expect(page.getByRole('heading', { name: 'Edit' })).toBeVisible();
        await page.locator('input[value="12"]').fill('15');
        await page.getByRole('button', { name: 'Save' }).click();

        await expect(page.getByText(/50\s*kg\s*x\s*15\s*reps/)).toBeVisible();
    });

    test('4.7. A. Session History - Delete Sporadic Set', async ({ page, createUniqueUser, request }) => {
        const user = await loginAndSetup(page, createUniqueUser);

        const exName = 'Spor Del ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        await page.getByRole('button', { name: 'Quick Log' }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('12');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Quit' }).click();

        await page.getByRole('button', { name: 'History' }).click();

        // Delete (2nd button for sporadic row, or last button in main if only one row)
        // With only one row, buttons are Edit, Delete. Delete is 2nd.
        await page.getByRole('main').getByRole('button').last().click();

        await expect(page.getByRole('dialog')).toBeVisible();
        await page.getByRole('button', { name: 'Delete' }).click();

        await expect(page.getByText('50 kg x 12 reps')).not.toBeVisible();
    });

    test('4.8. B. Performance Statistics - View Volume Chart', async ({ page, createUniqueUser, request }) => {
        test.setTimeout(120000);
        const user = await loginAndSetup(page, createUniqueUser);
        const exName = 'Vol Chart ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        // Session 1
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();

        await expect(page.getByText('50 kg x 10 reps')).toBeVisible();

        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Session 2
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('60');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        await page.getByRole('button', { name: 'Stats' }).click();
        await expect(page.getByText('Work Volume')).toBeVisible();
    });

    test('4.9. B. Performance Statistics - View Set Count Chart', async ({ page, createUniqueUser, request }) => {
        test.setTimeout(120000);
        const user = await loginAndSetup(page, createUniqueUser);
        const exName = 'Set Chart ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        // Session 1
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Session 2
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('60');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        await page.getByRole('button', { name: 'Stats' }).click();
        await expect(page.getByText('Number of Sets')).toBeVisible();
    });

    test('4.10. B. Performance Statistics - View Body Weight Chart', async ({ page, createUniqueUser, request }) => {
        test.setTimeout(120000);
        const user = await loginAndSetup(page, createUniqueUser);
        const exName = 'BW Chart ' + randomUUID().slice(0, 4);
        await request.post('/api/exercises', { data: { name: exName, type: 'STRENGTH' }, headers: { 'Authorization': `Bearer ${user.token}` } });

        // Complete 2 sessions (to unlock stats page - assuming constraint)
        // Session 1
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('50');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Session 2
        await page.getByRole('button', { name: /Free Workout/i }).click();
        await page.getByRole('textbox', { name: /Select/i }).click();
        await page.getByRole('button', { name: exName }).click();
        await page.getByLabel(/Weight/i).first().fill('60');
        await page.getByLabel(/Reps/i).first().fill('10');
        await page.getByRole('button', { name: /Log/i }).click();
        await page.getByRole('button', { name: 'Finish' }).click();
        await page.getByRole('button', { name: 'Confirm' }).click();

        // Log body weight history via API
        const yesterday = new Date();
        yesterday.setDate(yesterday.getDate() - 1);
        const dateStr = yesterday.toISOString().split('T')[0];

        await page.evaluate(async ({ token, dateStr }) => {
            await fetch('/api/weight', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Authorization': `Bearer ${token}`
                },
                body: JSON.stringify({ weight: 70, dateStr })
            });
        }, { token: user.token, dateStr });

        // Log today's weight via UI
        await page.getByRole('button', { name: 'Profile' }).click();
        await page.getByRole('button', { name: 'Weight Tracker' }).click();
        await page.getByPlaceholder('Enter weight...').fill('72');
        await page.getByRole('button', { name: 'Log', exact: true }).click();
        await expect(page.getByText('Weight logged successfully')).toBeVisible();

        await page.getByRole('button', { name: 'Stats' }).click();
        await expect(page.getByText('Body Weight History')).toBeVisible();
    });

});
