'use client'

import { Fragment, useEffect, useId, useRef, useState } from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import clsx from 'clsx'
import {
  type MotionProps,
  type Variant,
  AnimatePresence,
  motion,
} from 'framer-motion'
import { useDebouncedCallback } from 'use-debounce'

import {
  Eyebrow,
  FeatureDescription,
  FeatureTitle,
  MobileFeatureTitle,
  P,
  SectionHeader,
} from '@/components/Texts'
import { Container } from '@/components/Container'

import reservenodeimg from '/images/cloud/reserve.png'
import billingImg from '/images/cloud/billing.png'
import kubeconfigImg from '/images/cloud/kubeconfig.png'


interface CustomAnimationProps {
  isForwards: boolean
  changeCount: number
}

const features = [
  {
    name: 'Decentralized Kubernetes',
    description:
      "Reserve a node and deploy sovereign Kubernetes clusters on decentralized infrastructure.",
    icon: DeviceUserIcon,
    screen: ReserveNodeScreen,
  },
  {
    name: 'Manage Your Cluster',
    description:
      'Manage your cluster with ease, with a simple and intuitive interface.',
    icon: DeviceNotificationIcon,
    screen: ManageClusterScreen,
  },
  {
    name: 'Personalised Billings & Accounts',
    description:
      'Easily manage your cluster billing and accounts with personalised configurations.',
    icon: DeviceTouchIcon,
    screen: PersonalisedBillingsScreen,
  },
]

function DeviceUserIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
  return (
    <svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
      <circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M16 23a3 3 0 100-6 3 3 0 000 6zm-1 2a4 4 0 00-4 4v1a2 2 0 002 2h6a2 2 0 002-2v-1a4 4 0 00-4-4h-2z"
        fill="#737373"
      />
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M5 4a4 4 0 014-4h14a4 4 0 014 4v24a4.002 4.002 0 01-3.01 3.877c-.535.136-.99-.325-.99-.877s.474-.98.959-1.244A2 2 0 0025 28V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 001.041 1.756C8.525 30.02 9 30.448 9 31s-.455 1.013-.99.877A4.002 4.002 0 015 28V4z"
        fill="#A3A3A3"
      />
    </svg>
  )
}

function DeviceNotificationIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
  return (
    <svg viewBox="0 0 32 32" aria-hidden="true" {...props}>
      <circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M9 0a4 4 0 00-4 4v24a4 4 0 004 4h14a4 4 0 004-4V4a4 4 0 00-4-4H9zm0 2a2 2 0 00-2 2v24a2 2 0 002 2h14a2 2 0 002-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9z"
        fill="#A3A3A3"
      />
      <path
        d="M9 8a2 2 0 012-2h10a2 2 0 012 2v2a2 2 0 01-2 2H11a2 2 0 01-2-2V8z"
        fill="#737373"
      />
    </svg>
  )
}

function DeviceTouchIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
  let id = useId()

  return (
    <svg viewBox="0 0 32 32" fill="none" aria-hidden="true" {...props}>
      <defs>
        <linearGradient
          id={`${id}-gradient`}
          x1={14}
          y1={14.5}
          x2={7}
          y2={17}
          gradientUnits="userSpaceOnUse"
        >
          <stop stopColor="#737373" />
          <stop offset={1} stopColor="#D4D4D4" stopOpacity={0} />
        </linearGradient>
      </defs>
      <circle cx={16} cy={16} r={16} fill="#A3A3A3" fillOpacity={0.2} />
      <path
        fillRule="evenodd"
        clipRule="evenodd"
        d="M5 4a4 4 0 014-4h14a4 4 0 014 4v13h-2V4a2 2 0 00-2-2h-1.382a1 1 0 00-.894.553l-.448.894a1 1 0 01-.894.553h-6.764a1 1 0 01-.894-.553l-.448-.894A1 1 0 0010.382 2H9a2 2 0 00-2 2v24a2 2 0 002 2h4v2H9a4 4 0 01-4-4V4z"
        fill="#A3A3A3"
      />
      <path
        d="M7 22c0-4.694 3.5-8 8-8"
        stroke={`url(#${id}-gradient)`}
        strokeWidth={2}
        strokeLinecap="round"
        strokeLinejoin="round"
      />
      <path
        d="M21 20l.217-5.513a1.431 1.431 0 00-2.85-.226L17.5 21.5l-1.51-1.51a2.107 2.107 0 00-2.98 0 .024.024 0 00-.005.024l3.083 9.25A4 4 0 0019.883 32H25a4 4 0 004-4v-5a3 3 0 00-3-3h-5z"
        fill="#A3A3A3"
      />
    </svg>
  )
}

const maxZIndex = 2147483647

const bodyVariantBackwards: Variant = {
  opacity: 0.4,
  scale: 0.8,
  zIndex: 0,
  filter: 'blur(4px)',
  transition: { duration: 0.4 },
}


const bodyAnimation: MotionProps = {
  initial: 'initial',
  animate: 'animate',
  exit: 'exit',
  variants: {
    initial: (custom: CustomAnimationProps) => (
      custom.isForwards
        ? {
            y: '100%',
            zIndex: maxZIndex - custom.changeCount,
            transition: { duration: 0.4 },
          }
        : bodyVariantBackwards
    ),
    animate: (custom: CustomAnimationProps) => ({
      y: '0%',
      opacity: 1,
      scale: 1,
      zIndex: maxZIndex / 2 - custom.changeCount,
      filter: 'blur(0px)',
      transition: { duration: 0.4 },
    }),
    exit: (custom: CustomAnimationProps) => (
      custom.isForwards
        ? bodyVariantBackwards
        : {
            y: '100%',
            zIndex: maxZIndex - custom.changeCount,
            transition: { duration: 0.4 },
          }
    ),
  },
}


function ReserveNodeScreen() {
  return (
    <img
      src={reservenodeimg}
      alt="Mycelium Reserve Node"
      width={2432}
      height={1442}
      className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
    />
  );
}

function ManageClusterScreen() {
  return (
    <img
      src={kubeconfigImg}
      alt="Mycelium Kubeconfig"
      width={2432}
      height={1442}
      className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
    />
  );
}

function PersonalisedBillingsScreen() {
  return (
    <img
      src={billingImg}
      alt="Mycelium Billing"
      width={2432}
      height={1442}
      className="w-4xl max-w-none rounded-xl shadow-2xl ring-1 ring-gray-400/10 sm:w-240 md:-ml-32 lg:-ml-32"
    />
  );
}

function usePrevious<T>(value: T) {
  const ref = useRef<T>()

  useEffect(() => {
    ref.current = value
  }, [value])

  return ref.current
}

function CloudFeaturesDesktop() {
  let [changeCount, setChangeCount] = useState(0)
  let [selectedIndex, setSelectedIndex] = useState(0)
  let prevIndex = usePrevious(selectedIndex)
  let isForwards = prevIndex === undefined ? true : selectedIndex > prevIndex

  let onChange = useDebouncedCallback(
    (selectedIndex: number) => {
      setSelectedIndex(selectedIndex)
      setChangeCount((changeCount) => changeCount + 1)
    },
    100,
    { leading: true },
  )

  return (
    <TabGroup
      className="grid grid-cols-12 items-center gap-8 lg:gap-16"
      selectedIndex={selectedIndex}
      onChange={onChange}
      vertical
    >
      <TabList className="z-10 col-span-6 space-y-6 pl-4 sm:pl-6 lg:pl-8">
        {features.map((feature, featureIndex) => (
          <div
            key={feature.name}
            className={clsx(
              'relative rounded-2xl outline-2 transition-all duration-300 ease-in-out hover:scale-105 hover:bg-gray-800/30 ml-16',
              selectedIndex === featureIndex
                ? 'outline-cyan-500'
                : 'outline-transparent hover:outline-cyan-500',
            )}
          >
            {featureIndex === selectedIndex && (
              <motion.div
                layoutId="activeBackground"
                className="absolute inset-0 bg-gray-800 "
                initial={{ borderRadius: 16 }}
              />
            )}
            <div className="relative z-10 p-8">
              <feature.icon className="h-8 w-8" />
              <FeatureTitle as="h3" color="white" className="mt-6">
                <Tab className="text-left data-selected:not-data-focus:outline-hidden">
                  <span className="absolute inset-0 rounded-2xl" />
                  {feature.name}
                </Tab>
              </FeatureTitle>
              <FeatureDescription color="secondary" className="mt-2">
                {feature.description}
              </FeatureDescription>
            </div>
          </div>
        ))}
      </TabList>
      <div className="relative col-span-6 overflow-hidden">
        <div className="z-10 mx-auto w-full max-w-[366px]">
          <TabPanels as={Fragment}>
            <AnimatePresence
              initial={false}
              custom={{ isForwards, changeCount }}
            >
              {features.map((feature, featureIndex) =>
                selectedIndex === featureIndex ? (
                  <TabPanel
                    static
                    key={feature.name + changeCount}
                    className="col-start-1 row-start-1 flex focus:outline-offset-32 data-selected:not-data-focus:outline-hidden"
                  >
                    <motion.div {...bodyAnimation} custom={{ isForwards, changeCount }}>
                      <feature.screen />
                    </motion.div>
                  </TabPanel>
                ) : null,
              )}
            </AnimatePresence>
          </TabPanels>
        </div>
      </div>
    </TabGroup>
  )
}

function CloudFeaturesMobile() {
  let [activeIndex, setActiveIndex] = useState(0)
  let slideContainerRef = useRef<React.ElementRef<'div'>>(null)
  let slideRefs = useRef<Array<React.ElementRef<'div'>>>([])

  useEffect(() => {
    let observer = new window.IntersectionObserver(
      (entries) => {
        for (let entry of entries) {
          if (entry.isIntersecting && entry.target instanceof HTMLDivElement) {
            setActiveIndex(slideRefs.current.indexOf(entry.target))
            break
          }
        }
      },
      {
        root: slideContainerRef.current,
        threshold: 0.6,
      },
    )

    for (let slide of slideRefs.current) {
      if (slide) {
        observer.observe(slide)
      }
    }

    return () => {
      observer.disconnect()
    }
  }, [slideContainerRef, slideRefs])

  return (
    <>
      <div
        ref={slideContainerRef}
        className="-mb-4 flex snap-x snap-mandatory -space-x-4 overflow-x-auto overscroll-x-contain scroll-smooth pb-4 [scrollbar-width:none] sm:-space-x-6 [&::-webkit-scrollbar]:hidden"
      >
        {features.map((feature, featureIndex) => (
          <div
            key={featureIndex}
            ref={(ref) => ref && (slideRefs.current[featureIndex] = ref)}
            className="w-full flex-none snap-center px-4 sm:px-6 transition-all duration-300 ease-in-out hover:scale-105"
          >
                        <div
              className={clsx(
                'relative transform overflow-hidden rounded-2xl bg-gray-800 px-5 py-6 outline-2 transition-colors',
                activeIndex === featureIndex
                  ? 'outline-transparent' // Remove outline for active mobile slide
                  : 'outline-transparent hover:outline-cyan-500',
              )}
            >
              <div className="relative mx-auto w-full max-w-[366px]">
                <feature.screen />
              </div>
              <div className="absolute inset-x-0 bottom-0 bg-gray-800 p-6 backdrop-blur-sm sm:p-10">
                <feature.icon className="h-8 w-8" />
                <MobileFeatureTitle color="white" className="mt-6">
                  {feature.name}
                </MobileFeatureTitle>
                <FeatureDescription color="secondary" className="mt-2">
                  {feature.description}
                </FeatureDescription>
              </div>
            </div>
          </div>
        ))}
      </div>
      <div className="mt-6 flex justify-center gap-3">
        {features.map((_, featureIndex) => (
          <button
            type="button"
            key={featureIndex}
            className={clsx(
              'relative h-0.5 w-4 rounded-full',
              featureIndex === activeIndex ? 'bg-gray-600' : 'bg-gray-700',
            )}
            aria-label={`Go to slide ${featureIndex + 1}`}
            onClick={() => {
              slideRefs.current[featureIndex].scrollIntoView({
                block: 'nearest',
                inline: 'nearest',
              })
            }}
          >
            <span className="absolute -inset-x-1.5 -inset-y-3" />
          </button>
        ))}
      </div>
    </>
  )
}

export function CloudFeatures() {
  return (
    <section
      id="overview"
      aria-label="Features for investing all your money"
      className="bg-gray-900 py-20 sm:py-32"
    >
      <Container>
        <div className="mx-auto max-w-2xl lg:mx-0 lg:max-w-3xl">
          <Eyebrow color="accent">Platform Overview</Eyebrow>
          <SectionHeader color="white" className="mt-2">
            A Decentralized Cloud that Operates Itself
          </SectionHeader>
          <P color="light" className="mt-6">
           Mycelium Cloud runs Kubernetes on a sovereign, self-healing network with compute, storage, and networking built in, so you don’t need external cloud dependencies.
          </P>
        </div>
      </Container>
      <div className="hidden md:mt-20 md:block">
          <CloudFeaturesDesktop />
        </div>
      <div className="mt-16 md:hidden">
        <CloudFeaturesMobile />
      </div>
    </section>
  )
}
