import type { Meta, StoryObj } from '@storybook/react-vite'
import { expect, userEvent, screen, waitFor } from 'storybook/test'
import { SunIcon } from '@radix-ui/react-icons'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@components/ui/tabs/tabs'

import { Modal } from './modal'
import { Button } from '@components/ui/button/button'
import { RadioGroup, RadioGroupItem } from '@components/ui/radio-group/radio-group'
import { Label } from '@components/ui/label/label'

import { useState } from 'react'

const meta = {
  title: 'Modal',
  component: Modal,
  tags: ['autodocs'],
  parameters: {
    layout: 'centered',
  },
  argTypes: {
    isOpen: {
      control: { disable: true },
    },
    setIsOpen: {
      control: { disable: true },
    },
    title: {
      control: 'text',
    },
    subtitle: {
      control: 'text',
    },
    showCloseButton: {
      control: 'boolean',
    },
    preventClickOutsideToDismiss: {
      control: 'boolean',
    },
    size: {
      control: 'select',
      options: [undefined, 'fit-content', 'full-height', 'full-size', 'fit-content-width'],
    },
    onOpenAutoFocus: {
      control: { disable: true },
    },
  },
  args: {
    title: 'Modal Title',
    subtitle: 'This is the modal subtitle',
    showCloseButton: true,
    preventClickOutsideToDismiss: false,
  },
} satisfies Meta<typeof Modal>
export default meta

type Story = StoryObj<typeof meta>

const dummyText =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam rutrum laoreet erat ac sodales. Pellentesque nec nunc in ipsum tincidunt congue sit amet in augue. Sed interdum consequat arcu, ac tempor nisl eleifend sed. Mauris gravida ipsum orci, sed vestibulum nisl commodo in. Aliquam ut dolor dui. Donec fermentum viverra faucibus. In aliquet erat et quam ornare, et accumsan magna ornare. Suspendisse potenti. Etiam a elit dui. Mauris et lectus vel metus lobortis luctus. Vestibulum elementum sit amet augue vel rutrum. Aenean sem turpis, viverra hendrerit consequat eget, vulputate sed nunc. Pellentesque sollicitudin diam nunc, vel pretium massa mattis at. Curabitur fringilla convallis mollis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam rutrum laoreet erat ac sodales. Pellentesque nec nunc in ipsum tincidunt congue sit amet in augue. Sed interdum consequat arcu, ac tempor nisl eleifend sed. Mauris gravida ipsum orci, sed vestibulum nisl commodo in. Aliquam ut dolor dui. Donec fermentum viverra faucibus. In aliquet erat et quam ornare, et accumsan magna ornare. Suspendisse potenti. Etiam a elit dui. Mauris et lectus vel metus lobortis luctus. Vestibulum elementum sit amet augue vel rutrum. Aenean sem turpis, viverra hendrerit consequat eget, vulputate sed nunc. Pellentesque sollicitudin diam nunc, vel pretium massa mattis at. Curabitur fringilla convallis mollis. '

export const Default: Story = {
  args: {
    isOpen: false,
    setIsOpen: () => {},
    title: 'Modal Title',
    subtitle: 'This is the modal subtitle',
    showCloseButton: true,
    preventClickOutsideToDismiss: false,
  },
  render: (args) => {
    const [isOpen, setIsOpen] = useState(false)
    return (
      <>
        <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
        <Modal
          isOpen={isOpen}
          setIsOpen={setIsOpen}
          title={args.title}
          subtitle={args.subtitle}
          showCloseButton={args.showCloseButton}
          preventClickOutsideToDismiss={args.preventClickOutsideToDismiss}
          size={args.size}
          onOpenAutoFocus={args.onOpenAutoFocus}
          controls={args.controls}
        >
          <div className="bg-primary/20 p-4">
            <p>Modal Content</p>
            <br />
            <p>{dummyText}</p>
          </div>
        </Modal>
      </>
    )
  },
  play: async () => {
    // Open modal
    const openButton = screen.getByText('Open Modal')
    await userEvent.click(openButton)
    // Wait for modal content to appear and be visible
    await waitFor(() => {
      const modalContent = screen.queryByText('Modal Content')
      expect(modalContent).toBeTruthy()
      expect(modalContent).toBeVisible()
    })
    // Close modal (via close button)
    const closeButton = screen.getByRole('button', { name: /close/i })
    await userEvent.click(closeButton)
    // Wait for modal content to be hidden or removed
    await waitFor(() => {
      const modalContent = screen.queryByText('Modal Content')
      if (modalContent) {
        expect(modalContent).not.toBeVisible()
      }
    })
  },
}

export const Sizes: Story = {
  args: { isOpen: false, setIsOpen: () => {} },
  render: () => {
    const [isOpen, setIsOpen] = useState(false)
    const [size, setSize] = useState<'fit-content' | 'full-height' | 'full-size' | 'fit-content-width' | undefined>(
      undefined,
    )
    const sizeOptions = [
      { value: '', label: 'undefined' },
      { value: 'fit-content', label: 'fit-content' },
      { value: 'full-height', label: 'full-height' },
      { value: 'full-size', label: 'full-size' },
      { value: 'fit-content-width', label: 'fit-content-width' },
    ]
    return (
      <div className="flex flex-col gap-3 items-center">
        <RadioGroup
          defaultValue=""
          value={size ?? ''}
          onValueChange={(val) => setSize(val === '' ? undefined : (val as typeof size))}
          className="flex flex-row gap-2"
        >
          {sizeOptions.map((opt) => (
            <div key={opt.value} className="flex items-center gap-2">
              <RadioGroupItem value={opt.value} id={`modal-size-${opt.value}`} />
              <Label htmlFor={`modal-size-${opt.value}`} className="cursor-pointer">
                {opt.label}
              </Label>
            </div>
          ))}
        </RadioGroup>
        <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
        <Modal
          isOpen={isOpen}
          setIsOpen={setIsOpen}
          title="Modal Title"
          subtitle="This is the modal subtitle"
          showCloseButton={true}
          preventClickOutsideToDismiss={false}
          size={size}
        >
          <div className="bg-primary/20 w-[900px] min-w-0 h-full p-4">
            <p>Modal Content with w-[900px]</p>
            <br />
            <p>{dummyText}</p>
          </div>
        </Modal>
      </div>
    )
  },
}

export const WithControlsAndFooter: Story = {
  args: {
    isOpen: false,
    setIsOpen: () => {},
    title: 'Modal Title',
    showCloseButton: true,
    preventClickOutsideToDismiss: false,
    controls: [
      <Button key="c1" variant="outline" size="xs" onClick={() => alert('Cancel clicked')}>
        Cancel
      </Button>,
      <Button key="c2" variant="default" size="xs" onClick={() => alert('Save clicked')}>
        Save
      </Button>,
    ],
    footer: (
      <div className="flex items-center justify-center gap-3">
        This is the modal footer
        <SunIcon className="size-5 text-yellow-500" />
      </div>
    ),
  },
  render: (args) => {
    const [isOpen, setIsOpen] = useState(false)
    return (
      <>
        <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
        <Modal
          isOpen={isOpen}
          setIsOpen={setIsOpen}
          title={args.title}
          subtitle={args.subtitle}
          showCloseButton={args.showCloseButton}
          preventClickOutsideToDismiss={args.preventClickOutsideToDismiss}
          size={args.size}
          onOpenAutoFocus={args.onOpenAutoFocus}
          controls={args.controls}
          footer={args.footer}
        >
          <div className="bg-primary/20 p-4">
            <p>Modal Content</p>
            <br />
            <p>{dummyText}</p>
          </div>
        </Modal>
      </>
    )
  },
}

export const ComplexSubtitleExample: Story = {
  args: {
    isOpen: false,
    setIsOpen: () => {},
    title: 'Subtitle to navigate menu of multi page modal',
    showCloseButton: true,
    preventClickOutsideToDismiss: false,
  },
  render: (args) => {
    const [isOpen, setIsOpen] = useState(false)
    const [activeTab, setActiveTab] = useState('tab1')
    return (
      <>
        <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
        <Modal
          isOpen={isOpen}
          setIsOpen={setIsOpen}
          title={args.title}
          showCloseButton={args.showCloseButton}
          preventClickOutsideToDismiss={args.preventClickOutsideToDismiss}
          size={args.size}
          onOpenAutoFocus={args.onOpenAutoFocus}
          controls={args.controls}
          footer={args.footer}
          subtitle={
            <Tabs value={activeTab} onValueChange={setActiveTab} className="mt-2">
              <TabsList variant="protocol" size="sm" className="justify-start relative">
                <TabsTrigger variant="protocol" value="tab1" className="px-4 cursor-pointer">
                  Tab 1
                </TabsTrigger>
                <TabsTrigger variant="protocol" value="tab2" className="px-4 cursor-pointer">
                  Tab 2
                </TabsTrigger>
              </TabsList>
            </Tabs>
          }
        >
          <div className="p-3 pb-2">
            <Tabs value={activeTab} onValueChange={setActiveTab}>
              <TabsContent value="tab1">
                <h3>Modal page 1</h3>
              </TabsContent>
              <TabsContent value="tab2">
                <h3>Modal page 2</h3>
              </TabsContent>
            </Tabs>
          </div>
        </Modal>
      </>
    )
  },
}

export const ScrollableModal: Story = {
  args: {
    isOpen: false,
    setIsOpen: () => {},
  },
  render: (args) => {
    const [isOpen, setIsOpen] = useState(false)
    let repeatedText = ''
    for (let i = 0; i < 20; i++) {
      repeatedText += dummyText
    }
    return (
      <>
        <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
        <Modal isOpen={isOpen} setIsOpen={setIsOpen} title="Modal Title">
          <div className="bg-primary/20 p-4">
            <p>Modal Content</p>
            <br />
            <p>{repeatedText}</p>
          </div>
        </Modal>
      </>
    )
  },
}
