/**
 * NotificationConfigEntity.java
 * 
 * Room entity for storing plugin configuration and user preferences
 * Manages settings, preferences, and plugin state across sessions
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 * @since 2025-10-20
 */

package org.timesafari.dailynotification.entities;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Index;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;

/**
 * Room entity for storing plugin configuration and user preferences
 * 
 * This entity manages:
 * - User notification preferences
 * - Plugin settings and state
 * - TimeSafari integration configuration
 * - Performance and behavior tuning
 */
@Entity(
    tableName = "notification_config",
    indices = {
        @Index(value = {"timesafari_did"}),
        @Index(value = {"config_type"}),
        @Index(value = {"updated_at"})
    }
)
public class NotificationConfigEntity {
    
    @PrimaryKey
    @NonNull
    @ColumnInfo(name = "id")
    public String id;
    
    @ColumnInfo(name = "timesafari_did")
    public String timesafariDid;
    
    @ColumnInfo(name = "config_type")
    public String configType;
    
    @ColumnInfo(name = "config_key")
    public String configKey;
    
    @ColumnInfo(name = "config_value")
    public String configValue;
    
    @ColumnInfo(name = "config_data_type")
    public String configDataType;
    
    @ColumnInfo(name = "is_encrypted")
    public boolean isEncrypted;
    
    @ColumnInfo(name = "encryption_key_id")
    public String encryptionKeyId;
    
    @ColumnInfo(name = "created_at")
    public long createdAt;
    
    @ColumnInfo(name = "updated_at")
    public long updatedAt;
    
    @ColumnInfo(name = "ttl_seconds")
    public long ttlSeconds;
    
    @ColumnInfo(name = "is_active")
    public boolean isActive;
    
    @ColumnInfo(name = "metadata")
    public String metadata;
    
    /**
     * Default constructor for Room
     */
    public NotificationConfigEntity() {
        this.createdAt = System.currentTimeMillis();
        this.updatedAt = System.currentTimeMillis();
        this.isEncrypted = false;
        this.isActive = true;
        this.ttlSeconds = 30 * 24 * 60 * 60; // Default 30 days
    }
    
    /**
     * Constructor for configuration entries
     */
    @Ignore
    public NotificationConfigEntity(@NonNull String id, String timesafariDid, 
                                   String configType, String configKey, 
                                   String configValue, String configDataType) {
        this();
        this.id = id;
        this.timesafariDid = timesafariDid;
        this.configType = configType;
        this.configKey = configKey;
        this.configValue = configValue;
        this.configDataType = configDataType;
    }
    
    /**
     * Update the configuration value and timestamp
     */
    public void updateValue(String newValue) {
        this.configValue = newValue;
        this.updatedAt = System.currentTimeMillis();
    }
    
    /**
     * Mark configuration as encrypted
     */
    public void setEncrypted(String keyId) {
        this.isEncrypted = true;
        this.encryptionKeyId = keyId;
        touch();
    }
    
    /**
     * Update the last updated timestamp
     */
    public void touch() {
        this.updatedAt = System.currentTimeMillis();
    }
    
    /**
     * Check if this configuration has expired
     */
    public boolean isExpired() {
        long expirationTime = createdAt + (ttlSeconds * 1000);
        return System.currentTimeMillis() > expirationTime;
    }
    
    /**
     * Get time until expiration in milliseconds
     */
    public long getTimeUntilExpiration() {
        long expirationTime = createdAt + (ttlSeconds * 1000);
        return Math.max(0, expirationTime - System.currentTimeMillis());
    }
    
    /**
     * Get configuration age in milliseconds
     */
    public long getConfigAge() {
        return System.currentTimeMillis() - createdAt;
    }
    
    /**
     * Get time since last update in milliseconds
     */
    public long getTimeSinceUpdate() {
        return System.currentTimeMillis() - updatedAt;
    }
    
    /**
     * Parse configuration value based on data type
     */
    public Object getParsedValue() {
        if (configValue == null) {
            return null;
        }
        
        switch (configDataType) {
            case "boolean":
                return Boolean.parseBoolean(configValue);
            case "integer":
                try {
                    return Integer.parseInt(configValue);
                } catch (NumberFormatException e) {
                    return 0;
                }
            case "long":
                try {
                    return Long.parseLong(configValue);
                } catch (NumberFormatException e) {
                    return 0L;
                }
            case "float":
                try {
                    return Float.parseFloat(configValue);
                } catch (NumberFormatException e) {
                    return 0.0f;
                }
            case "double":
                try {
                    return Double.parseDouble(configValue);
                } catch (NumberFormatException e) {
                    return 0.0;
                }
            case "json":
            case "string":
            default:
                return configValue;
        }
    }
    
    /**
     * Set configuration value with proper data type
     */
    public void setTypedValue(Object value) {
        if (value == null) {
            this.configValue = null;
            this.configDataType = "string";
        } else if (value instanceof Boolean) {
            this.configValue = value.toString();
            this.configDataType = "boolean";
        } else if (value instanceof Integer) {
            this.configValue = value.toString();
            this.configDataType = "integer";
        } else if (value instanceof Long) {
            this.configValue = value.toString();
            this.configDataType = "long";
        } else if (value instanceof Float) {
            this.configValue = value.toString();
            this.configDataType = "float";
        } else if (value instanceof Double) {
            this.configValue = value.toString();
            this.configDataType = "double";
        } else if (value instanceof String) {
            this.configValue = (String) value;
            this.configDataType = "string";
        } else {
            // For complex objects, serialize as JSON
            this.configValue = value.toString();
            this.configDataType = "json";
        }
        touch();
    }
    
    @Override
    public String toString() {
        return "NotificationConfigEntity{" +
                "id='" + id + '\'' +
                ", timesafariDid='" + timesafariDid + '\'' +
                ", configType='" + configType + '\'' +
                ", configKey='" + configKey + '\'' +
                ", configDataType='" + configDataType + '\'' +
                ", isEncrypted=" + isEncrypted +
                ", isActive=" + isActive +
                ", isExpired=" + isExpired() +
                '}';
    }
}
