import React, { useEffect, useState } from 'react'
import { type Meta } from '@storybook/react-vite'

import Button from '../../components/Button/Button'
import Tag from '../../components/Tag/Tag'
import { useToggle } from '..'
import { DocsTemplate } from '../../../.storybook'
import OutputForDemo from '../../../.storybook/templates/OutputForDemo'
import {
  type Toggle,
  ToggleProviderContext,
} from '../../components/ToggleProvider/ToggleProvider'

export const Example = (): React.JSX.Element => {
  const toggleKey = 'demo-toggle'
  const [toggleData, setToggleData] = useState<Toggle>({
    key: toggleKey,
    enabled: true,
    application: 'demo',
    name: 'Demo Toggle',
  })

  const handleToggle = () => {
    const currentValue = localStorage.getItem(toggleKey) === 'true'
    localStorage.setItem(toggleKey, (!currentValue).toString())
    setToggleData({ ...toggleData, enabled: !currentValue })
  }

  return (
    <ToggleProviderContext.Provider value={{ toggles: [toggleData] }}>
      <ToggleStatus toggleKey={toggleKey} />
      <Button onClick={handleToggle} className='mt-4'>
        {toggleData.enabled ? 'Disable Toggle' : 'Enable Toggle'}
      </Button>
    </ToggleProviderContext.Provider>
  )
}

const ToggleStatus = ({ toggleKey }: { toggleKey: string }) => {
  const isEnabled = useToggle(toggleKey)
  const [, forceUpdate] = useState({})

  useEffect(() => {
    const handleStorageChange = () => forceUpdate({})
    window.addEventListener('storage', handleStorageChange)

    // Poll for changes since the storage event doesn't fire for same-window changes
    const interval = setInterval(() => {
      forceUpdate({})
    }, 500)

    return () => {
      window.removeEventListener('storage', handleStorageChange)
      clearInterval(interval)
    }
  }, [])

  return (
    <OutputForDemo
      output={
        <div className='flex flex-col gap-4'>
          <div>
            Toggle state: <b>{isEnabled.toString()}</b>
          </div>
          <div className='flex items-center gap-2'>
            Example:
            {isEnabled ? (
              <Tag color='green'>New Feature Enabled</Tag>
            ) : (
              <Tag color='blue'>Using Legacy Feature</Tag>
            )}
          </div>
        </div>
      }
    />
  )
}

export default {
  title: 'Hooks/useToggle',
  component: Example,
  parameters: {
    viewMode: 'docs',
    previewTabs: {
      canvas: { hidden: true },
    },
    docs: {
      page: () => (
        <DocsTemplate
          code={`
              import { useToggle } from '@patterninc/react-ui'

              const featureFlag = useToggle('feature-flag-name')

              output = Boolean

              // Example usage:
              {
                featureFlag ? (
                  <NewFeatureComponent />
                ) : (
                  <OldFeatureComponent />
                )
              }
            `}
          description='A hook that provides feature flag functionality for conditional rendering of components based on toggle settings. It checks if a specified toggle exists and is enabled by first looking in localStorage (allowing for user overrides) and then falling back to values from the ToggleProvider context.'
          infoBullets={[
            <span key='first-point'>
              <code>useToggle</code> is essential for implementing feature
              flags, allowing for gradual rollout of features or A/B testing.
            </span>,
            <span key='second-point'>
              Returns <code>true</code> if the toggle exists and is enabled,
              otherwise <code>false</code>.
            </span>,
            <span key='third-point'>
              The hook first checks localStorage with the toggle key for
              user-specific overrides, then falls back to context values from
              ToggleProvider.
            </span>,
            <span key='fourth-point'>
              Ideal for implementing canary releases, beta features, or
              selectively enabling functionality for specific users or
              environments.
            </span>,
          ]}
          noArgs
        />
      ),
      source: {
        code: false,
      },
    },
  },
} as Meta<typeof Example>
