<template>
    <NcSettingsSection
        :name="t('settings', 'Background jobs')"
        :description="
            t(
                'settings',
                `For the server to work properly, it's important to configure background jobs correctly. Cron is the recommended setting. Please see the documentation for more information.`,
            )
        "
        :doc-url="backgroundJobsDocUrl"
    >
        <template v-if="lastCronTimestamp">
            <NcNoteCard v-if="isExecutionTooOld" type="danger">
                {{
                    t(
                        'settings',
                        `Last job execution ran {time}. Something seems wrong.
                Timestamp of last cron: {timestamp} `,
                        {
                            time: relativeTime,
                            timestamp: lastCronTimestamp,
                        },
                    )
                }}
            </NcNoteCard>

            <NcNoteCard v-else-if="isLongExecutionCron" type="warning">
                {{
                    t(
                        'settings',
                        `Some jobs have not been executed since {maxAgeRelativeTime}. Please consider increasing the execution
                frequency.`,
                        {
                            maxAgeRelativeTime,
                        },
                    )
                }}
            </NcNoteCard>

            <NcNoteCard v-else type="success">
                {{ t('settings', 'Last job ran {relativeTime}.', { relativeTime }) }}
            </NcNoteCard>
        </template>

        <NcNoteCard v-else type="danger">
            {{ t('settings', 'Background job did not run yet!') }}
        </NcNoteCard>

          <!-- Missing Cross References Warning -->
        <NcNoteCard v-if="missingCrossReferencesCount >= 1" type="warning">
            {{
                t('settings', 'Found {count} missing dataset cross-reference(s). You can fix this by running: node ace detect:missing-cross-references --fix', {
                    count: missingCrossReferencesCount,
                })
            }}
        </NcNoteCard>

        <!-- Background Jobs Status Display -->
        <div class="background-jobs-mode">
            <h3>{{ t('settings', 'Background Jobs Mode') }}</h3>

            <div class="current-mode">
                <span class="mode-label">{{ t('settings', 'Current mode:') }}</span>
                <span class="mode-value">{{ getCurrentModeLabel() }}</span>
            </div>

            <!-- <div class="mode-description" v-if="backgroundJobsMode === 'cron'" v-html="cronLabel"></div> -->
        </div>

        <!-- Refresh Button -->
        <div class="actions">
            <button type="button" class="primary" @click="refreshStatus" :disabled="isRefreshing">
                {{ isRefreshing ? t('settings', 'Refreshing...') : t('settings', 'Refresh Status') }}
            </button>
        </div>
    </NcSettingsSection>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { usePage, router } from '@inertiajs/vue3';
import { loadState } from '@/utils/initialState';
import { showError, showSuccess } from '@/utils/toast';
import dayjs from '@/utils/dayjs';

import NcNoteCard from '@/Components/NCNoteCard.vue';
import NcSettingsSection from '@/Components/NcSettingsSection.vue';
import { translate as t } from '@/utils/tethyscloud-l10n';

// Props and reactive data
const cronMaxAge =ref<number>(loadState('settings', 'cronMaxAge', 1758824778));
const backgroundJobsMode = ref<string>(loadState('settings', 'backgroundJobsMode', 'cron'));
const cliBasedCronPossible = ref<boolean>(loadState('settings', 'cliBasedCronPossible', true));
const cliBasedCronUser = ref<string>(loadState('settings', 'cliBasedCronUser', 'www-data'));
const backgroundJobsDocUrl = ref<string>(loadState('settings', 'backgroundJobsDocUrl', ''));
const isRefreshing = ref<boolean>(false);

// Use reactive page reference
const page = usePage();

// Auto-refresh timer
let refreshTimer: NodeJS.Timeout | null = null;
const AUTO_REFRESH_INTERVAL = 30000; // 30 seconds

// Computed properties
const missingCrossReferencesCount = computed((): number => {
    const count = page.props.missingCrossReferencesCount as string | number;
    return typeof count === 'string' ? parseInt(count) || 0 : count || 0;
});

const lastCronTimestamp = computed((): number => {
    const lastCron =  page.props.lastCron as string | number;
    return typeof lastCron === 'string' ? parseInt(lastCron) || 0 : lastCron || 0;
});

const relativeTime = computed((): string => {
    if (!lastCronTimestamp.value) return '';
    // Reference currentTime.value to make this reactive to time changes
    let intermValue = page.props.lastCron as string | number;
    intermValue = typeof intermValue === 'string' ? parseInt(intermValue) || 0 : intermValue || 0;
    return dayjs.unix(intermValue).fromNow();
});

const maxAgeRelativeTime = computed((): string => {
    return dayjs.unix(cronMaxAge).fromNow();
});

const cronLabel = computed((): string => {
    let desc = t('settings', 'Use system cron service to call the cron.php file every 5 minutes.');

    if (cliBasedCronPossible.value) {
        desc +=
            '<br>' +
            t('settings', 'The cron.php needs to be executed by the system account "{user}".', {
                user: cliBasedCronUser.value,
            });
    } else {
        desc +=
            '<br>' +
            t('settings', 'The PHP POSIX extension is required. See {linkstart}PHP documentation{linkend} for more details.', {
                linkstart:
                    '<a target="_blank" rel="noreferrer nofollow" class="external" href="https://www.php.net/manual/en/book.posix.php">',
                linkend: '</a>',
            });
    }

    return desc;
});

const isExecutionTooOld = computed((): boolean => {
    if (!lastCronTimestamp.value) return false;
    return dayjs().unix() - lastCronTimestamp.value > 600; // older than 10 minutes
});

const isLongExecutionCron = computed((): boolean => {
    return dayjs().unix() - cronMaxAge > 24 * 3600 && backgroundJobsMode.value === 'cron';
});

// Methods
const getCurrentModeLabel = (): string => {
    switch (backgroundJobsMode.value) {
        case 'cron':
            return t('settings', 'Cron (Recommended)');
        case 'webcron':
            return t('settings', 'Webcron');
        case 'ajax':
            return t('settings', 'AJAX');
        default:
            return t('settings', 'Unknown');
    }
};

const refreshStatus = async (): Promise<void> => {
    isRefreshing.value = true;

    try {
        // Use Inertia to refresh the current page data
        router.reload({
            only: ['lastCron', 'cronMaxAge', 'missingCrossReferencesCount'], // Also reload missing cross references count
            onSuccess: () => {
                showSuccess(t('settings', 'Background job status refreshed'));
            },
            onError: () => {
                showError(t('settings', 'Failed to refresh status'));
            },
            onFinish: () => {
                isRefreshing.value = false;
            },
        });
    } catch (error) {
        console.error('Failed to refresh status:', error);
        showError(t('settings', 'Failed to refresh status'));
        isRefreshing.value = false;
    }
};

const startAutoRefresh = (): void => {
    refreshTimer = setInterval(() => {
        if (!isRefreshing.value) {
            router.reload({ only: ['lastCron', 'cronMaxAge', 'missingCrossReferencesCount'] });
        }
    }, AUTO_REFRESH_INTERVAL);
};

const stopAutoRefresh = (): void => {
    if (refreshTimer) {
        clearInterval(refreshTimer);
        refreshTimer = null;
    }
};

// Lifecycle hooks
onMounted(() => {
    startAutoRefresh();
});

onUnmounted(() => {
    stopAutoRefresh();
});
</script>

<style lang="css" scoped>
.error {
    margin-top: 8px;
    padding: 5px;
    border-radius: var(--border-radius);
    color: var(--color-primary-element-text);
    background-color: var(--color-error);
    width: initial;
}

.warning {
    margin-top: 8px;
    padding: 5px;
    border-radius: var(--border-radius);
    color: var(--color-primary-element-text);
    background-color: var(--color-warning);
    width: initial;
}

.background-jobs-mode {
    margin-top: 1rem;
}

.background-jobs-mode h3 {
    margin-bottom: 0.5rem;
    font-weight: 600;
}

.current-mode {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.mode-label {
    font-weight: 500;
    color: var(--color-text-light);
}

.mode-value {
    font-weight: 600;
    color: var(--color-main-text);
    padding: 0.25rem 0.5rem;
    background-color: var(--color-background-hover);
    border-radius: var(--border-radius);
}

.mode-description {
    color: var(--color-text-maxcontrast);
    font-size: 0.9rem;
    line-height: 1.4;
    margin-top: 0.5rem;
}

.actions {
    margin-top: 1rem;
    display: flex;
    gap: 0.5rem;
}

.actions button {
    padding: 0.5rem 1rem;
    border: none;
    border-radius: var(--border-radius);
    cursor: pointer;
    font-weight: 500;
    transition: all 0.2s ease;
}

.actions button.primary {
    background-color: var(--color-primary-element);
    color: var(--color-primary-element-text);
}

.actions button.primary:hover:not(:disabled) {
    background-color: var(--color-primary-element-hover);
}

.actions button.primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

@media (max-width: 768px) {
    .current-mode {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }
}
</style>
