(function () {
  'use strict';

  if (window._contribGraphLoaded) return;
  window._contribGraphLoaded = true;

  var MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

  var I18N = {
    en: {
      summary: function(t, g, h) { return t + ' commits in the last year \xb7 ' + g + ' from gitolite \xb7 ' + h + ' from GitHub'; },
      tooltip_gitolite: 'gitolite',
      tooltip_github: 'GitHub',
      tooltip_total: 'total',
    },
    it: {
      summary: function(t, g, h) { return t + ' commit nell’ultimo anno \xb7 ' + g + ' da gitolite \xb7 ' + h + ' da GitHub'; },
      tooltip_gitolite: 'gitolite',
      tooltip_github: 'GitHub',
      tooltip_total: 'totale',
    },
  };

  function level(count) {
    if (count === 0) return 0;
    if (count <= 3) return 0.35;
    if (count <= 9) return 0.60;
    if (count <= 19) return 0.80;
    return 1.0;
  }

  function hexWithOpacity(hex, opacity) {
    hex = hex.replace('#', '').trim();
    if (hex.length === 3) {
      hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
    }
    var r = parseInt(hex.substring(0, 2), 16);
    var g = parseInt(hex.substring(2, 4), 16);
    var b = parseInt(hex.substring(4, 6), 16);
    return 'rgba(' + r + ',' + g + ',' + b + ',' + opacity + ')';
  }

  function buildCellStyle(gitoliteCount, githubCount, rootStyle) {
    var gLevel = level(gitoliteCount);
    var hLevel = level(githubCount);

    if (gLevel === 0 && hLevel === 0) return '';

    var accent2 = rootStyle.getPropertyValue('--accent2').trim() || '#00ff88';
    var accent  = rootStyle.getPropertyValue('--accent').trim()  || '#a855f7';
    var border  = rootStyle.getPropertyValue('--border').trim()  || '#182840';

    var leftColor  = gLevel === 0 ? border : hexWithOpacity(accent2, gLevel);
    var rightColor = hLevel === 0 ? border : hexWithOpacity(accent, hLevel);

    return 'linear-gradient(90deg, ' + leftColor + ' 50%, ' + rightColor + ' 50%)';
  }

  function formatDate(dateStr) {
    // dateStr: "YYYY-MM-DD"
    var parts = dateStr.split('-');
    var d = new Date(parseInt(parts[0]), parseInt(parts[1]) - 1, parseInt(parts[2]));
    var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    var day = d.getDate();
    return months[d.getMonth()] + ' ' + day + ', ' + d.getFullYear();
  }

  function buildGraph(container, data) {
    var cellSize = parseInt(container.dataset.cellSize, 10) || 8;
    var lang = container.dataset.lang || 'en';
    var ariaLabel = container.dataset.ariaLabel || 'Contribution graph';
    var i18n = I18N[lang] || I18N.en;
    var gap = cellSize <= 6 ? 1 : 2;

    var rootStyle = getComputedStyle(document.documentElement);

    // Sort dates oldest → newest
    var dates = Object.keys(data).sort();

    // Build 53-col × 7-row grid
    // Find the day-of-week of the oldest date (Sun=0)
    var firstParts = dates[0].split('-');
    var firstDate = new Date(parseInt(firstParts[0]), parseInt(firstParts[1]) - 1, parseInt(firstParts[2]));
    var startDow = firstDate.getDay(); // 0=Sun

    // Assign each date to (col, row)
    // col 0 starts at row=startDow
    var cells = []; // { col, row, date, gitolite, github }
    for (var i = 0; i < dates.length; i++) {
      var slot = startDow + i;
      var col = Math.floor(slot / 7);
      var row = slot % 7;
      cells.push({ col: col, row: row, date: dates[i], gitolite: data[dates[i]].gitolite || 0, github: data[dates[i]].github || 0 });
    }

    var totalCols = cells[cells.length - 1].col + 1;

    // Month labels: track first col per month
    var monthCols = {}; // "YYYY-MM" → col index
    for (var j = 0; j < cells.length; j++) {
      var c = cells[j];
      var ym = c.date.substring(0, 7);
      if (!(ym in monthCols)) monthCols[ym] = c.col;
    }

    // Build figure
    var figure = document.createElement('figure');
    figure.setAttribute('role', 'img');
    figure.setAttribute('aria-label', ariaLabel);

    var wrap = document.createElement('div');
    wrap.className = 'contrib-graph-wrap';

    // Month label row
    var monthRow = document.createElement('div');
    monthRow.className = 'contrib-month-row';
    monthRow.style.setProperty('--contrib-cell-size', cellSize + 'px');
    monthRow.style.setProperty('--contrib-gap', gap + 'px');
    monthRow.style.gridTemplateColumns = 'repeat(' + totalCols + ', ' + cellSize + 'px)';

    var monthKeys = Object.keys(monthCols).sort();
    for (var m = 0; m < monthKeys.length; m++) {
      var ym2 = monthKeys[m];
      var colIdx = monthCols[ym2];
      var monthNum = parseInt(ym2.split('-')[1], 10) - 1;
      var span = document.createElement('span');
      span.className = 'contrib-month-label';
      span.textContent = MONTHS[monthNum];
      span.style.gridColumn = (colIdx + 1).toString();
      monthRow.appendChild(span);
    }

    // Graph grid
    var grid = document.createElement('div');
    grid.className = 'contrib-grid';
    grid.style.setProperty('--contrib-cell-size', cellSize + 'px');
    grid.style.setProperty('--contrib-gap', gap + 'px');
    grid.style.gridTemplateColumns = 'repeat(' + totalCols + ', ' + cellSize + 'px)';

    // Build a map of col+row → cell data for quick lookup
    var cellMap = {};
    for (var k = 0; k < cells.length; k++) {
      cellMap[cells[k].col + '_' + cells[k].row] = cells[k];
    }

    // Fill grid col by col, row by row
    for (var col2 = 0; col2 < totalCols; col2++) {
      for (var row2 = 0; row2 < 7; row2++) {
        var div = document.createElement('div');
        div.className = 'contrib-cell';
        var key = col2 + '_' + row2;
        var cellData = cellMap[key];
        if (cellData) {
          var bg = buildCellStyle(cellData.gitolite, cellData.github, rootStyle);
          if (bg) div.style.background = bg;
          var label = formatDate(cellData.date) + ': ' + cellData.gitolite + ' ' + i18n.tooltip_gitolite + ', ' + cellData.github + ' ' + i18n.tooltip_github;
          div.setAttribute('aria-label', label);
          div.dataset.gitolite = cellData.gitolite;
          div.dataset.github = cellData.github;
          div.dataset.date = cellData.date;
        }
        grid.appendChild(div);
      }
    }

    wrap.appendChild(monthRow);
    wrap.appendChild(grid);
    figure.appendChild(wrap);

    // Totals for summary
    var totalCommits = 0, totalGitolite = 0, totalGithub = 0;
    for (var n = 0; n < cells.length; n++) {
      totalGitolite += cells[n].gitolite;
      totalGithub += cells[n].github;
    }
    totalCommits = totalGitolite + totalGithub;

    // Summary figcaption
    var caption = document.createElement('figcaption');
    caption.className = 'contrib-summary';
    caption.textContent = i18n.summary(totalCommits, totalGitolite, totalGithub);
    figure.appendChild(caption);

    container.appendChild(figure);
    container.style.display = '';

    // Tooltip (inject once)
    var tooltip = document.querySelector('.contrib-tooltip');
    if (!tooltip) {
      tooltip = document.createElement('div');
      tooltip.className = 'contrib-tooltip';
      tooltip.setAttribute('aria-hidden', 'true');
      document.body.appendChild(tooltip);
    }

    // Event delegation on grid
    grid.addEventListener('mouseover', function(e) {
      var cell = e.target.closest('.contrib-cell');
      if (!cell || !cell.dataset.date) return;
      var g = parseInt(cell.dataset.gitolite, 10);
      var h = parseInt(cell.dataset.github, 10);
      tooltip.innerHTML =
        formatDate(cell.dataset.date) + '<br>' +
        i18n.tooltip_gitolite + ': ' + g + '<br>' +
        i18n.tooltip_github + ': ' + h + '<br>' +
        i18n.tooltip_total + ': ' + (g + h);
      tooltip.classList.add('visible');
    });

    grid.addEventListener('mousemove', function(e) {
      var x = e.clientX + 12;
      var y = e.clientY + 12;
      var tw = tooltip.offsetWidth;
      var th = tooltip.offsetHeight;
      if (x + tw > window.innerWidth - 8) x = e.clientX - tw - 12;
      if (y + th > window.innerHeight - 8) y = e.clientY - th - 12;
      tooltip.style.left = x + 'px';
      tooltip.style.top = y + 'px';
    });

    grid.addEventListener('mouseout', function(e) {
      if (!e.relatedTarget || !grid.contains(e.relatedTarget)) {
        tooltip.classList.remove('visible');
      }
    });
  }

  document.addEventListener('DOMContentLoaded', function() {
    var containers = document.querySelectorAll('.contrib-container');
    if (!containers.length) return;

    fetch('https://danix.xyz/contributions.json')
      .then(function(res) {
        if (!res.ok) throw new Error('fetch failed');
        return res.json();
      })
      .then(function(data) {
        containers.forEach(function(container) {
          buildGraph(container, data);
        });
      })
      .catch(function() {
        // hide silently — containers already display:none
      });
  });
}());
