"use client";

import { cn } from "@/shared/lib/utils";
import { useT } from "@/shared/i18n/client";

export interface HBarItem {
  key: string;
  label: string;
  value: number; // 0..100 for the bar width
  display?: string; // right-hand value text (defaults to `${value}%`)
  color?: string; // bar colour (defaults to primary)
  dim?: boolean;
  rank?: number;
}

/** Ranked horizontal bar list (module utilization, adoption ranking, score breakdown). */
export function HBarList({ items, className }: { items: HBarItem[]; className?: string }) {
  return (
    <div className={cn("space-y-2.5", className)}>
      {items.map((it) => (
        <div key={it.key} className={cn("flex items-center gap-3", it.dim && "opacity-40")}>
          {it.rank !== undefined && (
            <span className="w-5 text-right text-xs font-mono text-muted-foreground">{it.rank}</span>
          )}
          <span className="w-40 shrink-0 truncate text-sm">{it.label}</span>
          <div className="flex-1 h-2 rounded-full bg-muted overflow-hidden">
            <div
              className="h-full rounded-full transition-all"
              style={{
                width: `${Math.max(0, Math.min(100, it.value))}%`,
                backgroundColor: it.color ?? "var(--chart-1)",
              }}
            />
          </div>
          <span className="w-12 text-right text-xs font-mono font-medium tabular-nums">
            {it.display ?? `${Math.round(it.value)}%`}
          </span>
        </div>
      ))}
    </div>
  );
}

/**
 * Activity heatmap card content: Low→High legend, the 7×24 matrix, and the
 * by-hour / by-weekday marginal bars (spec: "BY HOUR OF DAY" / "BY DAY OF WEEK").
 */
export function ActivityHeatmap({
  matrix,
  byHour,
  byWeekday,
}: {
  matrix: number[][];
  byHour?: number[];
  byWeekday?: number[];
}) {
  const t = useT();
  const max = Math.max(1, ...matrix.flat());
  const hours = [0, 6, 12, 18, 23];
  const legendSteps = [0, 0.25, 0.5, 0.75, 1];

  return (
    <div className="space-y-4">
      {/* Low → High legend */}
      <div className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
        <span>{t.health.profile.low}</span>
        {legendSteps.map((o, i) => (
          <span
            key={i}
            className="w-3 h-3 rounded-[2px]"
            style={{
              backgroundColor: o === 0 ? "var(--muted)" : `color-mix(in oklch, var(--chart-1) ${Math.round(o * 100)}%, transparent)`,
            }}
          />
        ))}
        <span>{t.health.profile.high}</span>
      </div>

      <div className="overflow-x-auto">
        <div className="min-w-[560px]">
          <div className="flex">
            <div className="w-9" />
            <div className="flex-1 relative h-4">
              {hours.map((h) => (
                <span
                  key={h}
                  className="absolute text-[10px] text-muted-foreground -translate-x-1/2"
                  style={{ left: `${((h + 0.5) / 24) * 100}%` }}
                >
                  {String(h).padStart(2, "0")}
                </span>
              ))}
            </div>
          </div>
          {matrix.map((row, d) => (
            <div key={d} className="flex items-center gap-1 mb-1">
              <span className="w-9 text-[10px] text-muted-foreground">{t.health.weekdays[d]}</span>
              <div className="flex-1 grid gap-0.5" style={{ gridTemplateColumns: "repeat(24, minmax(0, 1fr))" }}>
                {row.map((v, h) => (
                  <div
                    key={h}
                    title={`${t.health.weekdays[d]} ${String(h).padStart(2, "0")}:00 · ${v}`}
                    className="aspect-square rounded-[2px]"
                    style={{
                      backgroundColor:
                        v > 0
                          ? `color-mix(in oklch, var(--chart-1) ${Math.round((v / max) * 100)}%, transparent)`
                          : "var(--muted)",
                    }}
                  />
                ))}
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Marginals */}
      {byHour && byWeekday && (
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          <MarginalBars title={t.health.profile.byHour} values={byHour} labels={["00:00", "06:00", "12:00", "18:00", "23:00"]} />
          <MarginalBars title={t.health.profile.byWeekday} values={byWeekday} labels={t.health.weekdays} labelEach />
        </div>
      )}
    </div>
  );
}

function MarginalBars({
  title,
  values,
  labels,
  labelEach = false,
}: {
  title: string;
  values: number[];
  labels: string[];
  labelEach?: boolean;
}) {
  const max = Math.max(1, ...values);
  return (
    <div>
      <p className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground mb-1.5">{title}</p>
      <div className="flex items-end gap-0.5 h-14">
        {values.map((v, i) => (
          <div
            key={i}
            title={String(v)}
            className="flex-1 rounded-t-[2px]"
            style={{
              height: `${Math.max(3, Math.round((v / max) * 100))}%`,
              backgroundColor: v > 0 ? "var(--chart-1)" : "var(--muted)",
            }}
          />
        ))}
      </div>
      <div className={labelEach ? "flex justify-between mt-1" : "relative mt-1 h-3"}>
        {labelEach
          ? labels.map((l) => (
              <span key={l} className="text-[9px] text-muted-foreground flex-1 text-center">{l}</span>
            ))
          : labels.map((l, i) => (
              <span
                key={l}
                className="absolute text-[9px] text-muted-foreground -translate-x-1/2"
                style={{ left: `${(i / (labels.length - 1)) * 100}%` }}
              >
                {l}
              </span>
            ))}
      </div>
    </div>
  );
}

/** GitHub-style contribution grid over the last ~12 months. */
export function ContributionGrid({ days }: { days: { date: string; count: number }[] }) {
  const t = useT();
  const map = new Map(days.map((d) => [d.date, d.count]));

  const nonZero = days.map((d) => d.count).filter((c) => c > 0).sort((a, b) => a - b);
  const q = (p: number) => (nonZero.length ? nonZero[Math.floor((nonZero.length - 1) * p)] : 0);
  const thresholds = [q(0.25), q(0.5), q(0.75)];
  const levelOf = (c: number) =>
    c <= 0 ? 0 : c <= thresholds[0] ? 1 : c <= thresholds[1] ? 2 : c <= thresholds[2] ? 3 : 4;
  const levelOpacity = [0, 0.25, 0.45, 0.7, 1];

  const fmt = (d: Date) =>
    `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;

  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const start = new Date(today);
  start.setDate(start.getDate() - 364);
  start.setDate(start.getDate() - ((start.getDay() + 6) % 7)); // back to Monday

  const weeks: { date: Date; count: number; inRange: boolean }[][] = [];
  const cur = new Date(start);
  while (cur <= today) {
    const week: { date: Date; count: number; inRange: boolean }[] = [];
    for (let d = 0; d < 7; d++) {
      const inRange = cur <= today;
      week.push({ date: new Date(cur), count: map.get(fmt(cur)) ?? 0, inRange });
      cur.setDate(cur.getDate() + 1);
    }
    weeks.push(week);
  }

  // Month label above the first week that enters a new month (GitHub-style).
  const monthLabels: (string | null)[] = weeks.map((week, wi) => {
    const m = week[0].date.getMonth();
    const prev = wi > 0 ? weeks[wi - 1][0].date.getMonth() : -1;
    return m !== prev
      ? week[0].date.toLocaleDateString(undefined, { month: "short" })
      : null;
  });

  return (
    <div className="space-y-2">
      <div className="overflow-x-auto">
        <div className="inline-block">
          {/* Month labels */}
          <div className="flex gap-[3px] ml-[26px] h-4">
            {weeks.map((_, wi) => (
              <span key={wi} className="w-[11px] text-[9px] text-muted-foreground whitespace-nowrap overflow-visible">
                {monthLabels[wi] ?? ""}
              </span>
            ))}
          </div>
          <div className="flex gap-[3px]">
            {/* Weekday labels (Mon / Wed / Fri, GitHub-style) */}
            <div className="flex flex-col gap-[3px] w-[23px]">
              {Array.from({ length: 7 }).map((_, di) => (
                <span key={di} className="h-[11px] text-[9px] leading-[11px] text-muted-foreground">
                  {di === 0 || di === 2 || di === 4 ? t.health.weekdays[di] : ""}
                </span>
              ))}
            </div>
            {weeks.map((week, wi) => (
              <div key={wi} className="flex flex-col gap-[3px]">
                {week.map((cell, di) => (
                  <div
                    key={di}
                    title={cell.inRange ? `${fmt(cell.date)} · ${cell.count}` : ""}
                    className="w-[11px] h-[11px] rounded-[2px]"
                    style={{
                      backgroundColor: !cell.inRange
                        ? "transparent"
                        : cell.count > 0
                        ? `color-mix(in oklch, var(--chart-1) ${Math.round(levelOpacity[levelOf(cell.count)] * 100)}%, transparent)`
                        : "var(--muted)",
                    }}
                  />
                ))}
              </div>
            ))}
          </div>
        </div>
      </div>
      <div className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
        <span>{t.health.profile.less}</span>
        {levelOpacity.map((o, i) => (
          <span
            key={i}
            className="w-[11px] h-[11px] rounded-[2px]"
            style={{ backgroundColor: o === 0 ? "var(--muted)" : `color-mix(in oklch, var(--chart-1) ${Math.round(o * 100)}%, transparent)` }}
          />
        ))}
        <span>{t.health.profile.more}</span>
      </div>
    </div>
  );
}
