"use client";

import React, { useEffect, useState, useMemo } from "react";
import { ScatterChart, Scatter, XAxis, YAxis, ZAxis, Tooltip, ResponsiveContainer, Cell, CartesianGrid } from "recharts";
import { useGridStore } from "@/store/use-grid-store";
import { getApiUrl } from "@/lib/api-config";
import { cn, safeJSONStringify } from "@/lib/utils";
import { Filter, TrendingUp, Info, Download, CheckCircle2, XCircle } from "lucide-react";

type CorrelationMethod = 'pearson' | 'spearman' | 'kendall';

// Multicollinearity threshold: correlations above this between predictors are problematic
const MULTICOLLINEARITY_THRESHOLD = 0.7;

interface CorrelationData {
  x: string;
  y: string;
  value: number;
  abs_value: number;
}

interface CorrelationResult {
  matrix: CorrelationData[];
  pvalues: Array<{ x: string; y: string; pvalue: number | null; significant: boolean }>;
  metadata: {
    method: string;
    n_observations: number;
    n_variables: number;
    columns_analyzed: string[];
    threshold_applied?: number;
  };
}

interface CorrelationSummary {
  strongest: CorrelationData[];
  weakest: CorrelationData[];
  total_pairs: number;
}

export function CorrelationHeatmap() {
  const { columns, getCleanData } = useGridStore();
  const [result, setResult] = useState<CorrelationResult | null>(null);
  const [summary, setSummary] = useState<CorrelationSummary | null>(null);
  const [loading, setLoading] = useState(false);

  // Controls
  const [method, setMethod] = useState<CorrelationMethod>('pearson');
  const [threshold, setThreshold] = useState<number | null>(null);
  const [showOnlySignificant, setShowOnlySignificant] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      const numericCols = columns.filter(c => c.type === 'numeric').map(c => c.name);
      const cleanData = getCleanData();

      if (numericCols.length < 2 || cleanData.length === 0) return;

      setLoading(true);
      try {
        const response = await fetch(getApiUrl("/analysis/correlation"), {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: safeJSONStringify({
            data: cleanData,
            columns: numericCols,
            method,
            min_threshold: threshold,
            include_pvalues: true
          })
        });

        const data = await response.json();
        if (data.status === "ok") {
          setResult(data.result);
          setSummary(data.summary);
        }
      } catch (e) {
        console.error("Correlation failed", e);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, [columns, getCleanData, method, threshold]);

  // Filter matrix based on significance toggle
  const filteredMatrix = useMemo(() => {
    if (!result || !showOnlySignificant) return result?.matrix || [];

    const significantSet = new Set(
      result.pvalues
        .filter(p => p.significant)
        .map(p => `${p.x}-${p.y}`)
    );

    return result.matrix.filter(m =>
      significantSet.has(`${m.x}-${m.y}`)
    );
  }, [result, showOnlySignificant]);

  if (loading) return (
    <div className="p-12 text-center text-slate-400 animate-pulse">
      Calcul de la corrélation ({method})...
    </div>
  );

  // Better error messages
  if (!result || result.matrix.length === 0) {
    const numericCount = columns.filter(c => c.type === 'numeric').length;
    const hasData = getCleanData().length > 0;

    return (
      <div className="flex flex-col items-center justify-center h-64 border-2 border-dashed border-slate-200 rounded-xl bg-white">
        <Info className="w-12 h-12 text-slate-300 mb-4" />
        <p className="text-slate-600 font-medium mb-2">Corrélation non disponible</p>
        <div className="text-xs text-slate-400 text-center space-y-1 max-w-md">
          {!hasData && <p>📂 Importez d'abord un fichier de données</p>}
          {hasData && numericCount < 2 && <p>📊 Il faut au moins <strong>2 colonnes numériques</strong> pour calculer une corrélation. Actuellement : {numericCount} colonne(s) numérique(s)</p>}
          {hasData && numericCount >= 2 && <p>⚠️ Erreur lors du calcul. Vérifiez que les données contiennent des valeurs numériques valides.</p>}
        </div>
      </div>
    );
  }

  const exportData = () => {
    if (!result) return;

    const csv = [
      ['Variable X', 'Variable Y', 'Corrélation', 'P-Value', 'Significatif'].join(','),
      ...result.matrix.map(m => {
        const pvalue = result.pvalues.find(p => p.x === m.x && p.y === m.y);
        return [
          m.x,
          m.y,
          m.value.toFixed(6),
          pvalue?.pvalue?.toFixed(6) || 'N/A',
          pvalue?.significant ? 'Oui' : 'Non'
        ].join(',');
      })
    ].join('\n');

    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `correlation_${method}_${new Date().toISOString().split('T')[0]}.csv`;
    a.click();
  };

  return (
    <div className="space-y-6">
      {/* Intro Section */}
      <div className="bg-gradient-to-br from-indigo-50 to-blue-50 p-6 rounded-2xl border border-indigo-100">
        <div className="flex items-start gap-4">
          <div className="w-12 h-12 bg-white rounded-xl flex items-center justify-center shadow-sm">
            <TrendingUp className="w-6 h-6 text-indigo-600" />
          </div>
          <div className="flex-1">
            <h2 className="text-sm font-bold text-slate-800 mb-2">Matrice de Corrélation</h2>
            <p className="text-xs text-slate-600 leading-relaxed mb-3">
              La corrélation mesure la force et la direction de la relation linéaire entre deux variables.
              Utilisez cette matrice pour :
            </p>
            <ul className="text-[10px] text-slate-600 space-y-1">
              <li className="flex items-start gap-2">
                <CheckCircle2 className="w-3 h-3 text-emerald-500 shrink-0 mt-0.5" />
                <span><strong>Identifier les prédicteurs pertinents</strong> - corrélations fortes avec votre cible</span>
              </li>
              <li className="flex items-start gap-2">
                <XCircle className="w-3 h-3 text-rose-500 shrink-0 mt-0.5" />
                <span><strong>Éviter la multicolinéarité</strong> - bordure <strong className="text-rose-600">rouge</strong> = corrélation ≥ {MULTICOLLINEARITY_THRESHOLD} entre prédicteurs (à exclure)</span>
              </li>
              <li className="flex items-start gap-2">
                <CheckCircle2 className="w-3 h-3 text-emerald-500 shrink-0 mt-0.5" />
                <span><strong>Comprendre les relations</strong> - comment les variables interagissent entre elles</span>
              </li>
            </ul>
          </div>
        </div>
      </div>

      {/* Controls Header */}
      <div className="bg-white p-6 rounded-2xl border border-slate-200 shadow-sm">
        <div className="flex items-center justify-between mb-4">
          <div>
            <h3 className="text-sm font-bold text-slate-800">Contrôles & Filtres</h3>
            <p className="text-xs text-slate-500 mt-1">
              {result.metadata.n_variables} variables • {result.metadata.n_observations} observations
            </p>
          </div>
          <button
            onClick={exportData}
            className="flex items-center gap-2 px-4 py-2 text-xs font-semibold text-slate-600 bg-slate-50 hover:bg-slate-100 rounded-lg border border-slate-200 transition-colors"
          >
            <Download className="w-4 h-4" />
            Exporter CSV
          </button>
        </div>

        {/* Controls */}
        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
          {/* Method Selection */}
          <div>
            <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2 block">
              Méthode
            </label>
            <select
              value={method}
              onChange={(e) => setMethod(e.target.value as CorrelationMethod)}
              className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
            >
              <option value="pearson">Pearson (linéaire)</option>
              <option value="spearman">Spearman (monotone)</option>
              <option value="kendall">Kendall (tau)</option>
            </select>
          </div>

          {/* Threshold Filter */}
          <div>
            <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2 block">
              Seuil minimum (optionnel)
            </label>
            <input
              type="number"
              min="0"
              max="1"
              step="0.1"
              value={threshold || ''}
              onChange={(e) => setThreshold(e.target.value ? parseFloat(e.target.value) : null)}
              placeholder="Ex: 0.5"
              className="w-full px-3 py-2 text-sm border border-slate-200 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
            />
          </div>

          {/* Significance Filter */}
          <div>
            <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-2 block">
              Filtre
            </label>
            <label className="flex items-center gap-2 px-3 py-2 text-sm border border-slate-200 rounded-lg cursor-pointer hover:bg-slate-50">
              <input
                type="checkbox"
                checked={showOnlySignificant}
                onChange={(e) => setShowOnlySignificant(e.target.checked)}
                className="rounded border-slate-300 text-indigo-600 focus:ring-indigo-500"
              />
              <span className="text-slate-700">Significatif seulement (p &lt; 0.05)</span>
            </label>
          </div>
        </div>
      </div>

      {/* Summary Cards */}
      {summary && (summary.strongest.length > 0 || summary.weakest.length > 0) && (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {/* Strongest Correlations */}
          {summary.strongest.length > 0 && (
            <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">
              <div className="flex items-center gap-2 mb-3">
                <TrendingUp className="w-4 h-4 text-rose-500" />
                <h4 className="text-xs font-bold text-slate-500 uppercase tracking-widest">
                  Corrélations les Plus Fortes
                </h4>
              </div>
              <div className="space-y-2">
                {summary.strongest.map((item, idx) => {
                  const pvalue = result.pvalues.find(p => p.x === item.x && p.y === item.y);
                  return (
                    <div key={idx} className="flex items-center justify-between text-xs p-2 bg-slate-50 rounded-lg">
                      <span className="font-medium text-slate-700">
                        {item.x} ↔ {item.y}
                      </span>
                      <div className="flex items-center gap-2">
                        <span className={cn(
                          "font-mono font-bold",
                          item.value > 0 ? "text-rose-500" : "text-blue-500"
                        )}>
                          {item.value.toFixed(4)}
                        </span>
                        {pvalue?.significant && (
                          <CheckCircle2 className="w-4 h-4 text-emerald-500" />
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}

          {/* Weakest Correlations */}
          {summary.weakest.length > 0 && (
            <div className="bg-white p-4 rounded-xl border border-slate-200 shadow-sm">
              <div className="flex items-center gap-2 mb-3">
                <Info className="w-4 h-4 text-slate-400" />
                <h4 className="text-xs font-bold text-slate-500 uppercase tracking-widest">
                  Corrélations les Plus Faibles
                </h4>
              </div>
              <div className="space-y-2">
                {summary.weakest.slice(0, 5).map((item, idx) => {
                  const pvalue = result.pvalues.find(p => p.x === item.x && p.y === item.y);
                  return (
                    <div key={idx} className="flex items-center justify-between text-xs p-2 bg-slate-50 rounded-lg">
                      <span className="font-medium text-slate-700">
                        {item.x} ↔ {item.y}
                      </span>
                      <div className="flex items-center gap-2">
                        <span className="font-mono font-bold text-slate-500">
                          {item.value.toFixed(4)}
                        </span>
                        {!pvalue?.significant && pvalue?.pvalue && (
                          <XCircle className="w-4 h-4 text-slate-300" />
                        )}
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </div>
      )}

      {/* Heatmap */}
      <div className="bg-white p-8 rounded-2xl border border-slate-200 shadow-sm">
        {filteredMatrix.length === 0 ? (
          <div className="text-center py-12 text-slate-400">
            Aucune corrélation ne correspond aux filtres sélectionnés.
          </div>
        ) : (
          <div className="h-[500px] w-full relative">
            <ResponsiveContainer width="100%" height="100%">
              <ScatterChart margin={{ top: 20, right: 20, bottom: 20, left: 100 }}>
                <CartesianGrid strokeDasharray="3 3" />
                <XAxis
                  dataKey="x"
                  type="category"
                  name="Variable X"
                  tick={{ fontSize: 10 }}
                  interval={0}
                  angle={-45}
                  textAnchor="end"
                  height={60}
                />
                <YAxis
                  dataKey="y"
                  type="category"
                  name="Variable Y"
                  tick={{ fontSize: 10 }}
                  width={100}
                />
                <ZAxis type="number" dataKey="value" range={[500, 500]} />
                <Tooltip
                  cursor={{ strokeDasharray: '3 3' }}
                  content={({ active, payload }) => {
                    if (active && payload && payload.length) {
                      const data = payload[0].payload as CorrelationData;
                      const pvalue = result.pvalues.find(p => p.x === data.x && p.y === data.y);
                      return (
                        <div className="bg-white p-3 rounded-lg shadow-xl text-xs border border-slate-200 z-50">
                          <p className="font-bold text-slate-800 mb-2">{data.x} ↔ {data.y}</p>
                          <div className="space-y-1">
                            <div className="flex items-center gap-2">
                              <span className="text-slate-500">Corrélation:</span>
                              <span className={cn(
                                "font-mono font-bold",
                                data.value > 0 ? "text-rose-500" : "text-blue-500"
                              )}>
                                {data.value.toFixed(6)}
                              </span>
                            </div>
                            {pvalue && pvalue.pvalue && (
                              <>
                                <div className="flex items-center gap-2">
                                  <span className="text-slate-500">P-value:</span>
                                  <span className="font-mono">{pvalue.pvalue.toFixed(6)}</span>
                                </div>
                                <div className="flex items-center gap-2">
                                  <span className="text-slate-500">Significatif:</span>
                                  {pvalue.significant ? (
                                    <CheckCircle2 className="w-4 h-4 text-emerald-500" />
                                  ) : (
                                    <XCircle className="w-4 h-4 text-slate-300" />
                                  )}
                                </div>
                              </>
                            )}
                            <div className="pt-1 border-t border-slate-100">
                              <span className={cn(
                                "italic text-[10px]",
                                Math.abs(data.value) > 0.7 ? "text-rose-500" :
                                Math.abs(data.value) < 0.3 ? "text-slate-400" : "text-amber-500"
                              )}>
                                {Math.abs(data.value) > 0.7 ? "(Fort)" :
                                 Math.abs(data.value) < 0.3 ? "(Faible)" : "(Moyen)"}
                              </span>
                            </div>
                          </div>
                        </div>
                      );
                    }
                    return null;
                  }}
                />
                <Scatter data={filteredMatrix} shape="square">
                  {filteredMatrix.map((entry, index) => {
                    const val = entry.value;
                    let color;
                    if (val >= 0) {
                      color = `rgba(244, 63, 94, ${0.1 + val * 0.9})`;
                    } else {
                      color = `rgba(59, 130, 246, ${0.1 + Math.abs(val) * 0.9})`;
                    }

                    // Check for problematic multicollinearity (high correlation between predictors)
                    // Exclude diagonal (self-correlation)
                    const isMulticollinear = Math.abs(val) >= MULTICOLLINEARITY_THRESHOLD && entry.x !== entry.y;

                    return (
                      <Cell
                        key={`cell-${index}`}
                        fill={color}
                        stroke={isMulticollinear ? "#dc2626" : "none"}
                        strokeWidth={isMulticollinear ? 3 : 0}
                        style={{
                          filter: isMulticollinear ? "brightness(0.85)" : "none"
                        }}
                      />
                    );
                  })}
                </Scatter>
              </ScatterChart>
            </ResponsiveContainer>
          </div>
        )}
      </div>
    </div>
  );
}
