---
import PhotosSubNav from "@/components/PhotosSubNav.astro";
import BaseLayout from "@/layouts/BaseLayout.astro";

type PhotoSidecar = {
  id: string;
  exif: {
    camera: string;
    lens: string;
    aperture: string;
    iso: string;
    focal_length: string;
    shutter_speed: string;
  };
};

const sidecars = import.meta.glob<PhotoSidecar>(
  "/src/content/photos/collections/**/*.json",
  { eager: true },
);

function countBy(values: string[]): { labels: string[]; data: number[] } {
  const counts: Record<string, number> = {};
  for (const v of values) {
    counts[v] = (counts[v] ?? 0) + 1;
  }
  const labels = Object.keys(counts).sort(
    (a, b) => (counts[b] ?? 0) - (counts[a] ?? 0),
  );
  return { labels, data: labels.map((l) => counts[l] ?? 0) };
}

function bucket(
  values: number[],
  buckets: { label: string; min: number; max: number }[],
): { labels: string[]; data: number[] } {
  const counts: Record<string, number> = {};
  for (const b of buckets) counts[b.label] = 0;
  for (const v of values) {
    const b = buckets.find((b) => v >= b.min && v < b.max);
    if (b) counts[b.label] = (counts[b.label] ?? 0) + 1;
  }
  const labels = buckets.map((b) => b.label);
  return { labels, data: labels.map((l) => counts[l] ?? 0) };
}

function parseShutter(s: string): number {
  if (s.includes("/")) {
    const [num, den] = s.split("/").map(Number);
    return (num ?? 1) / (den ?? 1);
  }
  return Number(s) || 0;
}

const exifs = Object.values(sidecars)
  .map((s) => s.exif)
  .filter(Boolean);
const totalPhotos = exifs.length;

const camera = countBy(exifs.map((e) => e.camera ?? "Unknown"));
function normalizeLens(lens: string): string {
  return lens.replace(/^Fujifilm Fujinon /, "").trim();
}
const lens = countBy(exifs.map((e) => normalizeLens(e.lens ?? "Unknown")));

const apertures = exifs
  .map((e) => parseFloat(e.aperture))
  .filter((n) => !isNaN(n));
const apertureUnique = [...new Set(apertures)].sort((a, b) => a - b);
const apertureCounts: Record<string, number> = {};
for (const v of apertures) {
  const k = `f/${v}`;
  apertureCounts[k] = (apertureCounts[k] ?? 0) + 1;
}
const aperture = {
  labels: apertureUnique.map((v) => `f/${v}`),
  data: apertureUnique.map((v) => apertureCounts[`f/${v}`] ?? 0),
};

const isoBuckets = [
  { label: "≤ 200", min: 0, max: 201 },
  { label: "400", min: 201, max: 600 },
  { label: "800", min: 600, max: 1200 },
  { label: "1600", min: 1200, max: 2400 },
  { label: "3200", min: 2400, max: 4800 },
  { label: "≥ 6400", min: 4800, max: Infinity },
];
const iso = bucket(
  exifs.map((e) => parseInt(e.iso)).filter((n) => !isNaN(n)),
  isoBuckets,
);

const focalBuckets = [
  { label: "≤ 24mm", min: 0, max: 25 },
  { label: "25–35mm", min: 25, max: 36 },
  { label: "36–50mm", min: 36, max: 51 },
  { label: "51–85mm", min: 51, max: 86 },
  { label: "86–135mm", min: 86, max: 136 },
  { label: "> 135mm", min: 136, max: Infinity },
];
const focal = bucket(
  exifs.map((e) => parseFloat(e.focal_length)).filter((n) => !isNaN(n)),
  focalBuckets,
);

const shutterBuckets = [
  { label: "≥ 1s", min: 1, max: Infinity },
  { label: "1/2 – 1s", min: 0.5, max: 1 },
  { label: "1/30 – 1/2", min: 1 / 30, max: 0.5 },
  { label: "1/125 – 1/30", min: 1 / 125, max: 1 / 30 },
  { label: "1/500 – 1/125", min: 1 / 500, max: 1 / 125 },
  { label: "< 1/500", min: 0, max: 1 / 500 },
];
const shutter = bucket(
  exifs.map((e) => parseShutter(e.shutter_speed)).filter((n) => n > 0),
  shutterBuckets,
);

const metrics = JSON.stringify({ camera, lens, aperture, iso, focal, shutter });
---

<BaseLayout
  title="Photo Stats"
  description="Metrics and statistics from my photo collection."
  navDesktopHidden={true}
  footerDark={true}
>
  <div class="page">
    <main class="main">
      <PhotosSubNav />

      <div class="stats-content" data-metrics={metrics}>
        <p class="total">{totalPhotos} photos total</p>

        <div class="chart-grid chart-grid--top">
          <section class="chart-section">
            <h2 class="section-title">Camera</h2>
            <div class="chart-wrap chart-wrap--tall">
              <canvas id="chart-camera" aria-label="Photos per camera"></canvas>
            </div>
          </section>

          <section class="chart-section">
            <h2 class="section-title">Lens</h2>
            <div class="chart-wrap chart-wrap--tall">
              <canvas id="chart-lens" aria-label="Photos per lens"></canvas>
            </div>
          </section>
        </div>

        <div class="chart-grid">
          <section class="chart-section">
            <h2 class="section-title">Aperture</h2>
            <div class="chart-wrap">
              <canvas id="chart-aperture" aria-label="Aperture distribution"></canvas>
            </div>
          </section>

          <section class="chart-section">
            <h2 class="section-title">ISO</h2>
            <div class="chart-wrap">
              <canvas id="chart-iso" aria-label="ISO distribution"></canvas>
            </div>
          </section>

          <section class="chart-section">
            <h2 class="section-title">Focal Length</h2>
            <div class="chart-wrap">
              <canvas id="chart-focal" aria-label="Focal length distribution"></canvas>
            </div>
          </section>

          <section class="chart-section">
            <h2 class="section-title">Shutter Speed</h2>
            <div class="chart-wrap">
              <canvas id="chart-shutter" aria-label="Shutter speed distribution"></canvas>
            </div>
          </section>
        </div>
      </div>
    </main>
  </div>
</BaseLayout>

<script>
  import Chart from "chart.js/auto";

  const container = document.querySelector<HTMLElement>(".stats-content");
  if (!container) throw new Error("No stats container");

  const metrics = JSON.parse(container.dataset.metrics ?? "{}");

  function neon(hex: string, alpha = 0.25) {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `rgba(${r},${g},${b},${alpha})`;
  }

  const COLORS = ["#39ff14", "#ff2d78", "#00e5ff", "#ffaa00", "#bf00ff", "#ff6b00"];

  function makeChart(
    id: string,
    labels: string[],
    data: number[],
    horizontal = false,
    colorIndex = 0,
  ) {
    const hex = COLORS[colorIndex % COLORS.length] ?? "#ffffff";
    const canvas = document.getElementById(id) as HTMLCanvasElement | null;
    if (!canvas) return;
    if (horizontal) {
      const wrap = canvas.parentElement as HTMLElement | null;
      if (wrap) wrap.style.height = `${labels.length * 44 + 40}px`;
    }
    new Chart(canvas, {
      type: "bar",
      data: {
        labels,
        datasets: [
          {
            label: "Photos",
            data,
            backgroundColor: neon(hex, 0.2),
            borderColor: neon(hex, 0.9),
            borderWidth: 1,
            borderRadius: 2,
          },
        ],
      },
      options: {
        indexAxis: horizontal ? "y" : "x",
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          legend: { display: false },
          tooltip: {
            callbacks: { label: (ctx) => ` ${horizontal ? ctx.parsed.x : ctx.parsed.y} photos` },
          },
        },
        scales: {
          x: {
            ticks: { color: "#999", font: { size: 11 } },
            grid: { color: horizontal ? "rgba(255,255,255,0.06)" : "none" },
            border: { color: "rgba(255,255,255,0.1)" },
          },
          y: {
            ticks: { color: "#f5f5f3", font: { size: 12 } },
            grid: { color: horizontal ? "none" : "rgba(255,255,255,0.06)" },
            border: { color: "rgba(255,255,255,0.1)" },
          },
        },
      },
    });
  }

  makeChart("chart-camera",  metrics.camera.labels,  metrics.camera.data,  true, 0);
  makeChart("chart-lens",    metrics.lens.labels,    metrics.lens.data,    true, 1);
  makeChart("chart-aperture",metrics.aperture.labels,metrics.aperture.data,false,2);
  makeChart("chart-iso",     metrics.iso.labels,     metrics.iso.data,     false,3);
  makeChart("chart-focal",   metrics.focal.labels,   metrics.focal.data,   false,4);
  makeChart("chart-shutter", metrics.shutter.labels, metrics.shutter.data, false,5);
</script>

<style>
  .page {
    display: grid;
    grid-template-rows: auto 1fr auto;
    min-height: 100dvh;
    background: #111;
    color: #f5f5f3;
  }

  .main {
    max-width: var(--width-wide);
    margin: 0 auto;
    padding: 1.5rem;
    width: 100%;
  }

  .stats-content {
    padding-top: 1rem;
  }

  .total {
    font-size: 0.85rem;
    color: #555;
    margin: 0 0 2rem;
  }

  .section-title {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #666;
    margin: 0 0 0.75rem;
  }

  .chart-section {
    margin-bottom: 2.5rem;
  }

  .chart-wrap {
    position: relative;
    height: 220px;
  }

  .chart-wrap--tall {
    height: 140px;
  }

  .chart-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem 3rem;
  }

  .chart-grid--top {
    margin-bottom: 2.5rem;
  }

  @media (max-width: 640px) {
    .chart-grid {
      grid-template-columns: 1fr;
    }
  }

  .page :global(.nav),
  .page :global(.mobile-bar) {
    background: #111;
    color: #000;
  }

  .page :global(.nav a),
  .page :global(.nav__icon-btn) {
    color: #000;
  }

  .page :global(.footer a) {
    color: #f5f5f3;
  }
</style>
