import { zodResolver } from "@hookform/resolvers/zod"
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
import { useEffect } from "react"
import { FormProvider, useForm } from "react-hook-form"
import { z } from "zod"

import { FormTextArea } from "../Form/FormTextArea"
import type { MaterialIconProps } from "../Icons/MaterialIcon"

interface FormTextAreaStoryProps {
  label?: string
  placeholder?: string
  description?: string
  descriptionIcon?: MaterialIconProps["icon"]
  disabled?: boolean
  readOnly?: boolean
  required?: boolean
  showLabel?: boolean
  showDescription?: boolean
  showDescriptionIcon?: boolean
  filled?: boolean
  defaultValue?: string
  errorMessage?: string
  name?: string
}

function FormTextAreaComponent({
  label,
  placeholder,
  description,
  descriptionIcon = "info",
  disabled = false,
  readOnly = false,
  required = false,
  showLabel = true,
  showDescription = true,
  showDescriptionIcon = true,
  filled = false,
  defaultValue = "",
  errorMessage,
  name = "textarea",
}: FormTextAreaStoryProps) {
  const schema = z.object({
    [name]: errorMessage
      ? z.string().min(1, errorMessage)
      : required
        ? z.string().min(1, "This field is required")
        : z.string().optional(),
  })

  const methods = useForm<{ [key: string]: string }>({
    resolver: zodResolver(schema),
    defaultValues: {
      [name]: filled ? defaultValue : "",
    },
    mode: "onChange",
  })

  useEffect(() => {
    if (errorMessage) {
      // Set error manually if errorMessage is provided
      methods.setError(name, {
        type: "manual",
        message: errorMessage,
      })
      // Trigger validation to show the error immediately
      methods.trigger(name)
    } else {
      // Clear errors if errorMessage is removed
      methods.clearErrors(name)
    }
  }, [errorMessage, methods, name])

  return (
    <FormProvider {...methods}>
      <div style={{ maxWidth: "500px", padding: "1rem" }}>
        <FormTextArea
          name={name}
          label={showLabel ? label : undefined}
          placeholder={placeholder}
          description={showDescription ? description : undefined}
          descriptionIcon={showDescriptionIcon ? descriptionIcon : undefined}
          disabled={disabled}
          readOnly={readOnly}
          registerOptions={required ? { required: true } : undefined}
        />
      </div>
    </FormProvider>
  )
}

const meta: Meta<typeof FormTextAreaComponent> = {
  title: "Core Components/TextArea",
  component: FormTextAreaComponent,
  argTypes: {
    label: {
      control: "text",
      description: "The label text displayed above the textarea field",
      table: {
        type: { summary: "string" },
      },
    },
    placeholder: {
      control: "text",
      description: "Placeholder text shown when textarea is empty",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
      },
    },
    description: {
      control: "text",
      description: "Supporting text displayed below the textarea",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
      },
    },

    disabled: {
      control: "boolean",
      description: "Whether the textarea is disabled",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    readOnly: {
      control: "boolean",
      description: "Whether the textarea is read-only",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    required: {
      control: "boolean",
      description: "Whether the textarea is required",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
      },
    },
    showLabel: {
      control: "boolean",
      description: "Whether to show the label",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "true" },
      },
    },
    showDescription: {
      control: "boolean",
      description: "Whether to show the description/supporting text",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "true" },
      },
    },
    defaultValue: {
      control: "text",
      description: "Default value when filled is true",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "" },
      },
    },
    errorMessage: {
      control: "text",
      description: "Error message to display (triggers error state)",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
      },
    },
  },
}

export default meta

type Story = StoryObj<typeof FormTextAreaComponent>

export const Default: Story = {
  args: {
    label: "Label",
    placeholder: "Placeholder",
    description: "Supporting text",
    disabled: false,
    readOnly: false,
    required: false,
    showLabel: true,
    showDescription: true,
    defaultValue: "",
    errorMessage: undefined,
  },
}
