<script>
  import type { GitHubRepoData, CachedRepoData, CardElements } from '@/types'

  let githubCardsObserver: IntersectionObserver | null = null

  // Retrieve cached GitHub repository data from localStorage with expiration check
  function getCachedData(repo: string): GitHubRepoData | null {
    try {
      const cacheKey = `github-repo-${repo}`
      const cached = localStorage.getItem(cacheKey)

      if (!cached) {
        return null
      }

      const parsedCache: CachedRepoData = JSON.parse(cached)
      const now = Date.now()
      const oneHour = 60 * 60 * 1000 // 1 hour in milliseconds

      // Check if cache is expired (older than 1 hour)
      if (now - parsedCache.timestamp > oneHour) {
        localStorage.removeItem(cacheKey)
        return null
      }

      return parsedCache.data
    } catch (error) {
      console.warn('Failed to read from cache:', error)
      return null
    }
  }

  // Store GitHub repository data in localStorage with timestamp for cache expiration
  function setCachedData(repo: string, data: GitHubRepoData): void {
    try {
      const cacheKey = `github-repo-${repo}`
      const cacheData: CachedRepoData = {
        data,
        timestamp: Date.now()
      }
      localStorage.setItem(cacheKey, JSON.stringify(cacheData))
    } catch (error) {
      console.warn('Failed to save to cache:', error)
    }
  }

  // Update the GitHub card UI elements with fetched repository data
  function updateCardUI(el: CardElements, data: GitHubRepoData) {
    const numberFormat = new Intl.NumberFormat('en', {
      notation: 'compact',
      maximumFractionDigits: 1
    })

    if (el.avatar && data.owner?.avatar_url) {
      el.avatar.style.backgroundImage = `url(${data.owner.avatar_url})`
    }

    if (el.desc) {
      el.desc.textContent = data.description ?? 'No description'
    }

    if (el.stars) {
      el.stars.textContent = numberFormat.format(data.stargazers_count ?? 0)
    }

    if (el.forks) {
      el.forks.textContent = numberFormat.format(data.forks_count ?? 0)
    }

    if (el.license) {
      el.license.textContent = data.license?.spdx_id ?? 'No License'
    }
  }

  // Load GitHub repository data for a card, using cache if available or fetching from API
  async function loadCardData(card: HTMLElement) {
    const repo = card.dataset.repo
    if (!repo) {
      return
    }

    const el = {
      avatar: card.querySelector('.gc-owner-avatar') as HTMLElement,
      desc: card.querySelector('.gc-repo-description') as HTMLElement,
      stars: card.querySelector('.gc-stars-count') as HTMLElement,
      forks: card.querySelector('.gc-forks-count') as HTMLElement,
      license: card.querySelector('.gc-license-info') as HTMLElement
    } as const

    // Try to get cached data first
    const cachedData = getCachedData(repo)
    if (cachedData) {
      updateCardUI(el, cachedData)
      return
    }

    // If no cache, fetch from API
    try {
      const response = await fetch(`https://api.github.com/repos/${repo}`)

      if (!response.ok) {
        if (el.desc) {
          el.desc.textContent = '⚠ Loading failed'
        }
        return
      }

      const data = await response.json()

      setCachedData(repo, data)

      updateCardUI(el, data)
    } catch (error) {
      console.error(`Failed to fetch ${repo}:`, error)
      if (el.desc) {
        el.desc.textContent = '⚠ Loading failed'
      }
    }
  }

  // Set up intersection observer for lazy loading GitHub cards when they enter viewport
  function lazySetupGithubCards() {
    githubCardsObserver?.disconnect()

    const githubCards = document.getElementsByClassName('gc-container')
    if (githubCards.length === 0) {
      return
    }

    // Create an intersection observer to lazy load GitHub repo data when cards enter viewport
    githubCardsObserver = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            loadCardData(entry.target as HTMLElement)
            githubCardsObserver?.unobserve(entry.target)
          }
        })
      },
      { rootMargin: '200px' }
    )

    Array.from(githubCards).forEach((card) => githubCardsObserver?.observe(card))
  }

  lazySetupGithubCards()
  document.addEventListener('astro:page-load', lazySetupGithubCards)
</script>

<style is:inline>
  .prose .gc-container {
    display: block;
    border: 0.5px solid var(--border);
    border-radius: 10px;
    padding: 1rem 1.25rem 0.75rem 1.25rem;
    margin: 1.25rem 0 1.75rem 0;
    text-decoration: none;
    color: inherit;
    transition: background 0.2s ease-out;
    background: var(--astro-code-background);
  }

  .prose .gc-container:hover {
    background: color-mix(in srgb, var(--selection) 75%, transparent);
    text-decoration: none;
  }

  .prose .gc-title-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
  }

  .prose .gc-owner-avatar {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background-color: var(--border);
    flex-shrink: 0;
  }

  .prose .gc-repo-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-regular);
    color: var(--text-primary);
    flex-grow: 1;
  }

  .prose .gc-repo-title strong {
    font-weight: var(--font-weight-bold);
  }

  .prose .gc-slash {
    color: var(--text-secondary);
    margin: 0 0.375rem;
  }

  .prose .gc-github-icon {
    width: 1.5rem;
    height: 1.5rem;
    color: var(--text-primary);
    flex-shrink: 0;
  }

  .prose .gc-repo-description {
    font-size: var(--font-size-m);
    color: var(--text-primary);
    opacity: 0.6;
    margin: 0 0 0.75rem 0;
    line-height: 1.4;
  }

  .prose .gc-info-bar {
    display: flex;
    align-items: center;
    color: var(--text-primary);
    opacity: 0.6;
    gap: 0.35rem;
  }

  .prose .gc-info-bar .gc-stars-count,
  .prose .gc-info-bar .gc-forks-count,
  .prose .gc-info-bar .gc-license-info {
    margin-right: 0.675rem;
    font-size: var(--font-size-s);
  }

  .prose .gc-info-icon {
    color: var(--text-primary);
    width: 0.875rem;
    height: 0.875rem;
  }
</style>
