#!/usr/bin/env python3
"""
Export the cluster classification model to JSON for use in JavaScript.
"""

import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
import json

# Dimension names
DIMENSIONS = [
    'Design_explicit_vs_implicit',
    'Design_precise_vs_interpretive',
    'Design_elite_vs_vernacular',
    'Design_documenting_vs_enabling',
    'Design_static_vs_malleable',
    'Design_technical_vs_social',
    'Design_universal_vs_particular',
    'Design_durable_vs_ephemeral',
    'Entanglement_macro_vs_micro',
    'Entanglement_sovereign_vs_subsidiary',
    'Entanglement_self-enforcing_vs_enforced',
    'Entanglement_abstract_vs_embodied',
    'Entanglement_obligatory_vs_voluntary',
    'Entanglement_flocking_vs_swarming',
    'Entanglement_defensible_vs_exposed',
    'Entanglement_exclusive_vs_non-exclusive',
    'Experience_sufficient_vs_insufficient',
    'Experience_crystallized_vs_contested',
    'Experience_trust-evading_vs_trust-inducing',
    'Experience_predictable_vs_emergent',
    'Experience_exclusion_vs_inclusion',
    'Experience_Kafka_vs_Whitehead',
    'Experience_dead_vs_alive',
]

# Load data
df = pd.read_csv('diagnostic_output.csv')
clusters = pd.read_csv('analysis_results/data/kmeans_clusters.csv')

# Remove duplicates
df = df.drop_duplicates(subset='Descriptor', keep='first')

# Merge and clean
merged = df.merge(clusters, on='Descriptor')
merged_clean = merged.dropna(subset=DIMENSIONS)

# Prepare training data
X = merged_clean[DIMENSIONS].values
y = merged_clean['cluster'].values

# Fit scaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Fit LDA
lda = LinearDiscriminantAnalysis(n_components=1)
lda.fit(X_scaled, y)

# Calculate cluster centroids
cluster_centroids = {}
for cluster_id in [1, 2]:
    cluster_data = X_scaled[y == cluster_id]
    cluster_centroids[cluster_id] = cluster_data.mean(axis=0).tolist()

# Calculate cluster means in original space (for reference)
cluster_means_original = {}
for cluster_id in [1, 2]:
    cluster_data_original = X[y == cluster_id]
    cluster_means_original[cluster_id] = cluster_data_original.mean(axis=0).tolist()

# Key dimensions (most discriminative)
KEY_DIMENSIONS = [
    'Design_elite_vs_vernacular',
    'Entanglement_flocking_vs_swarming',
    'Design_static_vs_malleable',
    'Entanglement_obligatory_vs_voluntary',
    'Entanglement_self-enforcing_vs_enforced',
    'Design_explicit_vs_implicit',
    'Entanglement_sovereign_vs_subsidiary',
    'Design_technical_vs_social',
]

# Build model export
model = {
    'version': '1.0',
    'generated': pd.Timestamp.now().isoformat(),
    'dimensions': DIMENSIONS,
    'key_dimensions': KEY_DIMENSIONS,
    'cluster_names': {
        '1': 'Relational/Cultural',
        '2': 'Institutional/Bureaucratic'
    },
    'cluster_descriptions': {
        '1': 'Community-based, emergent, voluntary, cultural protocols',
        '2': 'Formal, institutional, top-down, bureaucratic protocols'
    },
    'scaler': {
        'mean': scaler.mean_.tolist(),
        'scale': scaler.scale_.tolist()
    },
    'lda': {
        'coefficients': lda.coef_[0].tolist(),
        'intercept': lda.intercept_[0]
    },
    'cluster_centroids_scaled': cluster_centroids,
    'cluster_means_original': cluster_means_original,
    'thresholds': {
        'confidence_low': 0.6,
        'completeness_low': 0.5,
        'boundary_distance_low': 0.5
    },
    'metadata': {
        'total_protocols': len(merged_clean),
        'cluster_1_count': int((y == 1).sum()),
        'cluster_2_count': int((y == 2).sum()),
    }
}

# Save to JSON
output_path = 'bicorder_model.json'
with open(output_path, 'w') as f:
    json.dump(model, f, indent=2)

print(f"Model exported to {output_path}")
print(f"Total dimensions: {len(DIMENSIONS)}")
print(f"Key dimensions for short form: {len(KEY_DIMENSIONS)}")
print(f"Model size: {len(json.dumps(model))} bytes")
