"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var SettingsService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SettingsService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const system_settings_entity_1 = require("../database/entities/system-settings.entity");
const business_settings_entity_1 = require("../database/entities/business-settings.entity");
const config_service_1 = require("../common/config/config.service");
const encryption_util_1 = require("../common/utils/encryption.util");
let SettingsService = SettingsService_1 = class SettingsService {
    constructor(systemSettingsRepo, businessSettingsRepo, configService) {
        this.systemSettingsRepo = systemSettingsRepo;
        this.businessSettingsRepo = businessSettingsRepo;
        this.configService = configService;
        this.logger = new common_1.Logger(SettingsService_1.name);
    }
    async getSystemSetting(key) {
        const setting = await this.systemSettingsRepo.findOne({ where: { key } });
        if (!setting) {
            return null;
        }
        if (setting.isEncrypted) {
            try {
                return (0, encryption_util_1.decrypt)(setting.value, this.configService.getEncryptionKey());
            }
            catch {
                return setting.value;
            }
        }
        return setting.value;
    }
    async setSystemSetting(key, value, description, isEncrypted) {
        let setting = await this.systemSettingsRepo.findOne({ where: { key } });
        let storedValue = value;
        if (isEncrypted) {
            storedValue = (0, encryption_util_1.encrypt)(value, this.configService.getEncryptionKey());
        }
        if (!setting) {
            setting = this.systemSettingsRepo.create({
                key,
                value: storedValue,
                description: description || null,
                isEncrypted: isEncrypted || false,
                isPublic: false,
            });
        }
        else {
            setting.value = storedValue;
            if (description !== undefined) {
                setting.description = description;
            }
            if (isEncrypted !== undefined) {
                setting.isEncrypted = isEncrypted;
            }
        }
        setting.updatedAt = new Date();
        const saved = await this.systemSettingsRepo.save(setting);
        this.logger.log(`System setting ${key} updated`);
        return saved;
    }
    async getAllSystemSettings(includeEncrypted) {
        const query = this.systemSettingsRepo.createQueryBuilder('setting');
        if (!includeEncrypted) {
            query.where('setting.isEncrypted = :isEncrypted', { isEncrypted: false });
        }
        return query.orderBy('setting.key', 'ASC').getMany();
    }
    async getBusinessSetting(businessId, key) {
        const setting = await this.businessSettingsRepo.findOne({
            where: { businessId, key },
        });
        if (!setting) {
            return null;
        }
        if (setting.isEncrypted) {
            try {
                return (0, encryption_util_1.decrypt)(setting.value, this.configService.getEncryptionKey());
            }
            catch {
                return setting.value;
            }
        }
        return setting.value;
    }
    async setBusinessSetting(businessId, key, value, description, isEncrypted) {
        let setting = await this.businessSettingsRepo.findOne({
            where: { businessId, key },
        });
        let storedValue = value;
        if (isEncrypted) {
            storedValue = (0, encryption_util_1.encrypt)(value, this.configService.getEncryptionKey());
        }
        if (!setting) {
            setting = this.businessSettingsRepo.create({
                businessId,
                key,
                value: storedValue,
                description: description || null,
                isEncrypted: isEncrypted || false,
            });
        }
        else {
            setting.value = storedValue;
            if (description !== undefined) {
                setting.description = description;
            }
            if (isEncrypted !== undefined) {
                setting.isEncrypted = isEncrypted;
            }
        }
        setting.updatedAt = new Date();
        const saved = await this.businessSettingsRepo.save(setting);
        this.logger.log(`Business setting ${key} updated for ${businessId}`);
        return saved;
    }
    async getAllBusinessSettings(businessId) {
        return this.businessSettingsRepo.find({
            where: { businessId },
            order: { key: 'ASC' },
        });
    }
    async getMpesaConfiguration(businessId) {
        const systemMpesaKeys = [
            'mpesa_consumer_key',
            'mpesa_consumer_secret',
            'mpesa_passkey',
            'mpesa_shortcode',
            'mpesa_till_number',
            'mpesa_transaction_type',
            'mpesa_environment',
            'mpesa_callback_url',
        ];
        const config = {};
        for (const key of systemMpesaKeys) {
            const value = await this.getSystemSetting(key);
            if (value) {
                const configKey = key.replace('mpesa_', '');
                config[configKey] = value;
            }
        }
        config.consumer_key = config.consumer_key || this.configService.get('MPESA_CONSUMER_KEY', '');
        config.consumer_secret = config.consumer_secret || this.configService.get('MPESA_CONSUMER_SECRET', '');
        config.passkey = config.passkey || this.configService.get('MPESA_PASSKEY', '');
        config.shortcode = config.shortcode || this.configService.get('MPESA_SHORTCODE', '');
        config.till_number = config.till_number || this.configService.get('MPESA_TILL_NUMBER', '');
        config.transaction_type = config.transaction_type || this.configService.get('MPESA_TRANSACTION_TYPE', 'CustomerPayBillOnline');
        config.environment = config.environment || this.configService.get('MPESA_ENVIRONMENT', 'sandbox');
        config.callback_url = config.callback_url || this.configService.get('MPESA_CALLBACK_URL', '');
        if (businessId) {
            const businessOverrideKeys = systemMpesaKeys;
            for (const key of businessOverrideKeys) {
                const value = await this.getBusinessSetting(businessId, key);
                if (value) {
                    const configKey = key.replace('mpesa_', '');
                    config[configKey] = value;
                }
            }
        }
        return config;
    }
    async getEmailConfiguration() {
        const keys = [
            'smtp_host',
            'smtp_port',
            'smtp_username',
            'smtp_password',
            'smtp_from_email',
            'smtp_from_name',
            'smtp_encryption',
        ];
        const config = {};
        for (const key of keys) {
            const value = await this.getSystemSetting(key);
            if (value) {
                const configKey = key.replace('smtp_', '');
                config[configKey] = value;
            }
        }
        config.host = config.host || this.configService.get('SMTP_HOST', '');
        config.port = config.port || this.configService.get('SMTP_PORT', '587');
        config.username = config.username || this.configService.get('SMTP_USERNAME', '');
        config.password = config.password || this.configService.get('SMTP_PASSWORD', '');
        config.from_email = config.from_email || this.configService.get('SMTP_FROM_EMAIL', '');
        config.from_name = config.from_name || this.configService.get('SMTP_FROM_NAME', '');
        config.encryption = config.encryption || this.configService.get('SMTP_ENCRYPTION', 'tls');
        return config;
    }
    async getSmsConfiguration() {
        const keys = [
            'sms_provider',
            'sms_api_key',
            'sms_api_secret',
            'sms_sender_id',
            'sms_api_url',
        ];
        const config = {};
        for (const key of keys) {
            const value = await this.getSystemSetting(key);
            if (value) {
                const configKey = key.replace('sms_', '');
                config[configKey] = value;
            }
        }
        config.provider = config.provider || this.configService.get('SMS_PROVIDER', '');
        config.api_key = config.api_key || this.configService.get('SMS_API_KEY', '');
        config.api_secret = config.api_secret || this.configService.get('SMS_API_SECRET', '');
        config.sender_id = config.sender_id || this.configService.get('SMS_SENDER_ID', '');
        config.api_url = config.api_url || this.configService.get('SMS_API_URL', '');
        return config;
    }
};
exports.SettingsService = SettingsService;
exports.SettingsService = SettingsService = SettingsService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(system_settings_entity_1.SystemSettings)),
    __param(1, (0, typeorm_1.InjectRepository)(business_settings_entity_1.BusinessSettings)),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.Repository,
        config_service_1.ConfigService])
], SettingsService);
