import db from '../database/models/index.js';

const CATEGORY = 'sla';
const KEYS = {
    enabled: 'questionnaire_reminder.enabled',
    firstAfterDays: 'questionnaire_reminder.first_after_days',
    intervalDays: 'questionnaire_reminder.interval_days',
    maxCount: 'questionnaire_reminder.max_count'
} as const;

export type QuestionnaireReminderSettings = {
    enabled: boolean;
    firstAfterDays: number;
    intervalDays: number;
    maxCount: number;
    source: 'database' | 'environment';
};

function envBool(name: string, fallback: boolean): boolean {
    const v = String(process.env[name] ?? '').trim().toLowerCase();
    if (v === 'true' || v === '1') return true;
    if (v === 'false' || v === '0') return false;
    return fallback;
}

function envInt(name: string, fallback: number): number {
    const n = Number(process.env[name]);
    return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
}

function envDefaults(): QuestionnaireReminderSettings {
    return {
        enabled: envBool('QUESTIONNAIRE_REMINDER_SCHEDULER_ENABLED', true),
        firstAfterDays: envInt('QUESTIONNAIRE_REMINDER_FIRST_AFTER_DAYS', 1),
        intervalDays: envInt('QUESTIONNAIRE_REMINDER_INTERVAL_DAYS', 2),
        maxCount: envInt('QUESTIONNAIRE_REMINDER_MAX_COUNT', 5),
        source: 'environment'
    };
}

function parseStoredValue(key: string, raw: string): boolean | number | null {
    if (key === KEYS.enabled) {
        const v = raw.trim().toLowerCase();
        if (v === 'true' || v === '1') return true;
        if (v === 'false' || v === '0') return false;
        return null;
    }
    const n = Number(raw);
    return Number.isFinite(n) && n > 0 ? Math.floor(n) : null;
}

export async function getQuestionnaireReminderSettings(): Promise<QuestionnaireReminderSettings> {
    const defaults = envDefaults();
    const rows = await db.SystemConfiguration.findAll({
        where: { key: Object.values(KEYS), isActive: true }
    });
    if (!rows.length) return defaults;

    const map = new Map(rows.map((r: any) => [r.key, r.value]));
    let fromDb = false;

    const enabledRaw = map.get(KEYS.enabled);
    const firstRaw = map.get(KEYS.firstAfterDays);
    const intervalRaw = map.get(KEYS.intervalDays);
    const maxRaw = map.get(KEYS.maxCount);

    const enabledParsed = enabledRaw != null ? parseStoredValue(KEYS.enabled, String(enabledRaw)) : null;
    const firstParsed = firstRaw != null ? parseStoredValue(KEYS.firstAfterDays, String(firstRaw)) : null;
    const intervalParsed = intervalRaw != null ? parseStoredValue(KEYS.intervalDays, String(intervalRaw)) : null;
    const maxParsed = maxRaw != null ? parseStoredValue(KEYS.maxCount, String(maxRaw)) : null;

    if (enabledParsed !== null) fromDb = true;
    if (firstParsed !== null) fromDb = true;
    if (intervalParsed !== null) fromDb = true;
    if (maxParsed !== null) fromDb = true;

    return {
        enabled: (enabledParsed as boolean | null) ?? defaults.enabled,
        firstAfterDays: (firstParsed as number | null) ?? defaults.firstAfterDays,
        intervalDays: (intervalParsed as number | null) ?? defaults.intervalDays,
        maxCount: (maxParsed as number | null) ?? defaults.maxCount,
        source: fromDb ? 'database' : 'environment'
    };
}

export async function saveQuestionnaireReminderSettings(
    input: Partial<Omit<QuestionnaireReminderSettings, 'source'>>
): Promise<QuestionnaireReminderSettings> {
    const upsert = async (key: string, value: string, description: string) => {
        const existing = await db.SystemConfiguration.findOne({ where: { key } });
        if (existing) {
            await existing.update({ value, category: CATEGORY, isActive: true });
        } else {
            await db.SystemConfiguration.create({
                key,
                value,
                category: CATEGORY,
                description,
                isActive: true
            });
        }
    };

    if (input.enabled !== undefined) {
        await upsert(KEYS.enabled, String(input.enabled), 'Enable scheduled prospect questionnaire reminders');
    }
    if (input.firstAfterDays !== undefined) {
        await upsert(
            KEYS.firstAfterDays,
            String(input.firstAfterDays),
            'Days after Questionnaire Pending before first reminder'
        );
    }
    if (input.intervalDays !== undefined) {
        await upsert(
            KEYS.intervalDays,
            String(input.intervalDays),
            'Minimum days between repeat questionnaire reminders'
        );
    }
    if (input.maxCount !== undefined) {
        await upsert(KEYS.maxCount, String(input.maxCount), 'Maximum auto questionnaire reminders per application');
    }

    return getQuestionnaireReminderSettings();
}
