import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
import SettingsPage from '../+page.svelte';
import { api } from '$lib/api';
import { addToast } from '$lib/toasts.svelte.js';

vi.mock('$lib/api', () => ({
    api: {
        getConsolidatedSettings: vi.fn(),
        requestApi: vi.fn(),
        putApi: vi.fn(),
        postApi: vi.fn(),
        updateConsolidatedSettings: vi.fn()
    }
}));

vi.mock('$lib/toasts.svelte.js', () => ({
    addToast: vi.fn()
}));

vi.mock('$lib/i18n/index.svelte.js', () => ({
    t: {
        subscribe: (fn: (v: Record<string, unknown>) => void) => {
            fn({
                settings: {
                    title: 'Settings',
                    migration_sync: 'Migration Sync',
                    migration_sync_title: 'Cross-Environment ID Synchronization',
                    migration_sync_description: 'Sync IDs across environments',
                    sync_schedule: 'Sync Schedule',
                    sync_now: 'Sync Now',
                    syncing: 'Syncing...',
                    saving: 'Saving...',
                    environments: 'Environments',
                    logging: 'Logging',
                    llm: 'LLM',
                    storage: 'Storage',
                    save_success: 'Settings saved',
                    save_failed: 'Failed',
                    env_description: 'Configure environments',
                    migration_sync_failed: 'Sync failed',
                },
                common: { refresh: 'Refresh', save: 'Save', cancel: 'Cancel', loading: 'Loading...' },
                tasks: { cron_label: 'Cron Expression', cron_hint: 'Standard cron format' },
                nav: { settings_git: 'Git' },
            });
            return () => { };
        }
    },
    _: vi.fn((key: string) => key)
}));

// Mock child components
vi.mock('../../components/llm/ProviderConfig.svelte', () => ({
    default: class ProviderConfigMock {
        constructor(options: { target: HTMLElement }) {
            options.target.innerHTML = `<div data-testid="provider-config"></div>`;
        }
    }
}));

describe('SettingsPage.integration.test.js', () => {
    const mockSettings = {
        environments: [],
        logging: { level: 'INFO', task_log_level: 'INFO', enable_belief_state: false },
        connections: [],
        llm: {}
    } as const;

    const mockMigrationSettings = {
        cron: "0 2 * * *"
    } as const;

    beforeEach(() => {
        vi.clearAllMocks();
        // Reset URL hash to prevent test-to-test leakage
        window.location.hash = '';
        (api.getConsolidatedSettings as ReturnType<typeof vi.fn>).mockResolvedValue(mockSettings);
        (api.requestApi as ReturnType<typeof vi.fn>).mockImplementation((url: string, _method = 'GET', _body?: unknown) => {
            if (url === '/migration/settings') return Promise.resolve(mockMigrationSettings);
            if (url.includes('/migration/mappings-data')) return Promise.resolve({ items: [], total: 0 });
            return Promise.resolve({});
        });
    });

    it('renders and fetches consolidated settings on mount', async () => {
        render(SettingsPage);
        await waitFor(() => {
            expect(api.getConsolidatedSettings).toHaveBeenCalled();
        });
    });

    it('fetches migration settings when migration tab is selected', async () => {
        render(SettingsPage);
        await waitFor(() => expect(api.getConsolidatedSettings).toHaveBeenCalled());

        // Click migration tab to trigger migration settings load
        const migrationTabBtn = screen.getByText('Migration Sync');
        await fireEvent.click(migrationTabBtn);

        await waitFor(() => {
            expect(api.requestApi).toHaveBeenCalledWith('/migration/settings');
        });
    });

    it('navigates to the migration tab and checks content', async () => {
        render(SettingsPage);
        await waitFor(() => expect(api.getConsolidatedSettings).toHaveBeenCalled());

        // Find the migration tab button by text
        const migrationTabBtn = screen.getByText('Migration Sync');
        await fireEvent.click(migrationTabBtn);

        // Verify migration settings UI is shown
        expect(screen.getByText('Cross-Environment ID Synchronization')).toBeTruthy();
        expect(screen.getByDisplayValue('0 2 * * *')).toBeTruthy();
    });

    it('triggers a sync now action successfully', async () => {
        (api.postApi as ReturnType<typeof vi.fn>).mockResolvedValue({ synced_count: 1, failed_count: 0 });

        render(SettingsPage);
        await waitFor(() => expect(api.getConsolidatedSettings).toHaveBeenCalled());

        const migrationTabBtn = screen.getByText('Migration Sync');
        await fireEvent.click(migrationTabBtn);

        const syncNowBtn = screen.getByText('Sync Now');
        await fireEvent.click(syncNowBtn);

        expect(api.postApi).toHaveBeenCalledWith('/migration/sync-now', {});
        await waitFor(() => {
            expect(addToast).toHaveBeenCalledWith('Synced 1 environment(s)', 'success');
        });
    });
});
