// SPDX-FileCopyrightText: © 2025 Nøkken.io <nokken.io@proton.me>
// SPDX-License-Identifier: AGPL-3.0
//
// HealthAnalyticsEngine.h
// Core C++ header for health analytics calculations
//
#ifndef HEALTH_ANALYTICS_ENGINE_H
#define HEALTH_ANALYTICS_ENGINE_H

#include <vector>
#include <string>
#include <cstring>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <memory>
#include <cstdint>

// Constants
constexpr int MAX_STRING_SIZE = 200;

// Forward declarations
struct DateStruct;
struct BasicStats;
struct TrendResult;
struct CorrelationResult;
struct MultivariateCorrelation;
struct ClusterResult;
struct TimeSeriesForecast;
struct AnomalyResult;
struct FactorImpactResult;
struct DatePatternResult;
struct CycleAnalysisResult;
struct MedicationImpactAnalysis;
struct HormoneImpactAnalysis;

// Data structures for FFI communication
struct DateStruct {
    int year;
    int month;
    int day;
};

struct BasicStats {
    double mean;
    double median;
    double min;
    double max;
    double stdDev;
    double variance;
    double skewness;
    double kurtosis;
    double q1;
    double q3;
    double iqr;
};

enum TrendType {
    TREND_NONE = 0,
    TREND_INCREASING = 1,
    TREND_DECREASING = 2,
    TREND_CYCLIC = 3,
    TREND_VARIABLE = 4
};

struct TrendResult {
    TrendType trendType;
    double strength;
    char description[MAX_STRING_SIZE];
};

struct CorrelationResult {
    int factorIndex;
    double correlation;
    double pValue;
    double confidence;
    char factorName[MAX_STRING_SIZE];
};

enum RelationshipType {
    RELATIONSHIP_CORRELATION = 0,
    RELATIONSHIP_CAUSATION = 1,
    RELATIONSHIP_COINCIDENTAL = 2,
    RELATIONSHIP_MEDIATION = 3,
    RELATIONSHIP_NETWORK = 4
};

struct MultivariateCorrelation {
    int factorCount;
    char factorNames[MAX_STRING_SIZE][MAX_STRING_SIZE];
    double factorWeights[50]; // Using a constant size
    double correlationStrength;
    char description[MAX_STRING_SIZE];
    double confidence;
    RelationshipType relationshipType;
    int primaryFactorIndex;
    int secondaryFactorIndex;
    int tertiaryFactorIndex;
};

struct ClusterResult {
    int clusterId;
    char clusterName[MAX_STRING_SIZE];
    char description[MAX_STRING_SIZE];
    int dataPointCount;
    double significance;
    int factorIndices[50]; // Using a constant size
    double factorWeights[50]; // Using a constant size
    double centeroid[50]; // Using a constant size
    double radius;
};

enum TimeUnit {
    TIME_UNIT_DAYS = 0,
    TIME_UNIT_WEEKS = 1,
    TIME_UNIT_MONTHS = 2
};

struct TimeSeriesForecast {
    double predictions[30];
    double confidenceIntervals[30][2];
    double overallConfidence;
    int seasonalityPeriod;
    TimeUnit timeUnit;
    char factorName[MAX_STRING_SIZE];
};

enum AnomalyType {
    ANOMALY_OUTLIER = 0,
    ANOMALY_TREND_CHANGE = 1,
    ANOMALY_SEASONALITY_CHANGE = 2,
    ANOMALY_CONTEXTUAL = 3
};

struct AnomalyResult {
    int dataPointIndex;
    double anomalyScore;
    char description[MAX_STRING_SIZE];
    double originalValue;
    double expectedValue;
    DateStruct date;
    double confidence;
    AnomalyType anomalyType;
    char factorName[MAX_STRING_SIZE];
};

struct FactorImpactResult {
    int factorIndex;
    char factorName[MAX_STRING_SIZE];
    double impactScore;
    double directEffect;
    double indirectEffect;
    double confidence;
    char mechanism[MAX_STRING_SIZE];
};

enum PatternType {
    PATTERN_NONE = 0,
    PATTERN_DAILY = 1,
    PATTERN_WEEKLY = 2,
    PATTERN_MONTHLY = 3,
    PATTERN_CUSTOM = 4
};

struct DatePatternResult {
    PatternType patternType;
    int periodicity;
    double strength;
    char description[MAX_STRING_SIZE];
    double peakValues[7];  // For weekly patterns
    int peakDayOfWeek;     // 0-6, where 0 is Sunday
    int peakDayOfMonth;    // 1-31
    int peakMonth;         // 1-12
};

struct CycleAnalysisResult {
    double cycleLength;
    double cycleLengthVariance;
    double amplitude;
    double phaseShift;
    double confidence;
    char description[MAX_STRING_SIZE];
};

struct MedicationImpactAnalysis {
    char medicationName[MAX_STRING_SIZE];
    double beforeMean;
    double afterMean;
    double changeMagnitude;
    double changeSignificance;
    double overallImpact;
    int daysToEffect;
    char description[MAX_STRING_SIZE];
    char factorName[MAX_STRING_SIZE];
};

struct HormoneImpactAnalysis {
    char hormoneName[MAX_STRING_SIZE];
    double currentLevel;
    double optimalLevel;
    double optimalRangeLower;
    double optimalRangeUpper;
    double deviation;
    double impactOnMood;
    double impactOnEnergy;
    double impactOnOtherFactors[50]; // Using a constant size
    char factorNames[50][MAX_STRING_SIZE]; // Using a constant size
    char description[MAX_STRING_SIZE];
};

// Removed the HealthAnalyticsEngine class since it's not implemented

// C-style API for FFI
extern "C" {
    // Basic statistics
    BasicStats calculate_basic_stats(const double* values, int length);
    
    // Trend analysis
    TrendType detect_trend(const double* values, int length, double* strength_out);
    
    // Correlation analysis
    double calculate_correlation(const double* x, const double* y, int length);
    CorrelationResult* find_strongest_correlations(
        const double* target_values, 
        const double** factor_values, 
        const char** factor_names, 
        int data_length, 
        int factor_count);
    void free_correlation_results(CorrelationResult* results);
    
    // Multivariate analysis
    MultivariateCorrelation* find_multivariate_correlations(
        const double** factor_data,
        const char** factor_names,
        int factor_count,
        int data_length);
    void free_multivariate_correlations(MultivariateCorrelation* correlations);
    
    // Cluster analysis
    ClusterResult* perform_cluster_analysis(
        const double** factor_data,
        int factor_count,
        int data_length,
        int max_clusters);
    void free_cluster_results(ClusterResult* results);
    
    // Time series forecasting
    TimeSeriesForecast predict_time_series(
        const double* time_series_data,
        int data_length,
        int steps_ahead,
        const char* factor_name);
    
    // Anomaly detection
    AnomalyResult* detect_anomalies(
        const double* time_series_data,
        int data_length,
        double threshold,
        const DateStruct* dates,
        const char* factor_name);
    void free_anomaly_results(AnomalyResult* results);
    
    // Factor impact ranking
    FactorImpactResult* rank_factor_impacts(
        const double** factor_data,
        const double* target_data,
        const char** factor_names,
        int factor_count,
        int data_length);
    void free_factor_impact_results(FactorImpactResult* results);
    
    // Date pattern analysis
    DatePatternResult* analyze_date_patterns(
        const double* values,
        const DateStruct* dates,
        int data_length,
        const char* factor_name);
    void free_date_pattern_results(DatePatternResult* results);
    
    // Cycle analysis
    CycleAnalysisResult analyze_cycles(
        const double* values,
        const DateStruct* dates,
        int data_length,
        const char* factor_name);
    
    // Medication impact analysis
    MedicationImpactAnalysis* analyze_medication_impact(
        const double* before_data,
        int before_length,
        const double* after_data,
        int after_length,
        const char* medication_name,
        const char* factor_name);
    void free_medication_impact_analysis(MedicationImpactAnalysis* analysis);
    
    // Hormone impact analysis
    HormoneImpactAnalysis* analyze_hormone_impact(
        const double* hormone_levels,
        int data_length,
        const double** factor_data,
        const char** factor_names,
        int factor_count,
        const char* hormone_name,
        double min_optimal_level,
        double max_optimal_level);
    void free_hormone_impact_analysis(HormoneImpactAnalysis* analysis);
}
// Utility functions
void normalize_data(const double* data, int length, double minValue, double maxValue, double* normalizedData);
int detect_change_points(const double* data, int length, double threshold, int* changePoints, int maxChangePoints);
void optimize_svr_parameters(const double** x_data, const double* y_data, int length, 
                           double& bestC, double& bestEpsilon, double& bestGamma, double& bestScore);

#endif // HEALTH_ANALYTICS_ENGINE_H