const NAV_OFFSET = 120;
const DEFAULT_VISIBLE_PROJECTS = 9;
const INTERACTIVE_SELECTOR =
  'a, button, input, textarea, select, summary, [role="button"]';

initRevealOnScroll();
initActiveNavLink();
initProjectCardLinks();
initProjectFilters();

function initRevealOnScroll() {
  const revealTargets = document.querySelectorAll('.reveal');
  if (revealTargets.length === 0) {
    return;
  }

  const observer = new IntersectionObserver(
    (entries, currentObserver) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) {
          return;
        }

        entry.target.classList.add('visible');
        currentObserver.unobserve(entry.target);
      });
    },
    { threshold: 0.1, rootMargin: '0px 0px -40px 0px' }
  );

  revealTargets.forEach((target) => observer.observe(target));
}

function initActiveNavLink() {
  const sections = Array.from(document.querySelectorAll('section[id]'));
  const navLinks = Array.from(document.querySelectorAll('.nav-links a'));
  if (sections.length === 0 || navLinks.length === 0) {
    return;
  }

  const updateActiveNavLink = () => {
    let currentSectionId = '';

    sections.forEach((section) => {
      if (window.scrollY >= section.offsetTop - NAV_OFFSET) {
        currentSectionId = section.id;
      }
    });

    navLinks.forEach((link) => {
      link.classList.toggle(
        'is-active',
        link.getAttribute('href') === `#${currentSectionId}`
      );
    });
  };

  window.addEventListener('scroll', updateActiveNavLink, { passive: true });
  updateActiveNavLink();
}

function initProjectCardLinks() {
  const cardLinks = document.querySelectorAll('.card-link[data-href]');
  if (cardLinks.length === 0) {
    return;
  }

  cardLinks.forEach((card) => {
    card.setAttribute('role', 'link');
    card.setAttribute('tabindex', '0');

    card.addEventListener('click', (event) => {
      if (shouldIgnoreCardActivation(card, event.target)) {
        return;
      }

      navigateToCard(card, event);
    });

    card.addEventListener('keydown', (event) => {
      if (event.key !== 'Enter' && event.key !== ' ') {
        return;
      }

      if (shouldIgnoreCardActivation(card, event.target)) {
        return;
      }

      event.preventDefault();
      navigateToCard(card, event);
    });
  });
}

function shouldIgnoreCardActivation(card, target) {
  if (!(target instanceof Element)) {
    return false;
  }

  const interactiveAncestor = target.closest(INTERACTIVE_SELECTOR);
  return interactiveAncestor !== null && interactiveAncestor !== card;
}

function navigateToCard(card, event) {
  const href = card.dataset.href;
  if (!href) {
    return;
  }

  if (event.metaKey || event.ctrlKey || event.button === 1) {
    window.open(href, '_blank', 'noopener');
    return;
  }

  window.location.assign(href);
}

function initProjectFilters() {
  const filterChips = Array.from(document.querySelectorAll('.filter-chip'));
  const projectCards = Array.from(
    document.querySelectorAll('#project-grid .project-card')
  );
  if (filterChips.length === 0 || projectCards.length === 0) {
    return;
  }

  const seeMoreButton = document.querySelector('#projects-see-more');
  const techByCard = new Map(
    projectCards.map((card) => [
      card,
      (card.dataset.tech || '').split(/\s+/).filter(Boolean),
    ])
  );

  let selectedFilter = 'all';
  let isExpanded = false;

  const applyFilter = () => {
    let visibleCount = 0;

    projectCards.forEach((card) => {
      const tech = techByCard.get(card) || [];
      const matchesFilter =
        selectedFilter === 'all' || tech.includes(selectedFilter);

      card.classList.toggle('is-hidden', !matchesFilter);
      if (!matchesFilter) {
        card.classList.remove('is-collapsed');
        return;
      }

      const isCollapsed =
        !isExpanded && visibleCount >= DEFAULT_VISIBLE_PROJECTS;
      card.classList.toggle('is-collapsed', isCollapsed);
      visibleCount += 1;
    });

    if (!seeMoreButton) {
      return;
    }

    const canExpand = visibleCount > DEFAULT_VISIBLE_PROJECTS;
    seeMoreButton.hidden = !canExpand;
    seeMoreButton.setAttribute(
      'aria-expanded',
      canExpand && isExpanded ? 'true' : 'false'
    );
    seeMoreButton.textContent = isExpanded ? 'See less' : 'See more';
  };

  filterChips.forEach((chip) => {
    chip.addEventListener('click', () => {
      selectedFilter = chip.dataset.filter || 'all';
      isExpanded = false;

      filterChips.forEach((otherChip) => {
        otherChip.classList.toggle('active', otherChip === chip);
      });

      applyFilter();
    });
  });

  if (seeMoreButton) {
    seeMoreButton.addEventListener('click', () => {
      isExpanded = !isExpanded;
      applyFilter();
    });
  }

  applyFilter();
}
