import { useMemo, useState } from 'react';

interface DailyTotal {
  day: string; // YYYY-MM-DD
  contracts: number;
  total_value: number;
}

interface Props {
  data: DailyTotal[];
  years?: number;
  cellSize?: number;
  cellGap?: number;
}

const DAY_LABELS = ['L', '', 'M', '', 'V', '', ''];
const MONTH_LABELS = ['ian', 'feb', 'mar', 'apr', 'mai', 'iun', 'iul', 'aug', 'sep', 'oct', 'noi', 'dec'];

function formatRON(value: number): string {
  if (!Number.isFinite(value) || value <= 0) return '0';
  if (value >= 1_000_000_000) return `${(value / 1_000_000_000).toFixed(1)} mld`;
  if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)} mil`;
  if (value >= 1_000) return `${(value / 1_000).toFixed(0)}K`;
  return Math.round(value).toString();
}

export function CalendarHeatmap({ data, years = 5, cellSize = 11, cellGap = 2 }: Props) {
  const [hover, setHover] = useState<DailyTotal | null>(null);

  const { weeks, maxValue, totals, monthMarkers } = useMemo(() => {
    const lookup = new Map<string, DailyTotal>();
    let max = 0;
    for (const d of data) {
      lookup.set(d.day, d);
      if (Number(d.total_value) > max) max = Number(d.total_value);
    }
    // Build day-by-day grid for last `years` years, ending today, starting Monday-aligned.
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const endDate = today;
    const startDate = new Date(today);
    startDate.setFullYear(startDate.getFullYear() - years);
    // Align startDate to Monday
    const dow = startDate.getDay() === 0 ? 6 : startDate.getDay() - 1; // 0=Mon
    startDate.setDate(startDate.getDate() - dow);

    const wks: DailyTotal[][] = [];
    const monthSeen = new Set<number>();
    const monthMarkersLocal: { weekIdx: number; label: string }[] = [];
    let cur = new Date(startDate);
    while (cur <= endDate) {
      const week: DailyTotal[] = [];
      for (let i = 0; i < 7; i++) {
        const ymd = cur.toISOString().slice(0, 10);
        const found = lookup.get(ymd);
        week.push(found || { day: ymd, contracts: 0, total_value: 0 });
        cur.setDate(cur.getDate() + 1);
      }
      wks.push(week);
      // Mark month transitions on Monday rows
      const firstDay = week[0];
      const m = new Date(firstDay.day).getMonth();
      const y = new Date(firstDay.day).getFullYear();
      const key = y * 12 + m;
      if (!monthSeen.has(key) && new Date(firstDay.day).getDate() <= 7) {
        monthSeen.add(key);
        const lbl = m === 0 ? `${MONTH_LABELS[m]} ${y % 100}` : MONTH_LABELS[m];
        monthMarkersLocal.push({ weekIdx: wks.length - 1, label: lbl });
      }
    }

    let totalContracts = 0, totalValue = 0;
    for (const d of data) { totalContracts += Number(d.contracts) || 0; totalValue += Number(d.total_value) || 0; }

    return { weeks: wks, maxValue: max, totals: { contracts: totalContracts, value: totalValue }, monthMarkers: monthMarkersLocal };
  }, [data, years]);

  const intensity = (value: number) => {
    if (value <= 0 || maxValue <= 0) return 0;
    const ratio = value / maxValue;
    // Discrete buckets (5 levels) using log scale for skewed value distribution
    const log = Math.log10(value + 1) / Math.log10(maxValue + 1);
    if (log < 0.2) return 1;
    if (log < 0.4) return 2;
    if (log < 0.6) return 3;
    if (log < 0.8) return 4;
    return 5;
  };

  const COLORS = ['#F1F5F9', '#DBE5F1', '#93C5FD', '#3B82F6', '#1D4ED8', '#0F3473'];

  const width = weeks.length * (cellSize + cellGap) + 30;
  const height = 7 * (cellSize + cellGap) + 24;

  return (
    <div className="profile-heatmap">
      <div className="profile-heatmap-head">
        <div>
          <div className="profile-heatmap-title">Activitate {years} ani</div>
          <div className="profile-heatmap-subtitle">
            {totals.contracts.toLocaleString('ro-RO')} anunțuri · {formatRON(totals.value)} RON
          </div>
        </div>
        <div className="profile-heatmap-legend">
          <span>mai puțin</span>
          {COLORS.map((c, i) => (
            <span key={i} className="profile-heatmap-legend-cell" style={{ background: c, width: cellSize, height: cellSize }} />
          ))}
          <span>mai mult</span>
        </div>
      </div>

      <div className="profile-heatmap-scroll">
        <svg width={width} height={height} style={{ display: 'block' }}>
          {/* Day-of-week labels */}
          {DAY_LABELS.map((lbl, i) => (
            <text
              key={i}
              x={4}
              y={20 + i * (cellSize + cellGap) + cellSize - 2}
              fontSize="9"
              fill="#94A3B8"
              fontFamily="Inter, system-ui, sans-serif"
            >
              {lbl}
            </text>
          ))}
          {/* Month markers */}
          {monthMarkers.map((m, i) => (
            <text
              key={i}
              x={30 + m.weekIdx * (cellSize + cellGap)}
              y={12}
              fontSize="9.5"
              fill="#64748B"
              fontFamily="Plus Jakarta Sans, system-ui, sans-serif"
              fontWeight="500"
            >
              {m.label}
            </text>
          ))}
          {/* Cells */}
          {weeks.map((week, wi) =>
            week.map((day, di) => {
              const v = Number(day.total_value) || 0;
              const lvl = intensity(v);
              const x = 30 + wi * (cellSize + cellGap);
              const y = 20 + di * (cellSize + cellGap);
              const isHover = hover?.day === day.day && day.contracts > 0;
              return (
                <rect
                  key={`${wi}-${di}`}
                  x={x}
                  y={y}
                  width={cellSize}
                  height={cellSize}
                  rx={2}
                  fill={COLORS[lvl]}
                  stroke={isHover ? '#0F172A' : 'rgba(15,23,42,0.04)'}
                  strokeWidth={isHover ? 1 : 0.5}
                  onMouseEnter={() => setHover(day)}
                  onMouseLeave={() => setHover(null)}
                  style={{ cursor: day.contracts > 0 ? 'pointer' : 'default' }}
                />
              );
            }),
          )}
        </svg>
      </div>

      {hover && hover.contracts > 0 && (
        <div className="profile-heatmap-tip">
          <strong>{new Date(hover.day).toLocaleDateString('ro-RO', { day: 'numeric', month: 'long', year: 'numeric' })}</strong>
          {' · '}
          {hover.contracts} anunțuri · {formatRON(Number(hover.total_value))} RON
        </div>
      )}
    </div>
  );
}
