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"
import { Typography } from "../Typography"

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/Input/TextArea",
  component: FormTextAreaComponent,
  argTypes: {
    label: {
      control: "text",
      name: "Label",
      description: "Label text",
      table: {
        type: { summary: "string" },
        order: 1,
      },
    },
    placeholder: {
      control: "text",
      name: "Placeholder",
      description: "Placeholder text",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
        order: 2,
      },
    },
    showDescription: {
      control: "boolean",
      name: "Show Description",
      description: "Show description",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "true" },
        order: 3,
      },
    },
    description: {
      control: "text",
      name: "Description",
      description: "Helper text (hidden when error is shown)",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
        order: 4,
      },
    },
    descriptionIcon: {
      control: "select",
      name: "Description Icon",
      options: ["info", "warning", "error"],
      description: "Description icon",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "'info'" },
        order: 5,
      },
    },
    required: {
      control: "boolean",
      name: "Required",
      description: "Required field",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 6,
      },
    },
    disabled: {
      control: "boolean",
      name: "Disabled",
      description: "Disabled state",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 7,
      },
    },
    readOnly: {
      control: "boolean",
      name: "Read Only",
      description: "Read-only state",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 8,
      },
    },
    showLabel: {
      control: "boolean",
      name: "Show Label",
      description: "Show label",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "true" },
        order: 9,
      },
    },
    errorMessage: {
      control: "text",
      name: "Error Message",
      description: "Error message",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
        order: 10,
      },
    },
  },
}

export default meta

type Story = StoryObj<typeof FormTextAreaComponent>

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

// ============================================================================
// TextArea Variations Showcase
// ============================================================================

const showcaseSchema = z.object({
  default: z.string().optional(),
  placeholder: z.string().optional(),
  withDescription: z.string().optional(),
  withDescriptionPlaceholder: z.string().optional(),
  filled: z.string().optional(),
  required: z.string().min(1, "This field is required"),
  disabled: z.string().optional(),
  disabledFilled: z.string().optional(),
  error: z.string().min(10, "Must be at least 10 characters"),
  errorFilled: z.string().min(10, "Invalid content"),
  descriptionInfo: z.string().optional(),
  descriptionWarning: z.string().optional(),
})

type ShowcaseFormData = z.infer<typeof showcaseSchema>

function TextAreaShowcase() {
  const methods = useForm<ShowcaseFormData>({
    resolver: zodResolver(showcaseSchema),
    defaultValues: {
      filled:
        "This is a sample text that fills the textarea with some content.",
      disabledFilled: "This textarea is disabled and cannot be edited.",
      error: "Short",
      errorFilled: "Invalid content",
    },
    mode: "onChange",
  })

  // Trigger validation for error examples on mount
  useEffect(() => {
    methods.trigger(["error", "errorFilled"])
  }, [methods])

  return (
    <FormProvider {...methods}>
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: "3rem",
          maxWidth: "800px",
          padding: "2rem",
        }}
      >
        {/* Basic States */}
        <section>
          <Typography variant="Title/sm">
            <h2>Basic States</h2>
          </Typography>
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
              gap: "1.5rem",
              marginTop: "1rem",
            }}
          >
            <FormTextArea name="default" label="Default" />
            <FormTextArea
              name="placeholder"
              label="Placeholder"
              placeholder="Enter your message here..."
            />
            <FormTextArea
              name="withDescription"
              label="With Description"
              description="This is a default textarea with a description"
            />
            <FormTextArea
              name="withDescriptionPlaceholder"
              label="With Description"
              placeholder="Enter your message here..."
              description="This is a default textarea with a description"
            />
            <FormTextArea name="filled" label="Filled" />
            <FormTextArea
              name="required"
              label="Required"
              registerOptions={{ required: true }}
              hideError
            />
            <FormTextArea name="disabled" label="Disabled" disabled />
            <FormTextArea
              name="disabledFilled"
              label="Disabled Filled"
              disabled
            />
          </div>
        </section>

        {/* Supporting Text Variations */}
        <section>
          <Typography variant="Title/sm">
            <h2>Supporting Text</h2>
          </Typography>
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
              gap: "1.5rem",
              marginTop: "1rem",
            }}
          >
            <FormTextArea
              name="descriptionInfo"
              label="Info Description"
              description="This is an informational message"
              descriptionIcon="info"
            />
            <FormTextArea
              name="descriptionWarning"
              label="Warning Description"
              description="This is a warning message"
              descriptionIcon="warning"
            />
          </div>
        </section>

        {/* Validation States */}
        <section>
          <Typography variant="Title/sm">
            <h2>Validation States</h2>
          </Typography>
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))",
              gap: "1.5rem",
              marginTop: "1rem",
            }}
          >
            <FormTextArea
              name="error"
              label="Error State"
              registerOptions={{ minLength: 10 }}
            />
          </div>
        </section>
      </div>
    </FormProvider>
  )
}

export const AllVariations: StoryObj<typeof TextAreaShowcase> = {
  render: () => <TextAreaShowcase />,
  parameters: {
    layout: "fullscreen",
  },
}
