// [DEF:frontend.src.routes.settings.git.__tests__.git_settings_page_ux_test:Module]
// @RELATION: VERIFIES -> ../+page.svelte
// @PURPOSE: Test UX states and transitions for the Git Settings page

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

vi.mock('../../../../services/gitService', () => ({
    gitService: {
        getConfigs: vi.fn(),
        createConfig: vi.fn(),
        updateConfig: vi.fn(),
        deleteConfig: vi.fn(),
        testConnection: vi.fn(),
        listGiteaRepositories: vi.fn(),
        createGiteaRepository: vi.fn(),
        deleteGiteaRepository: vi.fn()
    }
}));

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

vi.mock('$lib/i18n', () => ({
    t: {
        subscribe: (fn) => {
            fn({
                settings: {
                    configured_servers: 'Configured Servers',
                    add_git_server: 'Add Git Server',
                    edit_git_server: 'Edit Git Server',
                    display_name: 'Display Name',
                    server_url: 'Server URL',
                    personal_access_token: 'Personal Access Token',
                    default_repository_optional: 'Default Repository (Optional)',
                    default_branch: 'Default Branch',
                    save_configuration: 'Save Configuration',
                    update_configuration: 'Update Configuration',
                    connection_success: 'Connection successful',
                    connection_failed_short: 'Connection failed',
                    git_config_saved: 'Git configuration saved',
                    git_config_updated: 'Git configuration updated',
                    git_delete_confirm: 'Are you sure?',
                    git_config_deleted: 'Git configuration deleted'
                },
                llm: { type: 'Type', test: 'Test' },
                nav: { settings_git: 'Git Settings' },
                git: { no_servers_configured: 'No servers configured' },
                common: { edit: 'Edit', delete: 'Delete', cancel: 'Cancel' }
            });
            return () => { };
        }
    },
    _: vi.fn((key) => key)
}));

// Mock window.scrollTo
Object.defineProperty(window, 'scrollTo', { value: vi.fn(), writable: true });

describe('GitSettingsPage UX Contracts', () => {
    const mockConfigs = [
        {
            id: 'conf-1',
            name: 'Dev GitLab',
            provider: 'GITLAB',
            url: 'https://gitlab.com',
            pat: '********',
            status: 'CONNECTED'
        }
    ];

    beforeEach(() => {
        vi.clearAllMocks();
        // Default confirm to always accept for tests
        global.confirm = vi.fn(() => true);
    });

    // @UX_STATE: Initial Load
    it('should display configured servers on mount', async () => {
        gitService.getConfigs.mockResolvedValue(mockConfigs);
        render(GitSettingsPage);

        await waitFor(() => {
            expect(screen.getByText('Dev GitLab')).toBeTruthy();
            expect(screen.getByText('GITLAB')).toBeTruthy();
            expect(screen.getByText('https://gitlab.com')).toBeTruthy();
        });
    });

    it('should show empty state when no servers configured', async () => {
        gitService.getConfigs.mockResolvedValue([]);
        render(GitSettingsPage);

        await waitFor(() => {
            expect(screen.getByText('No servers configured')).toBeTruthy();
        });
    });

    // @UX_FEEDBACK: Connection testing feedback
    it('should test connection successfully and show success toast', async () => {
        gitService.getConfigs.mockResolvedValue([]);
        gitService.testConnection.mockResolvedValue({ status: 'success' });

        render(GitSettingsPage);
        await waitFor(() => expect(screen.getByText('Add Git Server')).toBeTruthy());

        // Fill form
        await fireEvent.input(screen.getByLabelText('Display Name'), { target: { value: 'New Gitea' } });
        await fireEvent.input(screen.getByLabelText('Server URL'), { target: { value: 'https://gitea.local' } });
        await fireEvent.input(screen.getByLabelText('Personal Access Token'), { target: { value: 'token123' } });

        // Click Test
        await fireEvent.click(screen.getByText('Test'));

        await waitFor(() => {
            expect(gitService.testConnection).toHaveBeenCalledWith(expect.objectContaining({
                name: 'New Gitea',
                url: 'https://gitea.local',
                pat: 'token123'
            }));
            expect(addToast).toHaveBeenCalledWith('Connection successful', 'success');
        });
    });

    // @UX_FEEDBACK: Save configuration
    it('should save configuration and show success toast', async () => {
        gitService.getConfigs.mockResolvedValue([]);
        gitService.createConfig.mockResolvedValue({
            id: 'conf-2',
            name: 'New Server',
            provider: 'GITHUB',
            url: 'https://github.com',
            pat: '********',
            status: 'CONNECTED'
        });

        render(GitSettingsPage);
        await waitFor(() => expect(screen.getByText('Add Git Server')).toBeTruthy());

        await fireEvent.input(screen.getByLabelText('Display Name'), { target: { value: 'New Server' } });
        await fireEvent.click(screen.getByText('Save Configuration'));

        await waitFor(() => {
            expect(gitService.createConfig).toHaveBeenCalled();
            expect(addToast).toHaveBeenCalledWith('Git configuration saved', 'success');
            // Check that it's added to the list
            expect(screen.getByText('New Server')).toBeTruthy();
        });
    });

    // @UX_STATE: Delete configuration
    it('should delete configuration upon confirmation', async () => {
        gitService.getConfigs.mockResolvedValue([...mockConfigs]);
        gitService.deleteConfig.mockResolvedValue({ status: 'success' });

        render(GitSettingsPage);
        await waitFor(() => expect(screen.getByText('Dev GitLab')).toBeTruthy());

        // Click delete button
        const deleteButton = screen.getByTitle('Delete');
        await fireEvent.click(deleteButton);

        await waitFor(() => {
            expect(global.confirm).toHaveBeenCalledWith('Are you sure?');
            expect(gitService.deleteConfig).toHaveBeenCalledWith('conf-1');
            expect(addToast).toHaveBeenCalledWith('Git configuration deleted', 'success');
            expect(screen.queryByText('Dev GitLab')).toBeNull(); // Should be removed from DOM
        });
    });

    // @UX_STATE: Editing form state
    it('should load config into form when edit is clicked', async () => {
        gitService.getConfigs.mockResolvedValue([...mockConfigs]);

        render(GitSettingsPage);
        await waitFor(() => expect(screen.getByText('Dev GitLab')).toBeTruthy());

        // Click edit button
        const editButton = screen.getByTitle('Edit');
        await fireEvent.click(editButton);

        await waitFor(() => {
            expect(screen.getByText('Edit Git Server')).toBeTruthy();
            const nameInput = screen.getByLabelText('Display Name');
            expect(nameInput.value).toBe('Dev GitLab');
        });

        // Save changes
        gitService.updateConfig.mockResolvedValue({
            ...mockConfigs[0],
            name: 'Updated GitLab'
        });

        await fireEvent.input(screen.getByLabelText('Display Name'), { target: { value: 'Updated GitLab' } });
        await fireEvent.click(screen.getByText('Update Configuration'));

        await waitFor(() => {
            expect(gitService.updateConfig).toHaveBeenCalledWith('conf-1', expect.objectContaining({
                name: 'Updated GitLab'
            }));
            expect(screen.getByText('Updated GitLab')).toBeTruthy();
        });
    });
});
// [/DEF:frontend.src.routes.settings.git.__tests__.git_settings_page_ux_test:Module]
