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

// Animated illustrations - import directly from individual files
import AccountingAnimation from '../../generated/AccountingAnimation'
import Binoculars from '../../generated/Binoculars'
import BinocularsAnimation from '../../generated/BinocularsAnimation'
import CardAnimation from '../../generated/CardAnimation'
import FAQ from '../../generated/FAQ'
import FAQWithBackground from '../../generated/FAQWithBackground'
import VisuallyImpaired from '../../generated/VisuallyImpaired'
import WriteBook from '../../generated/WriteBook'
import { Illustration } from './Illustration'

function transformIllustrationSource(code: string) {
  // Find all src props with name values
  const srcMatches = [
    ...code.matchAll(/src=\{\{[^}]+name:\s*['"`]([^'"`]+)['"`][^}]+\}\}/g),
  ]

  if (srcMatches.length === 0) {
    return code // Return original code if no illustrations found
  }

  // Extract unique illustration names
  const illustrationNames = [...new Set(srcMatches.map(match => match[1]))]

  // Create import statements for all unique illustrations
  const importStatements = illustrationNames
    .map(
      name =>
        `import ${name} from '@payfit/unity-illustrations/assets/${name}';`,
    )
    .join('\n')

  // Replace all src prop objects with their corresponding imported variables
  let modifiedCode = code
  srcMatches.forEach(match => {
    const fullMatch = match[0] // The entire src={{...}} part
    const illustrationName = match[1] // The name value
    modifiedCode = modifiedCode.replace(fullMatch, `src={${illustrationName}}`)
  })

  return `${importStatements}\n\n${modifiedCode}`
}

/**
 * Displays illustrations from the Unity design system with consistent styling and accessibility.
 *
 * The Illustration component handles SVG illustrations and images, providing standardized sizing options,
 * responsive behavior, and proper accessibility attributes. All illustration assets must be imported
 * individually from the `@payfit/unity-illustrations` package before use. For example, if you want to use the FAQ illustration, you can import it like this:
 *
 * ```tsx
 * import FAQ from '@payfit/unity-illustrations/assets/FAQ'
 * ```
 *
 * See the [usage page](/docs/introduction-3-usage--docs) for complete examples and best practices.
 */
const meta = {
  title: 'Components/Illustration',
  component: Illustration,
  tags: ['autodocs'],
  parameters: {
    layout: 'centered',
    docs: {
      source: {
        transform: (code: string) => transformIllustrationSource(code),
        language: 'tsx',
      },
    },
  },
  argTypes: {
    src: {
      control: 'select',
      description:
        'The illustration asset to render. Must be imported from @payfit/unity-illustrations',
      table: {
        type: { summary: 'UnityIllustrationAsset' },
        category: 'Required',
      },
      type: { name: 'other', required: true, value: 'UnityIllustrationAsset' },
    },
    variant: {
      control: 'select',
      options: ['picture', 'icon'],
      description:
        'The illustration variant. It can be a regular picture or an illustrated icon',
      table: {
        type: { summary: "'picture' | 'icon'" },
        category: 'Required',
      },
      type: { name: 'enum', required: true, value: ['picture', 'icon'] },
    },
    alt: {
      control: 'text',
      description:
        'Accessible name for the illustration. Required when isDecorative is `true`',
      table: {
        type: { summary: 'string' },
        category: 'Accessibility',
      },
    },
    description: {
      control: 'text',
      description:
        'Optional description for complex illustrations. Active only when isDecorative is `true`',
      table: {
        type: { summary: 'string' },
        category: 'Accessibility',
      },
    },
    isDecorative: {
      control: 'boolean',
      description:
        'Whether the illustration is decorative (hidden from screen readers). When `true`, `alt` becomes optional',
      table: {
        type: { summary: 'boolean' },
        defaultValue: { summary: 'false' },
        category: 'Accessibility',
      },
    },
    size: {
      control: 'select',
      options: ['sm', 'md', 'lg'],
      description: 'The size of the illustration. Only applies to icon variant',
      if: { arg: 'variant', eq: 'icon' },
      table: {
        type: { summary: "'sm' | 'md' | 'lg'" },
        category: 'Icon Variant',
      },
    },
    className: {
      control: 'text',
      description: 'Additional CSS classes for styling',
      table: {
        type: { summary: 'string' },
        category: 'Styling',
      },
    },
  },
} satisfies Meta<typeof Illustration>

export default meta

type Story = StoryObj<typeof Illustration>

export const Primary: Story = {
  args: {
    variant: 'picture',
    src: Binoculars,
    className: 'uy:size-[150px]',
    alt: 'Binoculars illustration',
  },
}

/**
 * You can create responsive illustrations that adapt to different screen sizes by using responsive
 * Tailwind classes in the `className` prop. Set the `alt` prop to provide accessible descriptions
 * for screen readers when using the picture variant.
 */
export const IllustratedPicture: Story = {
  args: {
    variant: 'picture',
    src: VisuallyImpaired,
    className: 'uy:size-[50vmin]',
  },
}

/**
 * You can display illustrations as smaller icons by setting the `variant` prop to `"icon"`.
 * Use the `size` prop to choose from predefined sizes: `"sm"`, `"md"`, or `"lg"`. This is ideal for illustrations that are meant to be used as illustrated icons.
 */
export const IllustratedIcon: Story = {
  args: {
    variant: 'icon',
  },
  render: function Render(args) {
    return (
      <div className="uy:grid uy:grid-cols-3 uy:items-center uy:gap-200">
        <Illustration
          {...args}
          variant="icon"
          size="sm"
          src={FAQ}
          alt="FAQ icon small"
        />
        <Illustration
          {...args}
          variant="icon"
          size="md"
          src={FAQ}
          alt="FAQ icon medium"
        />
        <Illustration
          {...args}
          variant="icon"
          size="lg"
          src={FAQ}
          alt="FAQ icon large"
        />
        <Illustration
          {...args}
          variant="icon"
          size="sm"
          src={FAQWithBackground}
          alt="FAQ with background icon small"
        />
        <Illustration
          {...args}
          variant="icon"
          size="md"
          src={FAQWithBackground}
          alt="FAQ with background icon medium"
        />
        <Illustration
          {...args}
          variant="icon"
          size="lg"
          src={FAQWithBackground}
          alt="FAQ with background icon large"
        />
      </div>
    )
  },
}

/**
 * You can make the illustration decorative by setting the `isDecorative` prop to `true`.
 * When `isDecorative` is `true`, `alt` becomes optional. Screen readers will ignore the illustration and not read the `alt` or the `description` attributes. Use this when the illustration is purely decorative or visual appeal, and does not provide any information.
 */
export const IsDecorative: Story = {
  args: {
    variant: 'picture',
    src: VisuallyImpaired,
    className: 'uy:size-[50vmin]',
    isDecorative: true,
  },
}

/**
 * You can create responsive layouts where illustrations adapt to different viewport sizes
 * by combining responsive Tailwind classes with the illustration component (with media and container queries). Use Unity theme
 * classes to configure how the illustration behaves across breakpoints.
 */
export const Responsive: Story = {
  render: () => {
    return (
      <div className="uy:rounded-150 uy:bg-surface-neutral uy:border-border-neutral uy:shadow-floating uy:p-300 uy:flex uy:flex-col uy:gap-200 uy:sm:flex-row uy:max-w-[50vmax]">
        <Illustration
          src={WriteBook}
          variant="picture"
          className="uy:size-full uy:sm:max-w-1/2 uy:md:max-w-1/4"
          alt="Write book illustration"
        />
        <div className="uy:space-y-200">
          <h2 className="uy:typography-h2">Title</h2>
          <p className="uy:typography-body">
            The image above has a different size depending on the viewport size.
            Use unity-themes classes to configure how the illustration behaves
          </p>
        </div>
      </div>
    )
  },
}

/**
 * Unity illustrations supports animated illustrations in WEBP format. All the animated illustrations have the `Animation` suffix on their name
 * Animated illustrations will grow fluidly depending on its container size but are capped at their original dimensions to prevent oversizing.
 */
export const AnimatedIllustrations: Story = {
  parameters: {
    chromatic: { disableSnapshot: true },
  },
  render: () => {
    return (
      <div className="uy:space-y-300">
        <div>
          <h3 className="uy:typography-h3 uy:mb-200">
            Large Animation (Fluid)
          </h3>
          <div className="uy:border uy:border-dashed uy:border-border-neutral uy:p-200 uy:rounded-100 uy:w-[50dvw]">
            <Illustration
              src={AccountingAnimation}
              variant="picture"
              alt="Accounting animation showing financial calculations"
            />
          </div>
          <p className="uy:typography-caption uy:text-content-tertiary uy:mt-100">
            Max dimensions: 969×852px • Scales down responsively
          </p>
        </div>

        <div>
          <h3 className="uy:typography-h3 uy:mb-200">
            Medium Animation (Fluid)
          </h3>
          <div className="uy:border uy:border-dashed uy:border-border-neutral uy:p-200 uy:rounded-100 uy:w-[25dvw]">
            <Illustration
              src={BinocularsAnimation}
              variant="picture"
              alt="Binoculars animation for search or discovery"
            />
          </div>
          <p className="uy:typography-caption uy:text-content-tertiary uy:mt-100">
            Max dimensions: 750×750px • Scales down responsively
          </p>
        </div>
        <div>
          <h3 className="uy:typography-h3 uy:mb-200">
            Small Animation (Fluid)
          </h3>
          <div className="uy:border uy:border-dashed uy:border-border-neutral uy:p-200 uy:rounded-100">
            <Illustration
              src={CardAnimation}
              variant="picture"
              alt="Card animation for payment or identification"
            />
          </div>
          <p className="uy:typography-caption uy:text-content-tertiary uy:mt-100">
            Max dimensions: 224×224px • Scales down responsively
          </p>
        </div>
      </div>
    )
  },
}
