import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent, within } from 'storybook/test';
import { Input } from './input';
import { Search, Mail, Lock } from 'lucide-react';
import React from 'react';
import { Label } from '../label';

const meta: Meta<typeof Input> = {
  title: 'UI/Input',
  component: Input,
  render: args => <Input {...args} />,
  argTypes: {
    type: {
      control: 'select',
      options: ['text', 'email', 'password', 'number', 'search', 'tel', 'url'],
    },
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
      description: 'Size variant — matches the form sizing scale.',
    },
    disabled: {
      control: 'boolean',
    },
  },
};

export default meta;
type Story = StoryObj<typeof Input>;

export const Default: Story = {
  args: {
    placeholder: 'Standard Input',
  },
};

export const Email: Story = {
  args: {
    type: 'email',
    placeholder: 'you@example.com',
  },
};

export const Password: Story = {
  args: {
    type: 'password',
    placeholder: '••••••••',
  },
};

export const Disabled: Story = {
  args: {
    disabled: true,
    placeholder: 'Disabled Input',
    value: 'Content is fixed',
  },
};

export const WithLabel: Story = {
  render: args => (
    <div className="grid w-full max-w-sm items-center gap-1.5">
      <Label htmlFor="email" size={args.size}>
        Email
      </Label>
      <Input {...args} id="email" type="email" placeholder="Email" />
    </div>
  ),
};

export const WithHelperText: Story = {
  render: args => (
    <div className="grid w-full max-w-sm gap-1.5">
      <Label htmlFor="helper-input" size={args.size}>
        Email
      </Label>
      <Input {...args} id="helper-input" type="email" placeholder="you@example.com" />
      <p className="text-muted-foreground text-sm">We'll never share your email with anyone.</p>
    </div>
  ),
};

export const WithSearchIcon: Story = {
  render: args => {
    const iconSizeClasses = {
      sm: 'left-2.5 top-2 size-3.5',
      md: 'left-2.5 top-3 size-4',
      lg: 'left-3 top-4 size-5',
    };
    const paddingClasses = {
      sm: 'pl-8',
      md: 'pl-9',
      lg: 'pl-11',
    };

    return (
      <div className="relative w-full max-w-sm">
        <Search
          className={`absolute text-muted-foreground ${iconSizeClasses[args.size || 'md']}`}
        />
        <Input
          {...args}
          className={paddingClasses[args.size || 'md']}
          placeholder="Search components..."
        />
      </div>
    );
  },
};

/**
 * Size comparison: sm, md (default), lg.
 */
export const Sizes: Story = {
  render: () => (
    <div className="flex flex-col gap-4 max-w-sm">
      <div className="grid gap-1.5">
        <Label size="sm">Small (sm)</Label>
        <Input size="sm" placeholder="Small input" />
      </div>
      <div className="grid gap-1.5">
        <Label size="md">Medium (md — default)</Label>
        <Input size="md" placeholder="Medium input" />
      </div>
      <div className="grid gap-1.5">
        <Label size="lg">Large (lg)</Label>
        <Input size="lg" placeholder="Large input" />
      </div>
    </div>
  ),
};

export const Typing: Story = {
  args: { placeholder: 'Type here...' },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByRole('textbox');
    await userEvent.click(input);
    await expect(input).toHaveFocus();
    await userEvent.type(input, 'Hello Xertica');
    await expect(input).toHaveValue('Hello Xertica');
    await userEvent.clear(input);
    await expect(input).toHaveValue('');
  },
};

export const DisabledInteraction: Story = {
  args: { disabled: true, placeholder: 'Cannot type here' },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByRole('textbox');
    await expect(input).toBeDisabled();
  },
};
