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

import { Textarea } from './textarea'
import { useState } from 'react'
import { Button } from '@components/ui/button/button'
import { expect, userEvent, within } from 'storybook/test'

const meta = {
  title: 'Textarea',
  component: Textarea,
  tags: ['autodocs'],
  parameters: {
    layout: 'centered',
  },
  argTypes: {
    variant: {
      control: 'select',
      options: ['default', 'simple'],
    },
  },
} satisfies Meta<typeof Textarea>
export default meta

type Story = StoryObj<typeof meta>

export const Default: Story = {
  render: (args) => <Textarea {...args} className="w-[350px]" placeholder="Simple Textarea..." />,
}

export const Variants: Story = {
  render: () => (
    <div className="flex flex-wrap gap-4 items-center">
      <Textarea variant="default" className="w-[250px]" placeholder="default" />
      <Textarea variant="simple" className="w-[250px]" placeholder="simple" />
    </div>
  ),
}

export const Disabled: Story = {
  render: (args) => (
    <div className="flex flex-wrap gap-4 items-center">
      <Textarea disabled {...args} className="w-[350px]" placeholder="Disabled" />
    </div>
  ),
}

export const ManagedResizing: Story = {
  render: () => (
    <div className="flex flex-col gap-4 items-center">
      <Textarea className="h-12.5 w-[350px] resize-none" placeholder="No resizing - locked 2 lines 350px" />
      <Textarea
        className="min-h-6.5 max-h-24.5 w-[350px] resize-y"
        placeholder="Vertical resizing - minimum 2, maximum 5 lines."
      />
      <Textarea
        className="h-15.5 min-w-[200px] w-[350px] max-w-[500px] resize-x"
        placeholder="Horizontal resizing - minimum 200px, maximum 500px."
      />
      <Textarea
        className="min-h-12.5 min-w-[200px] max-h-24.5 max-w-[500px] w-[350px] resize"
        placeholder="Free resizing - minimum 200px 2 lines, maximum 500px 5 lines"
      />
    </div>
  ),
}

export const EmailForm: Story = {
  render: () => {
    const [value, setValue] = useState('')
    const [error, setError] = useState<string | null>(null)
    const [submitted, setSubmitted] = useState(false)
    const [touched, setTouched] = useState(false)

    function validateEmail(email: string) {
      return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) // simple email regex
    }

    function validate(value: string) {
      if (!value) return 'Field is required.'
      if (!validateEmail(value)) return 'Not a valid email.'
      return null
    }

    const handleSubmit = (e: React.FormEvent) => {
      e.preventDefault()
      setSubmitted(true)
      setError(validate(value))
    }

    const handleBlur = () => {
      setTouched(true)
      setError(validate(value))
    }

    return (
      <form className="flex flex-col gap-2 items-center w-[350px]" onSubmit={handleSubmit} noValidate>
        <Textarea
          className="w-full"
          placeholder="Enter an email..."
          value={value}
          onChange={(e) => {
            setValue(e.target.value)
            if (submitted || touched) setError(validate(e.target.value))
          }}
          onBlur={handleBlur}
          aria-invalid={!!error}
        />
        {error && (touched || submitted) && (
          <span className="text-destructive mt-1" role="alert">
            {error}
          </span>
        )}
        <Button type="submit" size="smLow">
          Submit
        </Button>
      </form>
    )
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement)
    const textarea = canvas.getByPlaceholderText('Enter an email...')
    const submitButton = canvas.getByRole('button', { name: /submit/i })

    // Submit with empty input
    await userEvent.clear(textarea)
    await userEvent.click(submitButton)
    expect(await canvas.findByRole('alert')).toHaveTextContent('Field is required.')
    // Enter invalid email and submit
    await userEvent.type(textarea, 'not-an-email')
    await userEvent.click(submitButton)
    expect(await canvas.findByRole('alert')).toHaveTextContent('Not a valid email.')
    // Enter valid email and submit
    await userEvent.clear(textarea)
    await userEvent.type(textarea, 'test@example.com')
    await userEvent.click(submitButton)
    expect(canvas.queryByRole('alert')).toBeNull()
  },
}
