'use client';
import { useEffect, useState, useMemo } from 'react';
import { getRepos, getHeatmap, getRecentCommits, calcStats } from '@/lib/gitea';
import type { GiteaRepo, GiteaCommit, HeatmapEntry } from '@/lib/types';

// ── Calendar constants ──
const CELL = 12, GAP = 3, STEP = CELL + GAP;
const DAY_LABEL_W = 26;
const WEEKS = 52;

const LEVELS = [
  'rgba(15,23,42,0.05)',
  'rgba(15,23,42,0.12)',
  'rgba(15,23,42,0.22)',
  'rgba(15,23,42,0.38)',
  'rgba(15,23,42,0.62)',
];

function getLevel(n: number) {
  if (n === 0) return 0;
  if (n <= 2) return 1;
  if (n <= 5) return 2;
  if (n <= 9) return 3;
  return 4;
}

function timeAgo(s: string) {
  const d = Date.now() - new Date(s).getTime();
  const m = Math.floor(d / 60000);
  if (m < 1) return 'just now';
  if (m < 60) return `${m}m`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h`;
  const days = Math.floor(h / 24);
  if (days < 30) return `${days}d`;
  return `${Math.floor(days / 30)}mo`;
}

// ── Stat item ──
function Stat({
  label,
  value,
  sub,
}: {
  label: string;
  value: string | number;
  sub: string;
}) {
  return (
    <div className="min-w-0">
      <span className="block text-[10px] font-semibold uppercase tracking-[.14em] text-slate-400 mb-1">
        {label}
      </span>
      <span className="block text-[clamp(1.4rem,3vw,2rem)] font-black text-slate-900 tabular-nums leading-none">
        {value}
      </span>
      <span className="block text-xs text-slate-500 mt-1">{sub}</span>
    </div>
  );
}

// ── Contribution Calendar ──
function ContributionCalendar({ data }: { data: HeatmapEntry[] }) {
  const [tooltip, setTooltip] = useState<{
    x: number;
    y: number;
    date: string;
    count: number;
  } | null>(null);

  const dateMap = useMemo(() => {
    const m = new Map<string, number>();
    data.forEach((e) => {
      const k = new Date(e.timestamp * 1000).toISOString().split('T')[0];
      m.set(k, (m.get(k) || 0) + e.contributions);
    });
    return m;
  }, [data]);

  const { weeks, monthLabels } = useMemo(() => {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const startSunday = new Date(today);
    startSunday.setDate(today.getDate() - today.getDay() - 51 * 7);

    const weeks: { date: Date; key: string; count: number }[][] = [];
    const monthLabels: { label: string; x: number }[] = [];
    let lastMonth = -1;
    const cur = new Date(startSunday);

    for (let w = 0; w < WEEKS; w++) {
      const week: { date: Date; key: string; count: number }[] = [];
      for (let d = 0; d < 7; d++) {
        const k = cur.toISOString().split('T')[0];
        week.push({ date: new Date(cur), key: k, count: dateMap.get(k) || 0 });
        cur.setDate(cur.getDate() + 1);
      }
      const mo = week[0].date.getMonth();
      if (mo !== lastMonth) {
        monthLabels.push({
          label: week[0].date.toLocaleDateString('en-US', { month: 'short' }),
          x: w * STEP + DAY_LABEL_W,
        });
        lastMonth = mo;
      }
      weeks.push(week);
    }

    return { weeks, monthLabels };
  }, [dateMap]);

  const svgW = DAY_LABEL_W + WEEKS * STEP;
  const svgH = 7 * STEP + 20;

  return (
    <div className="relative min-w-0">
      <div className="flex items-center justify-between gap-4 mb-4 flex-wrap">
        <span className="text-[11px] font-semibold uppercase tracking-[.14em] text-slate-400">
        </span>
        <div className="flex items-center gap-1.5 text-[10px] text-slate-400">
          <span>Less</span>
          {LEVELS.map((c, i) => (
            <span
              key={i}
              className="rounded-sm inline-block w-2.5 h-2.5 flex-shrink-0 border border-slate-200"
              style={{ background: c }}
              aria-hidden="true"
            />
          ))}
          <span>More</span>
        </div>
      </div>

      <div className="overflow-x-auto pb-1">
        <svg width={svgW} height={svgH} aria-label="Contribution calendar heatmap" role="img">
          {monthLabels.map((m, i) => (
            <text
              key={i}
              x={m.x}
              y={10}
              fontSize={9}
              fill="rgba(15,23,42,0.35)"
              fontFamily="var(--font-geist-mono, monospace)"
            >
              {m.label}
            </text>
          ))}

          {['', 'Mon', '', 'Wed', '', 'Fri', ''].map((d, i) =>
            d ? (
              <text
                key={i}
                x={DAY_LABEL_W - 4}
                y={17 + i * STEP + CELL}
                fontSize={9}
                fill="rgba(15,23,42,0.28)"
                textAnchor="end"
                fontFamily="var(--font-geist-mono, monospace)"
              >
                {d}
              </text>
            ) : null
          )}

          <g transform={`translate(${DAY_LABEL_W}, 14)`}>
            {weeks.map((week, wi) =>
              week.map((day, di) => (
                <rect
                  key={day.key}
                  x={wi * STEP}
                  y={di * STEP}
                  width={CELL}
                  height={CELL}
                  rx={2.5}
                  fill={LEVELS[getLevel(day.count)]}
                  onMouseEnter={(e) =>
                    setTooltip({
                      x: e.clientX,
                      y: e.clientY,
                      date: day.date.toLocaleDateString('en-GB', {
                        weekday: 'short',
                        day: 'numeric',
                        month: 'short',
                        year: 'numeric',
                      }),
                      count: day.count,
                    })
                  }
                  onMouseLeave={() => setTooltip(null)}
                  className="transition-opacity duration-100 hover:opacity-70 cursor-default"
                >
                  <title>
                    {`${day.count} contribution${day.count !== 1 ? 's' : ''} on ${day.date.toLocaleDateString()}`}
                  </title>
                </rect>
              ))
            )}
          </g>
        </svg>
      </div>

      {tooltip && (
        <div
          className="fixed z-50 pointer-events-none px-2.5 py-1.5 rounded-lg text-xs font-medium text-slate-900 bg-white/95 border border-slate-200 shadow-xl whitespace-nowrap"
          style={{ left: tooltip.x + 12, top: tooltip.y - 36 }}
        >
          <span className="font-bold">{tooltip.count}</span>
          {' contribution'}
          {tooltip.count !== 1 ? 's' : ''}
          <span className="text-slate-500 ml-1.5">{tooltip.date}</span>
        </div>
      )}
    </div>
  );
}

// ── Monthly chart ──
function MonthlyChart({ data }: { data: HeatmapEntry[] }) {
  const months = useMemo(() => {
    return Array.from({ length: 12 }, (_, i) => {
      const d = new Date();
      d.setMonth(d.getMonth() - 11 + i);
      const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
      const label = d.toLocaleDateString('en-US', { month: 'short' });
      const count = data
        .filter((e) => {
          const ed = new Date(e.timestamp * 1000);
          return `${ed.getFullYear()}-${String(ed.getMonth() + 1).padStart(2, '0')}` === key;
        })
        .reduce((s, e) => s + e.contributions, 0);
      return { label, count };
    });
  }, [data]);

  const maxVal = Math.max(...months.map((m) => m.count), 1);

  return (
    <div className="min-w-0">
      <span className="text-[11px] font-semibold uppercase tracking-[.14em] text-slate-400 block mb-5">
        Monthly activity
      </span>
      <div className="relative h-24 flex items-end gap-1.5" aria-label="Monthly commit activity bar chart" role="img">
        {months.map((m, i) => {
          const pct = (m.count / maxVal) * 100;
          return (
            <div key={i} className="flex-1 flex flex-col items-center gap-1.5 min-w-0">
              <div className="w-full relative" style={{ height: '80px' }}>
                <div
                  className="absolute bottom-0 left-0 right-0 rounded-sm transition-all duration-300 ease-out bg-slate-900/10"
                  style={{
                    height: `${Math.max(pct, 2)}%`,
                    opacity: 0.18 + (pct / 100) * 0.55,
                  }}
                  title={`${m.label}: ${m.count} contributions`}
                />
              </div>
              <span className="text-[9px] text-slate-400 font-mono">{m.label}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ── Recent commits ──
function RecentCommits({ commits }: { commits: GiteaCommit[] }) {
  if (!commits.length) {
    return <p className="text-sm text-slate-500 py-4">No recent commits.</p>;
  }

  return (
    <div className="min-w-0">
      <span className="text-[11px] font-semibold uppercase tracking-[.14em] text-slate-400 block mb-5">
        Recent commits
      </span>

      <ol className="grid gap-3" aria-label="Recent commit list">
        {commits.slice(0, 10).map((c) => {
          const sha = (c.sha || '').slice(0, 7);
          const msg = (c.commit?.message || '').split('\n')[0].slice(0, 72);
          const date = c.created || c.commit?.author?.date;

          return (
            <li
              key={c.sha}
              className="rounded-2xl border border-slate-200/80 bg-white/55 px-4 py-3 min-w-0"
            >
              <div className="flex items-start gap-3 min-w-0">
                <span className="mt-1.5 block w-2 h-2 rounded-full bg-slate-300 flex-shrink-0" aria-hidden="true" />
                <div className="min-w-0 flex-1">
                  <div className="flex items-baseline gap-2 mb-1 flex-wrap min-w-0">
                    <span className="text-[10px] font-semibold uppercase tracking-wider text-slate-400">
                      {c._repo}
                    </span>
                    <a
                      href={c._repoUrl ? `${c._repoUrl}/commit/${c.sha}` : '#'}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="font-mono text-[10px] text-slate-500 hover:text-slate-900 transition-colors px-1.5 py-0.5 rounded-md bg-slate-100 border border-slate-200"
                      aria-label={`View commit ${sha}`}
                    >
                      {sha}
                    </a>
                    <span className="text-[10px] text-slate-400 ml-auto">
                      {date ? timeAgo(date) : ''}
                    </span>
                  </div>
                  <p className="text-sm text-slate-700 truncate leading-snug">{msg}</p>
                </div>
              </div>
            </li>
          );
        })}
      </ol>
    </div>
  );
}

// ── Main section ──
export default function CommitSection() {
  const [repos, setRepos] = useState<GiteaRepo[]>([]);
  const [heatmap, setHeatmap] = useState<HeatmapEntry[]>([]);
  const [commits, setCommits] = useState<GiteaCommit[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    async function load() {
      try {
        const [r, h] = await Promise.all([getRepos(6), getHeatmap()]);
        setRepos(r);
        setHeatmap(h);
        const c = await getRecentCommits(r);
        setCommits(c);
      } catch (e: unknown) {
        const msg = e instanceof Error ? e.message : 'Unknown error';
        setError(msg);
      } finally {
        setLoading(false);
      }
    }
    load();
  }, []);

  const stats = useMemo(() => calcStats(heatmap), [heatmap]);

  return (
    <section id="activity" className="py-24 px-6" aria-labelledby="activity-heading">
      <div className="max-w-5xl mx-auto min-w-0">
        <h2
          id="activity-heading"
          className="text-[clamp(1.8rem,4vw,2.5rem)] font-black tracking-tight text-slate-900 mb-8"
        >
        </h2>

        <div className="relative glass rounded-[28px] p-5 sm:p-7 md:p-8 overflow-visible">
          <div className="relative grid gap-8 lg:grid-cols-[minmax(0,1.15fr)_minmax(0,0.85fr)]">
            {/* Left side */}
            <div className="min-w-0 grid gap-6">
              <div className="grid grid-cols-2 sm:grid-cols-4 gap-4 border-b border-slate-200/80 pb-6 min-w-0">
                <Stat
                  label="Contributions"
                  value={loading ? '—' : stats.total.toLocaleString()}
                  sub="this year"
                />
                <Stat
                  label="Current streak"
                  value={loading ? '—' : `${stats.currentStreak}d`}
                  sub="days"
                />
                <Stat
                  label="Longest streak"
                  value={loading ? '—' : `${stats.longestStreak}d`}
                  sub="days"
                />
                <Stat
                  label="Active days"
                  value={loading ? '—' : stats.activeDays}
                  sub="this year"
                />
              </div>

              <div className="min-w-0">
                {loading ? (
                  <div className="flex flex-col gap-3">
                    <div className="skel h-3 w-48" />
                    <div className="skel h-[120px] w-full rounded-xl" />
                  </div>
                ) : error ? (
                  <div className="py-6">
                    <p className="text-slate-500 text-sm">Could not load heatmap</p>
                    <p className="text-slate-400 text-xs font-mono mt-1">{error}</p>
                  </div>
                ) : (
                  <ContributionCalendar data={heatmap} />
                )}
              </div>
            </div>

            {/* Right side */}
            <div className="min-w-0 grid gap-6 lg:border-l lg:border-slate-200/80 lg:pl-8">
              <div className="min-w-0">
                {loading ? (
                  <div className="skel h-32 w-full rounded-xl" />
                ) : (
                  <MonthlyChart data={heatmap} />
                )}
              </div>

              <div className="min-w-0">
                {loading ? (
                  <div className="flex flex-col gap-4">
                    {[...Array(5)].map((_, i) => (
                      <div key={i} className="flex gap-3">
                        <div className="skel w-2 h-2 rounded-full mt-1.5 flex-shrink-0" />
                        <div className="flex-1 min-w-0">
                          <div className="skel h-2.5 w-1/3 mb-1.5" />
                          <div className="skel h-3.5 w-5/6" />
                        </div>
                      </div>
                    ))}
                  </div>
                ) : (
                  <RecentCommits commits={commits} />
                )}
              </div>

              {!!repos.length && (
                <div className="pt-2 border-t border-slate-200/80 min-w-0">
                  <span className="text-[11px] font-semibold uppercase tracking-[.14em] text-slate-400 block mb-4">
                    Projects
                  </span>
                  <div className="grid grid-cols-2 sm:grid-cols-3 gap-2.5 min-w-0">
                    {repos.slice(0, 6).map((repo) => (
                      <a
                        key={repo.id ?? repo.name}
                        href={repo.html_url || repo.website || '#'}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="rounded-2xl border border-slate-200/80 bg-white/50 px-3 py-3 text-sm text-slate-700 hover:text-slate-900 hover:border-slate-300 transition-colors min-w-0"
                      >
                        <span className="block truncate font-medium">{repo.name}</span>
                      </a>
                    ))}
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}
