import { useState } from 'react';
import { DimensionBreakdownPanel } from '../ticker/DimensionBreakdownPanel';
import { RadarChart, radarAxesFromDimensions } from '../charts/horizon';
import type { DimensionScoreDetail, CompositeBreakdown } from '../../lib/types';

interface ScoreCardProps {
  compositeScore: number | null;
  dimensions: DimensionScoreDetail[];
  compositeBreakdown?: CompositeBreakdown | null;
  /** Hide the composite ring/header when the composite is shown elsewhere
   *  (e.g. the Standing matrix) and this card only carries the dimension detail. */
  showComposite?: boolean;
  /** Hide the radar fingerprint when the page shows it elsewhere (ticker header). */
  showRadar?: boolean;
}

function scoreColor(score: number): string {
  if (score > 70) return 'text-emerald-400';
  if (score >= 40) return 'text-amber-400';
  return 'text-red-400';
}

function ringGradient(score: number): string {
  if (score > 70) return '#2f9db2';
  if (score >= 40) return '#f59e0b';
  return '#e36a58';
}

function barGradient(score: number): string {
  if (score > 70) return 'from-emerald-500 to-emerald-400';
  if (score >= 40) return 'from-amber-500 to-amber-400';
  return 'from-red-500 to-red-400';
}

function ScoreRing({ score }: { score: number }) {
  const radius = 36;
  const circumference = 2 * Math.PI * radius;
  const clamped = Math.max(0, Math.min(100, score));
  const offset = circumference - (clamped / 100) * circumference;
  const color = ringGradient(score);

  return (
    <div className="relative inline-flex items-center justify-center">
      <svg width="88" height="88" className="-rotate-90">
        <circle cx="44" cy="44" r={radius} fill="none" strokeWidth="6" className="stroke-white/[0.06]" />
        <circle
          cx="44" cy="44" r={radius} fill="none" strokeWidth="6" strokeLinecap="round"
          strokeDasharray={circumference} strokeDashoffset={offset}
          stroke={color}
          style={{ filter: `drop-shadow(0 0 8px ${color}40)`, transition: 'all 0.6s ease' }}
        />
      </svg>
      <span className={`absolute text-lg font-bold ${scoreColor(score)}`}>
        {Math.round(score)}
      </span>
    </div>
  );
}

export function ScoreCard({ compositeScore, dimensions, compositeBreakdown, showComposite = true, showRadar = true }: ScoreCardProps) {
  const [expanded, setExpanded] = useState<Record<string, boolean>>({});

  const toggleExpand = (dimension: string) => {
    setExpanded((prev) => ({ ...prev, [dimension]: !prev[dimension] }));
  };

  return (
    <div className="glass p-5">
      {(showComposite || (showRadar && dimensions.length >= 3)) && (
        <div className="flex flex-wrap items-center gap-4">
          {showComposite && (compositeScore !== null ? (
            <ScoreRing score={compositeScore} />
          ) : (
            <div className="flex h-[88px] w-[88px] items-center justify-center text-sm text-gray-500">N/A</div>
          ))}
          {showComposite && (
          <div>
            <p className="text-xs text-gray-500 uppercase tracking-wider">Composite Score</p>
            <p className={`text-2xl font-bold ${compositeScore !== null ? scoreColor(compositeScore) : 'text-gray-500'}`}>
              {compositeScore !== null ? Math.round(compositeScore) : '—'}
            </p>
            {compositeBreakdown && (
              <p className="mt-1 text-[10px] text-gray-500 leading-snug max-w-[220px]" data-testid="renorm-explanation">
                {compositeBreakdown.sentiment_adjustment != null &&
                compositeBreakdown.base_score != null &&
                Math.abs(compositeBreakdown.sentiment_adjustment) >= 0.05
                  ? `Base ${Math.round(compositeBreakdown.base_score)} · sentiment ${
                      compositeBreakdown.sentiment_adjustment >= 0 ? '+' : '−'
                    }${Math.abs(compositeBreakdown.sentiment_adjustment).toFixed(1)}`
                  : 'Weighted base of the other dimensions; sentiment adjusts it up or down.'}
              </p>
            )}
          </div>
          )}
          {showRadar && dimensions.length >= 3 && (
            <div
              className={showComposite ? 'ml-auto' : 'mx-auto sm:mx-0'}
              title="Score fingerprint — hover a corner for the exact value"
            >
              <RadarChart axes={radarAxesFromDimensions(dimensions)} size={104} />
            </div>
          )}
        </div>
      )}

      {dimensions.length > 0 && (
        <div className={`${showComposite ? 'mt-5' : ''} space-y-1`}>
          <p className="text-[10px] font-medium uppercase tracking-widest text-gray-500">Dimensions</p>
          {dimensions.map((d) => {
            const isExpanded = expanded[d.dimension] ?? false;
            const weight = compositeBreakdown?.renormalized_weights?.[d.dimension]
              ?? compositeBreakdown?.weights?.[d.dimension];

            return (
              <div key={d.dimension}>
                <button
                  type="button"
                  className="flex w-full items-center justify-between text-sm py-1 hover:bg-white/[0.03] rounded transition-colors"
                  onClick={() => d.breakdown && toggleExpand(d.dimension)}
                  data-testid={`dimension-row-${d.dimension}`}
                >
                  <span className="text-gray-300 capitalize flex items-center gap-1.5">
                    {d.breakdown && (
                      <span className="text-gray-500 text-[10px]">{isExpanded ? '▾' : '▸'}</span>
                    )}
                    {d.dimension}
                  </span>
                  <div className="flex items-center gap-2">
                    {d.dimension === 'sentiment' && compositeBreakdown?.sentiment_adjustment != null ? (
                      <span
                        className={`text-[10px] tabular-nums ${
                          compositeBreakdown.sentiment_adjustment > 0.05
                            ? 'text-emerald-400/80'
                            : compositeBreakdown.sentiment_adjustment < -0.05
                            ? 'text-red-400/80'
                            : 'text-gray-500'
                        }`}
                        data-testid="weight-sentiment"
                        title="Points sentiment adds to or subtracts from the base composite"
                      >
                        {compositeBreakdown.sentiment_adjustment >= 0 ? '+' : '−'}
                        {Math.abs(compositeBreakdown.sentiment_adjustment).toFixed(1)}
                      </span>
                    ) : weight != null ? (
                      <span className="text-[10px] text-gray-500 tabular-nums" data-testid={`weight-${d.dimension}`}>
                        {Math.round(weight * 100)}%
                      </span>
                    ) : null}
                    <div className="h-1.5 w-20 rounded-full bg-white/[0.06] overflow-hidden">
                      <div
                        className={`h-1.5 rounded-full bg-gradient-to-r ${barGradient(d.score)} transition-all duration-500`}
                        style={{ width: `${Math.max(0, Math.min(100, d.score))}%` }}
                      />
                    </div>
                    <span className={`w-8 text-right font-medium text-xs ${scoreColor(d.score)}`}>
                      {Math.round(d.score)}
                    </span>
                  </div>
                </button>
                {isExpanded && d.breakdown && (
                  <div className="ml-4 mt-1 mb-2 pl-3 border-l border-white/[0.06]">
                    <DimensionBreakdownPanel breakdown={d.breakdown} />
                  </div>
                )}
              </div>
            );
          })}

          {/* Missing dimensions */}
          {compositeBreakdown && compositeBreakdown.missing_dimensions.length > 0 && (
            <div className="mt-2 space-y-1">
              {compositeBreakdown.missing_dimensions
                .filter((dim) => !dimensions.some((d) => d.dimension === dim))
                .map((dim) => (
                  <div
                    key={dim}
                    className="flex items-center justify-between text-sm py-1 opacity-40"
                    data-testid={`missing-dimension-${dim}`}
                  >
                    <span className="text-gray-500 capitalize">{dim}</span>
                    <span className="text-[10px] text-gray-600 italic">redistributed</span>
                  </div>
                ))}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
