import { useMemo } from 'react';
import {
  Heart, Footprints, Moon, Activity, Wind, Timer, Flame, Zap,
  Battery, Brain, TrendingUp, TrendingDown, Minus, Thermometer,
  Scale, HeartPulse, RefreshCw, Dumbbell, Apple, Droplets,
} from 'lucide-react';
import { LineChart, Line, ResponsiveContainer } from 'recharts';
import {
  METRIC_CONFIG,
  PROVIDER_CONFIG,
  type Provider,
  type APIDeviceReading,
  type MetricId,
} from './types';

const ICON_MAP: Record<string, React.ComponentType<{ className?: string }>> = {
  Heart, Footprints, Moon, Activity, Wind, Timer, Flame, Zap,
  Battery, Brain, TrendingUp, Thermometer, Scale, HeartPulse, Dumbbell,
  Apple, Droplets,
};

interface MetricCardProps {
  metricId: string;
  value: number | null;
  date: string | null;
  provider: Provider | null;
  trend?: number;
  showSparkline?: boolean;
  history?: APIDeviceReading[];
  compact?: boolean;
  onClick?: () => void;
}

export function MetricCard({
  metricId, value, date, provider, trend,
  showSparkline, history, compact, onClick,
}: MetricCardProps) {
  const config = METRIC_CONFIG[metricId as MetricId];
  if (!config) return null;

  const Icon = ICON_MAP[config.icon] || Activity;
  const provInfo = provider ? PROVIDER_CONFIG[provider] : null;

  const rangeStatus = useMemo(() => {
    if (value == null || !config.normalRange) return 'none';
    const { min, max } = config.normalRange;
    if (value >= min && value <= max) return 'good';
    const margin = (max - min) * 0.2;
    if (value >= min - margin && value <= max + margin) return 'warn';
    return 'bad';
  }, [value, config.normalRange]);

  const rangeBarColor = {
    good: 'bg-emerald-400',
    warn: 'bg-amber-400',
    bad: 'bg-red-400',
    none: 'bg-gray-200',
  }[rangeStatus];

  const trendInfo = useMemo(() => {
    if (trend == null) return null;
    const dir = config.goodDirection;
    const positive = trend > 0;
    let color = 'text-gray-400';
    let TrendIcon = Minus;
    if (dir === 'up') {
      color = positive ? 'text-emerald-500' : 'text-red-500';
      TrendIcon = positive ? TrendingUp : TrendingDown;
    } else if (dir === 'down') {
      color = positive ? 'text-red-500' : 'text-emerald-500';
      TrendIcon = positive ? TrendingUp : TrendingDown;
    }
    return { color, TrendIcon, label: `${trend > 0 ? '+' : ''}${trend.toFixed(1)}%` };
  }, [trend, config.goodDirection]);

  const dateLabel = useMemo(() => {
    if (!date) return '';
    // Compare against LOCAL dates, not UTC — Android writes readings tagged
    // with the user's local calendar day, so the "Today" label has to be
    // computed in local time too or it'll say "Yesterday" for users east of
    // UTC after midnight.
    const fmt = (d: Date) => {
      const y = d.getFullYear();
      const m = String(d.getMonth() + 1).padStart(2, '0');
      const dd = String(d.getDate()).padStart(2, '0');
      return `${y}-${m}-${dd}`;
    };
    const today = fmt(new Date());
    const yesterday = fmt(new Date(Date.now() - 86400000));
    if (date === today) return 'Today';
    if (date === yesterday) return 'Yesterday';
    return new Date(date + 'T00:00:00').toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  }, [date]);

  if (compact) {
    return (
      <button
        onClick={onClick}
        className="flex items-center gap-2.5 p-2.5 rounded-lg border border-gray-100 hover:border-gray-200 hover:shadow-sm transition-all text-left w-full"
      >
        <div className="w-8 h-8 rounded-lg bg-gray-50 flex items-center justify-center shrink-0">
          <Icon className="w-4 h-4 text-gray-500" />
        </div>
        <div className="min-w-0 flex-1">
          <p className="text-[11px] text-gray-400 truncate">{config.label}</p>
          {value != null ? (
            <p className="text-sm font-semibold text-gray-800">{config.format(value)} <span className="text-[10px] font-normal text-gray-400">{config.unit}</span></p>
          ) : (
            <p className="text-xs text-gray-300">No data</p>
          )}
        </div>
      </button>
    );
  }

  return (
    <button
      onClick={onClick}
      className="p-4 rounded-xl border border-gray-100 hover:border-gray-200 hover:shadow-md transition-all text-left w-full bg-white group"
    >
      <div className="flex items-start justify-between mb-2">
        <div className="w-9 h-9 rounded-lg bg-gray-50 flex items-center justify-center group-hover:bg-gray-100 transition-colors">
          <Icon className="w-4.5 h-4.5 text-gray-500" />
        </div>
        {trendInfo && (
          <div className={`flex items-center gap-0.5 text-xs font-medium ${trendInfo.color}`}>
            <trendInfo.TrendIcon className="w-3.5 h-3.5" />
            {trendInfo.label}
          </div>
        )}
      </div>

      <p className="text-xs text-gray-400 mb-0.5">{config.label}</p>

      {value != null ? (
        <div className="flex items-baseline gap-1">
          <span className="text-xl font-bold text-gray-900">{config.format(value)}</span>
          <span className="text-xs text-gray-400">{config.unit}</span>
        </div>
      ) : (
        <div className="flex items-center gap-1.5 text-gray-300">
          <RefreshCw className="w-3.5 h-3.5" />
          <span className="text-sm">No data</span>
        </div>
      )}

      {/* Normal range bar */}
      {config.normalRange && value != null && (
        <div className={`h-1 rounded-full mt-2 ${rangeBarColor}`} />
      )}

      {/* Sparkline */}
      {showSparkline && history && history.length > 1 && (
        <div className="mt-2 h-10">
          <ResponsiveContainer width="100%" height="100%">
            <LineChart data={history.map(r => ({ v: r.value }))}>
              <Line type="monotone" dataKey="v" stroke="#94a3b8" strokeWidth={1.5} dot={false} />
            </LineChart>
          </ResponsiveContainer>
        </div>
      )}

      {/* Footer */}
      <div className="flex items-center justify-between mt-2">
        <span className="text-[10px] text-gray-300">{dateLabel}</span>
        {provInfo && (
          <span
            className="text-[10px] font-medium px-1.5 py-0.5 rounded"
            style={{ color: provInfo.brandColor, backgroundColor: `${provInfo.brandColor}12` }}
          >
            {provInfo.name}
          </span>
        )}
      </div>
    </button>
  );
}
