<script lang="ts">
  import { onMount } from 'svelte';
  import gsap from 'gsap';
  import { SplitText } from 'gsap/SplitText';
	import { goto } from '$app/navigation';
  let { data } = $props();

  const orderedPosts = $derived.by(() => (data.posts || []).sort((a, b) => {
    return a.meta.order - b.meta.order;
  }));

  function getColorValue(cssValue: string): string {
    // If it's a CSS variable reference, resolve it
    if (cssValue.trim().startsWith('var(')) {
      // Extract the variable name and resolve it
      const varName = cssValue.match(/var\(([^)]+)\)/)?.[1];
      if (varName) {
        return getComputedStyle(document.documentElement).getPropertyValue(varName.trim()).trim() || cssValue;
      }
    }
    return cssValue.trim();
  }

  onMount(() => {
    document.querySelectorAll('.workclone')?.forEach(clone => {
      clone.remove();
    })
    gsap.registerPlugin(SplitText);

    let isZoomed = false;

    // const currentBgColor = getComputedStyle(document.documentElement).getPropertyValue('--color-bg');
    // const currentHighlightColor = getComputedStyle(document.documentElement).getPropertyValue('--color-highlight');

    // Read from data.theme if available, otherwise from CSS
    let currentBgColor: string;
    let currentHighlightColor: string;
    
    if (data.theme) {
      currentBgColor = getColorValue(data.theme.bg);
      currentHighlightColor = getColorValue(data.theme.highlight);
    } else {
      currentBgColor = getComputedStyle(document.documentElement).getPropertyValue('--color-bg').trim();
      currentHighlightColor = getComputedStyle(document.documentElement).getPropertyValue('--color-highlight').trim();
    }

    let works: Array<HTMLElement> = Array.from(document.querySelectorAll('.work'));
    for ( let i = 0; i < 40; i++ ){
      let clone = works[i].cloneNode(true) as HTMLElement;
      works[i].parentNode?.appendChild(clone);
      works.push(clone);
    }

    works.forEach((work, index) => {
      let workrect = work.getBoundingClientRect();
      let worksrect = document.querySelector('.works')?.getBoundingClientRect() || {x: 0, y: 0, width: 1, height: 1};
      let distanceXinPercent = (workrect.x - worksrect?.x || 0) / (worksrect?.width || 1) * 100 ;
      let distanceYinPercent = (workrect.y - worksrect?.y || 0) / (worksrect?.height || 1) * 100 ;

      work.addEventListener('click', (e) => {
        isZoomed = !isZoomed;
        e.preventDefault();
        let href = work.getAttribute('href');
        if (isZoomed) {
          gsap.to('.works', {
            rotate: 0,
            xPercent: -distanceXinPercent,
            yPercent: -distanceYinPercent,
            rotateX: 0,
            rotateY: 0,
            scale: 1,
            duration: .75,
            ease: 'power2.inOut',
            onComplete: () => {
              let workclone = work.cloneNode(true) as HTMLElement;
              workclone.classList.add('workclone');
              workclone.style.position = 'fixed';
              workclone.style.top = `0`;
              workclone.style.left = `0`;
              document.body.appendChild(workclone);
              // window.location.href = href || ''
              goto(href || '');
            }
          })
          gsap.fromTo(split.chars, {
            scaleY: 1,
            opacity: 1,
          }, {
            scaleY: 0,
            opacity: 1,
            duration: .3,
            ease: 'power3.out',
          })
        } else {
          gsap.to('.works', {
            rotate: -5,
            transformOrigin: '0 0',
            xPercent: -3,
            yPercent: 0,
            rotateX: 0,
            rotateY: 0,
            scale: .25,
            duration: 1,
            ease: 'power4.inOut'
          })
        }
      })
    });

    // set initial positions AFTER the individual rects have been read

    let split = new SplitText('.headline', { type: 'chars', charsClass: 'charChildren' });

    gsap.set('.works, .headline', {
      rotate: -5,
      xPercent: -5,
      yPercent: -2,
      rotateX: 0,
      rotateY: 0,
      scale: .25,
    })
    gsap.set('.work, .works, .headline', {
      transformOrigin: '0 0',
    })
    gsap.set('.work',{
      autoAlpha: 0,
      yPercent: 50,
      scaleY: 0,
    })
    gsap.to('.work',{
      autoAlpha:1,
      yPercent: 0,
      scaleY: 1,
      duration: .75,
      stagger: 0.01,
      ease: 'power4.inOut',
    })
    gsap.fromTo(split.chars, {
      yPercent: -300
    }, {
      yPercent: 0,
      duration: 1,
      stagger: 0.0075,
      ease: 'elastic.out(1, .8)',
    })
    // Move the works around on mousemove
    let mouseMoveHandler = (e: MouseEvent) => {
      let x = e.clientX;
      let y = e.clientY;
      if (isZoomed) return;
      gsap.to('.works, .headline', {
        xPercent: -x/window.innerWidth * 4 - 3,
        yPercent: -y/window.innerHeight * 4,
        rotateX: x/window.innerWidth * 10 - 5,
        rotateY: x/window.innerWidth * 10 - 5,
        duration: 1,
        ease: 'power4.out',
        overwrite: true,
      })
    }
    window.addEventListener('mousemove', mouseMoveHandler);

    // Create handler functions outside the loop for proper cleanup
    const handleMouseEnter = (work: HTMLElement) => {
      if (isZoomed) return;
      gsap.killTweensOf([work, work.querySelector('.work-logo')]);
      gsap.to(work, {
        backgroundColor: currentBgColor,
        duration: .125,
        ease: 'power1.inOut',
      })
      const logo = work.querySelector('.work-logo');
      if (logo) {
        gsap.to(logo, {
          color: currentHighlightColor,
          duration: .125,
          ease: 'power1.inOut',
        })
      }
    }

    const handleMouseLeave = (work: HTMLElement) => {
      if (isZoomed) return;
      gsap.killTweensOf([work, work.querySelector('.work-logo')]);
      gsap.to(work, {
        backgroundColor: currentHighlightColor,
        duration: .125,
        ease: 'power1.inOut',
      })
      const logo = work.querySelector('.work-logo');
      if (logo) {
        gsap.to(logo, {
          color: currentBgColor,
          duration: .125,
          ease: 'power1.inOut',
        })
      }
    }
    
    // Hover states of .work
    works.forEach((work) => {
      work.addEventListener('mouseenter', () => handleMouseEnter(work));
      work.addEventListener('mouseleave', () => handleMouseLeave(work));
    })
    
    // Move the works the same way on touch drag
    let touchMoveHandler = (e: TouchEvent) => {
      let x = e.touches[0].clientX;
      let y = e.touches[0].clientY;
      if (isZoomed) return;
      gsap.to('.works, .headline', {
        xPercent: -x/window.innerWidth * 4 - 3.33,
        yPercent: -y/window.innerHeight * 4,
        rotateX: x/window.innerWidth * 10 - 5,
        rotateY: x/window.innerWidth * 10 - 5,
        duration: 1,
        ease: 'power4.out',
        overwrite: true,
      })
    }
    window.addEventListener('touchmove', touchMoveHandler, { passive: true });

    document.querySelector('html')?.style.setProperty('overflow', 'hidden');
    document.querySelector('html')?.style.setProperty('overscroll-behavior', 'none');
    
    return () => {
      document.querySelector('html')?.style.setProperty('overflow', 'visible');
      document.querySelector('html')?.style.setProperty('overscroll-behavior', 'auto');
      window.removeEventListener('mousemove', mouseMoveHandler);
      window.removeEventListener('touchmove', touchMoveHandler);
      gsap.killTweensOf('.works, .work');
      works.forEach((work) => {
        work.removeEventListener('mouseenter', () => handleMouseEnter(work));
        work.removeEventListener('mouseleave', () => handleMouseLeave(work));
        work.removeEventListener('click', (e) => {});
      })
    }
  });
</script>

<div class="works-wrapper">
  <h1 class="headline"><span>Work References</span></h1>
    <div class="works">
      {#each orderedPosts as work, i}
        <a 
          data-sveltekit-preload-data
          href="{work.path}" 
          class="work" 
        >
          <div class="work-logo">
            {@html work.meta.svg}
          </div>
          <div class="work-info">
            <h2 class="title"><span class="title-words">{work.meta.title}</span></h2>
            {#if work.meta.tags}
            <ul class="tags">
              {#each work.meta.tags as tag, index}
                <li class="tag">{tag}{index < work.meta.tags.length-1 ? ' | ' : ''}</li>
              {/each}
            </ul>
            {/if}
          </div>  
        </a>
      {/each}
    </div>
</div>

<style>
  :global(html) {
    overflow: hidden;
    overscroll-behavior: none;
  }
  .works-wrapper {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    perspective: 700px;
    transform-origin: 0 0;
    will-change: transform;
  }
  .headline {
    position: fixed;
    pointer-events: none;
    display: flex;
    width: 100%;
    height: 100%;
    text-align: center;
    flex-direction: column;
    justify-content: center;
    align-content: center;
    letter-spacing: -0.05em;
    z-index: 10;
    transform: translateZ(500px);
    margin-left: 40.5vw;
    margin-top: 37.25vh;
    font-size: 14vw;
  }
  @media screen and (min-width: 768px) {
    .headline {
      margin-left: 41.66vw;
      margin-top: 40.5vh;
      font-size: 7vw;
      transform: translateZ(600px);
    }
  }
  .works {
    margin: 0 auto;
    position: absolute;
    top: 0;
    left: 0;
    width: 600vw;
    height: 600vw;
    transform: scale(.333);
    transform-origin: 0 0;
    display: grid;
    grid-template-columns: repeat(6, 100vw);
    grid-auto-rows: 100vh;
    gap: 6px;
    will-change: transform;
  }
  .work {
    background-color: var(--color-highlight);
    text-decoration: none;
    text-align: center;
    width: 100vw;
    height: 100vh;
    opacity: 0;
    visibility: hidden;
    transform: translateZ(700px);
    will-change: transform;
  }
  :global(.work-logo) {
    width: 100%;
    height: 100%;
    color: var(--color-bg);
    padding: 3em;
    margin: auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    will-change: transform;
  }
  @media screen and (min-width: 768px) {
    :global(.work-logo) { width: 60%; }
  }
  :global(.work-logo svg) {
    object-fit: fill;
    width: 100%;
    height: 100%;
  }
  .work-info {
    display: none;
  }
  .work-info .tags {
    display: flex;
    list-style: none;
    gap: .25em;
  }
</style>