// noqa: js-006 - async init pattern is safe, loadData has try/catch
/**
 * Testing Dashboard Component
 * Manages the pytest testing dashboard page
 */

// Use centralized logger
const testingDashboardLog = window.LogConfig.createLogger('TESTING-DASHBOARD');

function testingDashboard() {
    return {
        // Extend base data
        ...data(),

        // Set current page for navigation
        currentPage: 'testing',

        // Dashboard-specific data
        loading: false,
        running: false,
        collecting: false,
        error: null,
        successMessage: null,
        activeRunId: null,
        pollInterval: null,
        elapsedTime: 0,
        elapsedTimer: null,

        // Statistics
        stats: {
            total_tests: 0,
            passed: 0,
            failed: 0,
            errors: 0,
            skipped: 0,
            pass_rate: 0,
            duration_seconds: 0,
            coverage_percent: null,
            last_run: null,
            last_run_status: null,
            total_test_files: 0,
            collected_tests: 0,
            unit_tests: 0,
            integration_tests: 0,
            performance_tests: 0,
            system_tests: 0,
            last_collected: null,
            trend: [],
            by_category: {},
            top_failing: []
        },

        // Recent runs
        runs: [],

        async init() {
            // Load i18n translations
            await I18n.loadModule('dev_tools');

            // Guard against multiple initialization
            if (window._adminTestingDashboardInitialized) return;
            window._adminTestingDashboardInitialized = true;

            try {
                testingDashboardLog.info('Initializing testing dashboard');
                await this.loadStats();
                await this.loadRuns();
                // Check if there's a running test and resume polling
                await this.checkForRunningTests();
            } catch (error) {
                testingDashboardLog.error('Failed to initialize testing dashboard:', error);
            }
        },

        async checkForRunningTests() {
            // Check if there's already a test running
            const runningRun = this.runs.find(r => r.status === 'running');
            if (runningRun) {
                testingDashboardLog.info('Found running test:', runningRun.id);
                this.running = true;
                this.activeRunId = runningRun.id;

                // Calculate elapsed time from when the run started
                const startTime = new Date(runningRun.timestamp);
                this.elapsedTime = Math.floor((Date.now() - startTime.getTime()) / 1000);

                // Start elapsed time counter
                this.elapsedTimer = setInterval(() => {
                    this.elapsedTime++;
                }, 1000);

                // Start polling for status
                this.pollInterval = setInterval(() => this.pollRunStatus(), 2000);  // noqa: PERF062
            }
        },

        async loadStats() {
            this.loading = true;
            this.error = null;

            try {
                const stats = await apiClient.get('/admin/tests/stats');
                this.stats = stats;
                testingDashboardLog.info('Stats loaded:', stats);
            } catch (err) {
                testingDashboardLog.error('Failed to load stats:', err);
                this.error = err.message;

                // Redirect to login if unauthorized
                if (err.message.includes('Unauthorized')) {
                    window.location.href = '/admin/login';
                }
            } finally {
                this.loading = false;
            }
        },

        async loadRuns() {
            try {
                const runs = await apiClient.get('/admin/tests/runs?limit=10');
                this.runs = runs;
                testingDashboardLog.info('Runs loaded:', runs.length);
            } catch (err) {
                testingDashboardLog.error('Failed to load runs:', err);
                // Don't set error - stats are more important
            }
        },

        async runTests(testPath = 'tests') {
            this.running = true;
            this.error = null;
            this.successMessage = null;
            this.elapsedTime = 0;

            testingDashboardLog.info('Starting tests:', testPath);

            try {
                // Start the test run (returns immediately)
                const result = await apiClient.post('/admin/tests/run', {
                    test_path: testPath
                });

                testingDashboardLog.info('Test run started:', result);
                this.activeRunId = result.id;

                // Start elapsed time counter
                this.elapsedTimer = setInterval(() => {
                    this.elapsedTime++;
                }, 1000);

                // Start polling for status
                this.pollInterval = setInterval(() => this.pollRunStatus(), 2000);  // noqa: PERF062

                Utils.showToast(I18n.t('dev_tools.messages.test_run_started'), 'info');

            } catch (err) {
                testingDashboardLog.error('Failed to start tests:', err);
                this.error = err.message;
                this.running = false;
                Utils.showToast('Failed to start tests: ' + err.message, 'error');

                // Redirect to login if unauthorized
                if (err.message.includes('Unauthorized')) {
                    window.location.href = '/admin/login';
                }
            }
        },

        async pollRunStatus() {
            if (!this.activeRunId) return;

            try {
                const run = await apiClient.get(`/admin/tests/runs/${this.activeRunId}`);

                if (run.status !== 'running') {
                    // Test run completed
                    this.stopPolling();

                    testingDashboardLog.info('Test run completed:', run);

                    // Format success message
                    const status = run.status === 'passed' ? 'All tests passed!' : 'Tests completed with failures.';
                    this.successMessage = `${status} ${run.passed}/${run.total_tests} passed (${run.pass_rate.toFixed(1)}%) in ${this.formatDuration(run.duration_seconds)}`;

                    // Reload stats and runs
                    await this.loadStats();
                    await this.loadRuns();

                    // Show toast notification
                    Utils.showToast(this.successMessage, run.status === 'passed' ? 'success' : 'warning');

                    // Clear success message after 10 seconds
                    setTimeout(() => {
                        this.successMessage = null;
                    }, 10000);
                }
            } catch (err) {
                testingDashboardLog.error('Failed to poll run status:', err);
                // Don't stop polling on error, might be transient
            }
        },

        stopPolling() {
            if (this.pollInterval) {
                clearInterval(this.pollInterval);
                this.pollInterval = null;
            }
            if (this.elapsedTimer) {
                clearInterval(this.elapsedTimer);
                this.elapsedTimer = null;
            }
            this.running = false;
            this.activeRunId = null;
        },

        async collectTests() {
            this.collecting = true;
            this.error = null;

            testingDashboardLog.info('Collecting tests');

            try {
                const result = await apiClient.post('/admin/tests/collect');
                testingDashboardLog.info('Collection completed:', result);

                Utils.showToast(`Collected ${result.total_tests} tests from ${result.total_files} files`, 'success');

                // Reload stats
                await this.loadStats();
            } catch (err) {
                testingDashboardLog.error('Failed to collect tests:', err);
                Utils.showToast('Failed to collect tests: ' + err.message, 'error');
            } finally {
                this.collecting = false;
            }
        },

        async refresh() {
            await this.loadStats();
            await this.loadRuns();
        },

        formatDuration(seconds) {
            if (seconds === null || seconds === undefined) return 'N/A';
            if (seconds < 1) return `${Math.round(seconds * 1000)}ms`;
            if (seconds < 60) return `${seconds.toFixed(1)}s`;
            const minutes = Math.floor(seconds / 60);
            const secs = Math.round(seconds % 60);
            return `${minutes}m ${secs}s`;
        }
    };
}
