(function() {
  var template = document.getElementById('board-card-template');
  var addCardButtons = document.querySelectorAll('.board-column-add-card');

  var ICONS_BASE = '/static/icons/';
  var ICON_LIST = ['cloud.svg', 'cloud-filled.svg', 'cloud-storm.svg', 'cloud-down.svg', 'cloud-up.svg', 'cloud-exclamation.svg'];

  function preloadIcons() {
    ICON_LIST.forEach(function(name) {
      var img = new Image();
      img.src = ICONS_BASE + name;
    });
  }

  function setCardIcon(card, iconName) {
    var icon = card && card.querySelector && card.querySelector('.board-card-icon');
    if (icon) icon.setAttribute('data-icon', iconName);
  }

  function assignCloudIconToCard(card) {
    setCardIcon(card, 'cloud');
  }

  function assignCloudIconToAllCards() {
    document.querySelectorAll('.board-card').forEach(assignCloudIconToCard);
  }

  preloadIcons();
  function initBoard() {
    assignCloudIconToAllCards();
    loadTasksForBoard();
  }
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initBoard);
  } else {
    initBoard();
  }

  function getBoardContext() {
    var boardColumns = document.querySelector('.board-columns');
    var project = boardColumns && boardColumns.dataset.project;
    var board = boardColumns && boardColumns.dataset.board;
    if (!project && location.pathname) {
      var m = location.pathname.match(/^\/project\/(.+?)\/board\/?$/);
      if (m) project = m[1];
    }
    if (!board) board = (new URLSearchParams(location.search)).get('b') || 'Tasks';
    return { project: project || '', board: board || 'Tasks' };
  }

  function createCardFromTask(task) {
    if (!template || !template.content) return null;
    var clone = template.content.cloneNode(true);
    var card = clone.querySelector && clone.querySelector('.board-card');
    if (!card) return null;
    var status = task.status || 'TODO';
    card.dataset.taskRef = task.ref || '';
    card.dataset.taskStatus = status;
    var titleEl = card.querySelector('.board-card-title');
    if (titleEl) titleEl.textContent = task.title || 'Untitled';
    var descEl = card.querySelector('.board-card-description');
    if (descEl) descEl.textContent = task.description || '';
    setCardIcon(card, 'cloud-filled');
    var meta = card.querySelector('.board-card-meta');
    if (meta) {
      var badge = meta.querySelector('.badge');
      var assigneeSpan = meta.querySelectorAll('.text-truncate')[0];
      var commentsSpan = meta.querySelector('.ms-auto');
      if (badge) {
        badge.textContent = task.priority || 'LOW';
        badge.className = 'badge badge-outline text-' + (task.priority === 'CRITICAL' ? 'danger' : task.priority === 'HIGH' ? 'warning' : 'secondary');
      }
      if (assigneeSpan) assigneeSpan.textContent = task.assignee || 'None';
      if (commentsSpan) commentsSpan.textContent = (task.comments_count || 0) + ' comment' + ((task.comments_count || 0) !== 1 ? 's' : '');
    }
    var details = card.querySelector('.board-card-details');
    if (details) {
      var fullDesc = details.querySelector('.board-card-description-full');
      var dueDate = details.querySelector('.board-card-due-date');
      var updatedAt = details.querySelector('.board-card-updated-at');
      var statusEl = details.querySelector('.board-card-status');
      var priorityEl = details.querySelector('.board-card-priority');
      var assigneeEl = details.querySelector('.board-card-assignee');
      var commentsCountEl = details.querySelector('.board-card-comments-count');
      if (fullDesc) fullDesc.textContent = task.description || '';
      if (dueDate) dueDate.textContent = task.due_date || 'None';
      if (updatedAt) updatedAt.textContent = task.updated_at || 'None';
      if (statusEl) statusEl.textContent = status;
      if (priorityEl) priorityEl.textContent = task.priority || 'LOW';
      if (assigneeEl) assigneeEl.textContent = task.assignee || 'None';
      if (commentsCountEl) commentsCountEl.textContent = (task.comments_count || 0) + ' comment' + ((task.comments_count || 0) !== 1 ? 's' : '');
    }
    return clone;
  }

  function loadTasksForBoard() {
    var ctx = getBoardContext();
    if (!ctx.project) return;
    var listUrl = '/tasks/list?' + new URLSearchParams({ project: ctx.project, board: ctx.board }).toString();
    fetch(listUrl).then(function(res) {
      if (!res.ok) return;
      return res.json();
    }).then(function(tasks) {
      if (!Array.isArray(tasks)) return;
      var byStatus = {};
      tasks.forEach(function(task) {
        var s = task.status || 'TODO';
        if (!byStatus[s]) byStatus[s] = [];
        byStatus[s].push(task);
      });
      var columns = document.querySelectorAll('.board-column.dropzone');
      columns.forEach(function(column) {
        var status = column.dataset.status || 'TODO';
        var cardsContainer = column.querySelector('.board-column-cards');
        if (!cardsContainer) return;
        cardsContainer.innerHTML = '';
        (byStatus[status] || []).forEach(function(task) {
          var frag = createCardFromTask(task);
          if (frag) cardsContainer.appendChild(frag);
        });
        updateColumnBadge(column);
      });
    }).catch(function() {});
  }

  function addDefaultCard(ev) {
    if (!template || !template.content) return;
    var column = ev.currentTarget.closest('.board-column');
    var cardsContainer = column && column.querySelector('.board-column-cards');
    var boardColumns = document.querySelector('.board-columns');
    if (!cardsContainer || !boardColumns) return;
    var ctx = getBoardContext();
    var project = ctx.project;
    var board = ctx.board;
    if (!project) return;
    var clone = template.content.cloneNode(true);
    var card = clone.querySelector && clone.querySelector('.board-card');
    if (!card) return;
    var titleEl = card.querySelector('.board-card-title');
    if (titleEl) titleEl.textContent = 'New task';
    assignCloudIconToCard(card);
    cardsContainer.appendChild(clone);
    var badge = column.querySelector('.board-column-add-card');
    if (badge) {
      badge.textContent = cardsContainer.querySelectorAll('.board-card').length;
    }
    var status = column.dataset.status || 'TODO';
    setCardIcon(card, 'cloud-up');
    var createUrl = '/tasks/create?' + new URLSearchParams({
      project: project,
      board: board,
      title: 'New task',
      description: '',
      status: status,
      priority: 'LOW',
      assignee: '',
      due_date: ''
    }).toString();
    fetch(createUrl, { method: 'POST' }).then(function(res) {
      if (res.ok) {
        return res.json().then(function(body) {
          setCardIcon(card, 'cloud-filled');
          if (body.ref) card.dataset.taskRef = body.ref;
        });
      }
      if (res.status >= 400 && res.status < 600) {
        setCardIcon(card, 'cloud-exclamation');
      }
    }).catch(function() {
      setCardIcon(card, 'cloud-exclamation');
    });
  }

  addCardButtons.forEach(function(btn) {
    btn.addEventListener('click', addDefaultCard);
  });

  var boardColumns = document.querySelector('.board-columns');
  var dropzones = document.querySelectorAll('.board-column.dropzone');
  var draggedCard = null;
  var didDrag = false;

  function updateColumnBadge(column) {
    var cardsContainer = column && column.querySelector('.board-column-cards');
    var badge = column && column.querySelector('.board-column-add-card');
    if (badge && cardsContainer) {
      badge.textContent = cardsContainer.querySelectorAll('.board-card').length;
    }
  }

  function handleDragStart(e) {
    var card = e.target.closest && e.target.closest('.board-card');
    if (!card) return;
    didDrag = true;
    draggedCard = card;
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', card.dataset.taskRef || '');
    card.classList.add('opacity-50');
  }
  function handleDragEnd(e) {
    var card = e.target.closest && e.target.closest('.board-card');
    if (card) card.classList.remove('opacity-50');
    draggedCard = null;
    setTimeout(function() { didDrag = false; }, 0);
  }

  /** Parse display date text to YYYY-MM-DD for input[type=date]. Returns '' if none. */
  function parseDateForInput(text) {
    if (!text || text.trim() === 'None') return '';
    var s = text.trim();
    var m = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
    return m ? m[0] : '';
  }

  function setupPopoutEditables(popoutCard) {
    var titleEl = popoutCard.querySelector('.board-card-title');
    var descEl = popoutCard.querySelector('.board-card-description-full');
    var dueEl = popoutCard.querySelector('.board-card-due-date');
    var statusEl = popoutCard.querySelector('.board-card-status');
    var priorityEl = popoutCard.querySelector('.board-card-priority');

    function pushTaskUpdate() {
      var taskRef = popoutCard.dataset.taskRef;
      if (!taskRef) return;
      var ctx = getBoardContext();
      if (!ctx.project) return;
      var tEl = popoutCard.querySelector('.board-card-title');
      var dEl = popoutCard.querySelector('.board-card-description-full');
      var dueEl_ = popoutCard.querySelector('.board-card-due-date');
      var sEl = popoutCard.querySelector('.board-card-status');
      var pEl = popoutCard.querySelector('.board-card-priority');
      var aEl = popoutCard.querySelector('.board-card-assignee');
      var dueVal = (dueEl_ && dueEl_.textContent) ? dueEl_.textContent.trim() : '';
      var statusDisplay = (sEl && sEl.textContent) ? sEl.textContent.trim() : 'TODO';
      var priorityDisplay = (pEl && pEl.textContent) ? pEl.textContent.trim() : 'LOW';
      var body = {
        title: (tEl && tEl.textContent) ? tEl.textContent.trim() || 'Untitled' : 'Untitled',
        description: (dEl && dEl.textContent) ? dEl.textContent.trim() : '',
        status: statusDisplay ? statusDisplay.replace(/\s+/g, '_').toUpperCase() : 'TODO',
        priority: priorityDisplay ? priorityDisplay.replace(/\s+/g, '_').toUpperCase() : 'LOW',
        assignee: (aEl && aEl.textContent && aEl.textContent.trim() !== 'None') ? aEl.textContent.trim() : null,
        due_date: (dueVal && dueVal !== 'None') ? dueVal : null
      };
      fetch('/tasks/update?' + new URLSearchParams({ project: ctx.project, board: ctx.board, task: taskRef }).toString(), {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      }).catch(function() {});
    }

    if (titleEl) titleEl.classList.add('board-card-editable');
    function commitTitle() {
      var input = popoutCard.querySelector('.board-card-title-edit');
      if (!input) return;
      var val = (input.value || '').trim() || 'Untitled';
      titleEl.textContent = val;
      titleEl.classList.remove('d-none');
      input.remove();
      pushTaskUpdate();
    }
    if (titleEl) {
      titleEl.addEventListener('click', function () {
        if (popoutCard.querySelector('.board-card-title-edit')) return;
        var val = (titleEl.textContent || '').trim();
        var input = document.createElement('input');
        input.type = 'text';
        input.className = 'form-control form-control-sm board-card-title-edit';
        input.value = val;
        titleEl.classList.add('d-none');
        titleEl.parentNode.insertBefore(input, titleEl);
        input.focus();
        input.addEventListener('blur', commitTitle);
        input.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); input.blur(); } });
      });
    }

    function commitDescription() {
      var textarea = popoutCard.querySelector('.board-card-description-edit');
      if (!textarea) return;
      var val = (textarea.value || '').trim();
      descEl.textContent = val || '';
      descEl.classList.remove('d-none');
      textarea.remove();
      pushTaskUpdate();
    }
    if (descEl) {
      descEl.addEventListener('click', function () {
        if (popoutCard.querySelector('.board-card-description-edit')) return;
        var val = (descEl.textContent || '').trim();
        var textarea = document.createElement('textarea');
        textarea.className = 'form-control form-control-sm board-card-description-edit mt-1';
        textarea.rows = 3;
        textarea.value = val;
        descEl.classList.add('d-none');
        descEl.parentNode.insertBefore(textarea, descEl);
        textarea.focus();
        textarea.addEventListener('blur', commitDescription);
      });
    }

    function commitDueDate() {
      var input = popoutCard.querySelector('.board-card-due-date-edit');
      if (!input) return;
      var val = (input.value || '').trim();
      dueEl.textContent = val || 'None';
      dueEl.classList.remove('d-none');
      input.remove();
      pushTaskUpdate();
    }
    if (dueEl) {
      dueEl.addEventListener('click', function () {
        if (popoutCard.querySelector('.board-card-due-date-edit')) return;
        var val = parseDateForInput(dueEl.textContent);
        var input = document.createElement('input');
        input.type = 'date';
        input.className = 'form-control form-control-sm board-card-due-date-edit mt-1';
        input.value = val;
        dueEl.classList.add('d-none');
        dueEl.parentNode.insertBefore(input, dueEl);
        input.focus();
        input.addEventListener('blur', commitDueDate);
      });
    }

    function commitStatus() {
      var sel = popoutCard.querySelector('.board-card-status-edit');
      if (!sel) return;
      var display = (sel.options[sel.selectedIndex] && sel.options[sel.selectedIndex].text) ? sel.options[sel.selectedIndex].text : (sel.value || 'TODO');
      statusEl.textContent = display || 'TODO';
      statusEl.classList.remove('d-none');
      sel.remove();
      var statusValue = display ? display.replace(/\s+/g, '_').toUpperCase() : 'TODO';
      popoutCard.dataset.taskStatus = statusValue;
      pushTaskUpdate();
    }
    if (statusEl) {
      statusEl.addEventListener('click', function () {
        if (popoutCard.querySelector('.board-card-status-edit')) return;
        var current = (statusEl.textContent || '').trim() || 'TODO';
        var sel = document.createElement('select');
        sel.className = 'form-select form-select-sm board-card-status-edit mt-1';
        sel.innerHTML = '';
        var opt = document.createElement('option');
        opt.value = current;
        opt.textContent = current;
        opt.selected = true;
        sel.appendChild(opt);
        statusEl.classList.add('d-none');
        statusEl.parentNode.insertBefore(sel, statusEl);
        sel.focus();
        sel.addEventListener('blur', commitStatus);
        sel.addEventListener('change', commitStatus);
      });
    }

    function commitPriority() {
      var sel = popoutCard.querySelector('.board-card-priority-edit');
      if (!sel) return;
      var display = (sel.options[sel.selectedIndex] && sel.options[sel.selectedIndex].text) ? sel.options[sel.selectedIndex].text : (sel.value || 'LOW');
      priorityEl.textContent = display || 'LOW';
      priorityEl.classList.remove('d-none');
      sel.remove();
      pushTaskUpdate();
    }
    if (priorityEl) {
      priorityEl.addEventListener('click', function () {
        if (popoutCard.querySelector('.board-card-priority-edit')) return;
        var current = (priorityEl.textContent || '').trim() || 'LOW';
        var sel = document.createElement('select');
        sel.className = 'form-select form-select-sm board-card-priority-edit mt-1';
        sel.innerHTML = '';
        var opt = document.createElement('option');
        opt.value = current;
        opt.textContent = current;
        opt.selected = true;
        sel.appendChild(opt);
        priorityEl.classList.add('d-none');
        priorityEl.parentNode.insertBefore(sel, priorityEl);
        sel.focus();
        sel.addEventListener('blur', commitPriority);
        sel.addEventListener('change', commitPriority);
      });
    }
  }

  function showCardPopout(card) {
    var cardsContainer = card.parentNode;
    var nextSibling = card.nextSibling;
    card.classList.add('board-card-popout');
    card.draggable = false;
    card.removeAttribute('draggable');
    var details = card.querySelector('.board-card-details');
    if (details) details.classList.remove('d-none');
    setupPopoutEditables(card);
    var overlay = document.createElement('div');
    overlay.className = 'board-card-popout-overlay';
    overlay.appendChild(card);
    function close() {
      overlay.removeEventListener('click', closeOnBackdrop);
      document.body.removeChild(overlay);
      card.classList.remove('board-card-popout');
      card.setAttribute('draggable', 'true');
      card.draggable = true;
      if (details) details.classList.add('d-none');
      if (nextSibling) {
        cardsContainer.insertBefore(card, nextSibling);
      } else {
        cardsContainer.appendChild(card);
      }
      updateColumnBadge(cardsContainer.closest('.board-column'));
    }
    function closeOnBackdrop(e) {
      if (e.target === overlay) close();
    }
    overlay.addEventListener('click', closeOnBackdrop);
    document.body.appendChild(overlay);
    updateColumnBadge(cardsContainer.closest('.board-column'));
  }

  function handleCardClick(e) {
    if (didDrag) return;
    var card = e.target.closest && e.target.closest('.board-card');
    if (!card || card.classList.contains('board-card-popout')) return;
    e.preventDefault();
    showCardPopout(card);
  }

  function handleDragOver(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    e.currentTarget.classList.add('border-primary');
  }
  function handleDragLeave(e) {
    e.currentTarget.classList.remove('border-primary');
  }
  function pushTaskStatusUpdate(card, newStatus) {
    var taskRef = card && card.dataset.taskRef;
    if (!taskRef) return;
    var ctx = getBoardContext();
    if (!ctx.project) return;
    fetch('/tasks/update?' + new URLSearchParams({ project: ctx.project, board: ctx.board, task: taskRef }).toString(), {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ status: newStatus || 'TODO' })
    }).catch(function() {});
  }

  function handleDrop(e) {
    e.preventDefault();
    e.currentTarget.classList.remove('border-primary');
    if (!draggedCard) return;
    var targetColumn = e.currentTarget.closest && e.currentTarget.closest('.board-column');
    var targetCards = targetColumn && targetColumn.querySelector('.board-column-cards');
    if (!targetCards) return;
    var sourceColumn = draggedCard.closest && draggedCard.closest('.board-column');
    if (sourceColumn === targetColumn) return;
    var newStatus = targetColumn.dataset.status || 'TODO';
    draggedCard.dataset.taskStatus = newStatus;
    targetCards.appendChild(draggedCard);
    updateColumnBadge(sourceColumn);
    updateColumnBadge(targetColumn);
    pushTaskStatusUpdate(draggedCard, newStatus);
  }

  if (boardColumns) {
    boardColumns.addEventListener('dragstart', handleDragStart);
    boardColumns.addEventListener('dragend', handleDragEnd);
    boardColumns.addEventListener('click', handleCardClick);
  }
  dropzones.forEach(function(el) {
    el.addEventListener('dragover', handleDragOver);
    el.addEventListener('dragleave', handleDragLeave);
    el.addEventListener('drop', handleDrop);
  });
})();