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

import { DocsTemplate } from '../../../.storybook'
import Button from '../Button/Button'
import FormFooter from '../Form/FormFooter'
import { SideDrawer } from './SideDrawer'
import TextInput from '../Form/TextInput'
import { toast } from '../Toast/Toast'
import Icon from '../Icons/Icon'

const meta: Meta<typeof SideDrawer> = {
  title: 'Components/SideDrawer',
  component: SideDrawer,
  parameters: {
    design: {
      type: 'figma',
      url: 'https://www.figma.com/design/RvhKD82948FMQnh5MyCi0o/Web-Design-System?node-id=121-346&t=jsd8kEmb1sJfCa2m-0',
    },
    docs: {
      page: () => (
        <DocsTemplate
          figmaLink='https://www.figma.com/design/RvhKD82948FMQnh5MyCi0o/Web-Design-System?node-id=121-346&t=jsd8kEmb1sJfCa2m-0'
          description={
            <span>
              The <code>SideDrawer</code> should be used to contain all forms
              that were previously handled in popovers. These drawers can be
              used for information, help, and will be in place of popovers that
              are otherwise too large to comfortably fit the screen.
            </span>
          }
          infoBullets={[
            'Many instances of forms that could comfortably fit in a drawer. These would not include very large forms that may need their own page.',
            'In mobile when the popover content cannot easily fit on the screen.',
          ]}
        />
      ),
    },
  },
}

export default meta

type Story = StoryObj<typeof SideDrawer>

const Template: Story = {
  render: function Render(args) {
    const [isOpen, setIsOpen] = useState(false)

    return (
      <>
        <div className='flex flex-col'>
          <Button onClick={() => setIsOpen(true)}>Open Side Drawer</Button>
          {args.onlyMobile && (
            <div className='mt-2 text-xs'>
              Resize screen to a mobile view to see the drawer.
            </div>
          )}
        </div>
        <SideDrawer
          {...args}
          isOpen={isOpen}
          closeCallout={(isOutsideClick) => {
            if (isOutsideClick) {
              toast({
                type: 'info',
                message: 'You clicked outside the drawer!',
              })
            }
            setIsOpen(false)
          }}
        >
          {args.children ? args.children : <p>Side Drawer Content Goes here</p>}
        </SideDrawer>
      </>
    )
  },
}

export const Basic: Story = {
  ...Template,
  args: {
    headerContent: 'Basic Side Drawer',
  },
}

export const Medium: Story = {
  ...Template,
  args: {
    headerContent: 'Medium Side Drawer',
    size: 'md',
  },
}

export const Large: Story = {
  ...Template,
  args: {
    headerContent: 'Large Side Drawer',
    size: 'lg',
  },
}

export const Confirmation: Story = {
  ...Template,
  args: {
    headerContent: 'Confirmation',
    confirmation: {
      type: 'red',
      header: 'Are you sure?',
      body: 'This will perform some action. Would you like to continue?',
      confirmCallout: () => {
        toast({ message: 'You clicked confirm!', type: 'success' })
      },
      cancelCallout: () => {
        toast({ message: 'You clicked cancel!', type: 'info' })
      },
    },
  },
}

const resetButtonProps = {
  onClick: () => {
    toast({
      type: 'success',
      message: 'You clicked the Reset button!',
    })
  },
}
const cancelButtonProps = (close) => {
  return {
    onClick: () => {
      toast({
        type: 'success',
        message: 'You clicked the Cancel button!',
      })
      close()
    },
  }
}
const saveButtonProps = (close) => {
  return {
    onClick: () => {
      toast({
        type: 'success',
        message: 'You clicked the Save button!',
      })
      close()
    },
  }
}

export const FooterContent: Story = {
  ...Template,
  args: {
    headerContent: 'Footer Content',
    footerContent: ({ close }) => (
      <FormFooter
        resetButtonProps={resetButtonProps}
        cancelButtonProps={cancelButtonProps(close)}
        saveButtonProps={saveButtonProps(close)}
      />
    ),
  },
}

const overflowDummyData = (
  <div>
    {Array.from(Array(40)).map((_, index) => (
      <div className='mb-4' key={index}>
        Body overflow example. Scroll down.
      </div>
    ))}
  </div>
)

export const BodyOverflow: Story = {
  ...Template,
  args: {
    headerContent: 'Body Overflow',
    children: overflowDummyData,
  },
}

export const BodyOverflowWithFooter: Story = {
  ...Template,
  args: {
    headerContent: 'Body Overflow With Footer',
    children: overflowDummyData,
    footerContent: ({ close }) => (
      <FormFooter
        resetButtonProps={resetButtonProps}
        cancelButtonProps={cancelButtonProps(close)}
        saveButtonProps={{
          ...saveButtonProps(close),
          children: 'Save Changes',
        }}
      />
    ),
  },
}

export const WithStepper: Story = {
  ...Template,
  args: {
    headerContent: 'With Stepper',
    stepperProps: {
      steps: ['Step 1', 'Step 2', 'Step 3'],
      currentStep: 2,
      callout: () => {
        return
      },
    },
    children: overflowDummyData,
    footerContent: ({ close }) => (
      <FormFooter
        resetButtonProps={resetButtonProps}
        cancelButtonProps={cancelButtonProps(close)}
        saveButtonProps={saveButtonProps(close)}
      />
    ),
  },
}

export const OnlyMobileVisible: Story = {
  ...Template,
  args: {
    headerContent: 'Mobile Only',
    onlyMobile: true,
  },
}

export const FullWidth: Story = {
  ...Template,
  args: {
    headerContent: 'Full Width Side Drawer',
    fullWidth: true,
  },
}

export const Layered: Story = {
  render: function Render() {
    const [isOpen, setIsOpen] = useState({
      0: false,
      1: false,
      2: false,
    })
    const [numLayers, setNumLayers] = useState(3)

    const toggleDrawer = (index) => {
      setIsOpen((prevState) => ({
        ...prevState,
        [index]: !prevState[index],
      }))
    }

    const updateNumLayers = (layers) => {
      setNumLayers(layers)
      const newIsOpen = {}
      for (let i = 0; i < layers; i++) {
        newIsOpen[i] = false
      }
      setIsOpen((prevState) => ({
        ...prevState,
        ...newIsOpen,
      }))
    }

    return (
      <>
        <div className='flex flex-col gap-4'>
          <TextInput
            value={numLayers}
            callout={(_, value) => updateNumLayers(Number(value))}
            type='number'
            labelText='Number of Layers'
          />
          <Button onClick={() => toggleDrawer(0)}>
            Open First Side Drawer
          </Button>
        </div>

        {Array.from(Array(numLayers)).map((_, index) => (
          <SideDrawer
            key={index}
            headerContent={`Layer ${index + 1}`}
            isOpen={isOpen[index]}
            closeCallout={() => toggleDrawer(index)}
            {...(index > 0 ? { layerPosition: index + 1 } : {})}
          >
            {index + 1 < numLayers ? (
              <Button onClick={() => toggleDrawer(index + 1)}>
                Open New Drawer
              </Button>
            ) : (
              <p>This is the last layer!</p>
            )}
          </SideDrawer>
        ))}
      </>
    )
  },
  parameters: {
    docs: {
      source: {
        language: 'tsx',
        type: 'dynamic',
        excludeDecorators: true,
      },
    },
  },
}

export const LayeredWithOverlay: Story = {
  render: function Render() {
    const [isOpen, setIsOpen] = useState({
      0: false,
      1: false,
      2: false,
    })
    const [numLayers, setNumLayers] = useState(3)

    const toggleDrawer = (index) => {
      setIsOpen((prevState) => ({
        ...prevState,
        [index]: !prevState[index],
      }))
    }

    const updateNumLayers = (layers) => {
      setNumLayers(layers)
      const newIsOpen = {}
      for (let i = 0; i < layers; i++) {
        newIsOpen[i] = false
      }
      setIsOpen((prevState) => ({
        ...prevState,
        ...newIsOpen,
      }))
    }

    return (
      <>
        <div className='flex flex-col gap-4'>
          <TextInput
            value={numLayers}
            callout={(_, value) => updateNumLayers(Number(value))}
            type='number'
            labelText='Number of Layers'
          />
          <Button onClick={() => toggleDrawer(0)}>
            Open First Side Drawer
          </Button>
        </div>

        {Array.from(Array(numLayers)).map((_, index) => (
          <SideDrawer
            key={index}
            headerContent={`Layer ${index + 1}`}
            isOpen={isOpen[index]}
            fullWidth={index === 0 ? true : false}
            showBackgroundOverlay={true}
            closeCallout={() => toggleDrawer(index)}
            {...(index > 0 ? { layerPosition: index + 1 } : {})}
          >
            {index + 1 < numLayers ? (
              <Button onClick={() => toggleDrawer(index + 1)}>
                Open New Drawer
              </Button>
            ) : (
              <p>This is the last layer!</p>
            )}
          </SideDrawer>
        ))}
      </>
    )
  },
  parameters: {
    docs: {
      source: {
        language: 'tsx',
        type: 'dynamic',
        excludeDecorators: true,
      },
    },
  },
}

export const customHeader: Story = {
  ...Template,
  args: {
    headerContent: (
      <div className='flex flex-row items-center gap-4'>
        <div>Header Text</div>
        <div className='flex flex-row items-center gap-2'>
          <Icon icon='sellers' iconSize='20px' color='dark-red' />
          <span className='text-sm text-dark-red lowercase'>
            Secondary-Text
          </span>
          <Icon icon='info' iconSize='16px' color='dark-blue' />
        </div>
      </div>
    ),
    fullWidth: true,
  },
}
