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

import { PasswordInput } from "./index"
import { Typography } from "../Typography"
import type { MaterialIconProps } from "../Icons/MaterialIcon"
import { passwordValidator } from "@scandic-hotels/common/utils/zod/passwordValidator"

// Simple error formatter for Storybook
const defaultErrorFormatter = (
  _intl: IntlShape,
  errorMessage?: string
): string => errorMessage ?? ""

interface PasswordInputStoryProps {
  label?: string
  placeholder?: string
  disabled?: boolean
  visibilityToggleable?: boolean
  isNewPassword?: boolean
  required?: boolean
  errorMessage?: string
  defaultValue?: string
  description?: string
  descriptionIcon?: MaterialIconProps["icon"]
  autoComplete?: string
}

function PasswordInputComponent({
  label,
  placeholder,
  disabled = false,
  visibilityToggleable = true,
  isNewPassword = false,
  required = false,
  errorMessage,
  defaultValue = "",
  description,
  descriptionIcon = "info",
  autoComplete,
}: PasswordInputStoryProps) {
  const schema = z.object({
    password: errorMessage
      ? isNewPassword
        ? z.literal("").optional().or(passwordValidator())
        : z.string().min(1, errorMessage)
      : required
        ? isNewPassword
          ? passwordValidator()
          : z.string().min(1, "This field is required")
        : isNewPassword
          ? z.literal("").optional().or(passwordValidator())
          : z.string().optional(),
  })

  const methods = useForm<{ password: string }>({
    resolver: zodResolver(schema),
    defaultValues: {
      password: defaultValue,
    },
    mode: isNewPassword ? "all" : "onChange",
    criteriaMode: isNewPassword ? "all" : undefined,
    reValidateMode: isNewPassword ? "onChange" : undefined,
  })

  useEffect(() => {
    if (errorMessage && !isNewPassword) {
      methods.setError("password", {
        type: "manual",
        message: errorMessage,
      })
      methods.trigger("password")
    } else if (isNewPassword && defaultValue) {
      methods.trigger("password")
    } else {
      methods.clearErrors("password")
    }
  }, [errorMessage, methods, isNewPassword, defaultValue])

  return (
    <FormProvider {...methods}>
      <div style={{ padding: "1rem" }}>
        <PasswordInput
          name="password"
          label={label}
          placeholder={placeholder}
          disabled={disabled}
          visibilityToggleable={visibilityToggleable}
          isNewPassword={isNewPassword}
          registerOptions={required ? { required: true } : undefined}
          errorFormatter={defaultErrorFormatter}
          description={description}
          descriptionIcon={descriptionIcon}
          autoComplete={autoComplete}
        />
      </div>
    </FormProvider>
  )
}

const meta: Meta<typeof PasswordInputComponent> = {
  title: "Core Components/Input/PasswordInput",
  component: PasswordInputComponent,
  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,
      },
    },
    disabled: {
      control: "boolean",
      name: "Disabled",
      description: "Disabled state",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 3,
      },
    },
    visibilityToggleable: {
      control: "boolean",
      name: "Visibility Toggleable",
      description: "Show/hide password toggle button",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "true" },
        order: 4,
      },
    },
    isNewPassword: {
      control: "boolean",
      name: "Is New Password",
      description: "Enable new password validation",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 5,
      },
    },
    required: {
      control: "boolean",
      name: "Required",
      description: "Required field",
      table: {
        type: { summary: "boolean" },
        defaultValue: { summary: "false" },
        order: 6,
      },
    },
    errorMessage: {
      control: "text",
      name: "Error Message",
      description: "Error message (only for non-new-password fields)",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
        order: 7,
      },
    },
    defaultValue: {
      control: "text",
      name: "Default Value",
      description: "Default password value",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "''" },
        order: 8,
      },
    },
    description: {
      control: "text",
      name: "Description",
      description: "Helper text (hidden when error is shown)",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "undefined" },
        order: 9,
      },
    },
    descriptionIcon: {
      control: "select",
      name: "Description Icon",
      options: ["info", "warning", "error"],
      description: "Description icon",
      table: {
        type: { summary: "string" },
        defaultValue: { summary: "'info'" },
        order: 10,
      },
    },
    autoComplete: {
      control: "select",
      name: "Autocomplete",
      description:
        "HTML autocomplete attribute value. If not provided, automatically sets to 'new-password' when isNewPassword is true, or 'current-password' when isNewPassword is false.",
      options: [undefined, "current-password", "new-password", "off"],
      table: {
        type: { summary: "string" },
        defaultValue: {
          summary: "undefined (auto-set based on isNewPassword)",
        },
        order: 11,
      },
    },
  },
}

export default meta

type Story = StoryObj<typeof PasswordInputComponent>

export const Default: Story = {
  args: {
    label: undefined,
    placeholder: undefined,
    disabled: false,
    visibilityToggleable: true,
    isNewPassword: false,
    required: false,
    errorMessage: undefined,
    defaultValue: "",
    description: undefined,
    descriptionIcon: "info",
    autoComplete: undefined,
  },
}

// ============================================================================
// Password Validation Showcase
// ============================================================================

const showcasePasswordSchema = z.object({
  empty: z.literal("").optional().or(passwordValidator()),
  weak: passwordValidator(),
  partial: passwordValidator(),
  valid: passwordValidator(),
  tooLong: passwordValidator(),
})

type ShowcasePasswordFormData = z.infer<typeof showcasePasswordSchema>

function PasswordValidationShowcase() {
  const methods = useForm<ShowcasePasswordFormData>({
    resolver: zodResolver(showcasePasswordSchema),
    defaultValues: {
      empty: "",
      weak: "weak",
      partial: "Password1",
      valid: "ValidPassword123!",
      tooLong: "A".repeat(41) + "1!",
    },
    mode: "all",
    criteriaMode: "all",
    reValidateMode: "onChange",
  })

  // Trigger validation on mount to show validation states
  useEffect(() => {
    methods.trigger(["weak", "partial", "valid", "tooLong"])
  }, [methods])

  return (
    <FormProvider {...methods}>
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: "3rem",
          maxWidth: "800px",
          padding: "2rem",
        }}
      >
        <section>
          <Typography variant="Title/sm">
            <h2>Password Validation States</h2>
          </Typography>
          <div
            style={{
              display: "grid",
              gridTemplateColumns: "repeat(auto-fit, minmax(350px, 1fr))",
              gap: "2rem",
              marginTop: "1rem",
            }}
          >
            <div>
              <Typography variant="Body/Paragraph/mdRegular">
                <p>Empty Password</p>
              </Typography>
              <PasswordInput
                name="empty"
                isNewPassword
                errorFormatter={defaultErrorFormatter}
              />
            </div>

            <div>
              <Typography variant="Body/Paragraph/mdRegular">
                <p>Valid Password</p>
              </Typography>
              <PasswordInput
                name="valid"
                isNewPassword
                errorFormatter={defaultErrorFormatter}
              />
            </div>

            <div>
              <Typography variant="Body/Paragraph/mdRegular">
                <p>Too Short Password</p>
              </Typography>
              <PasswordInput
                name="weak"
                isNewPassword
                errorFormatter={defaultErrorFormatter}
              />
            </div>

            <div>
              <Typography variant="Body/Paragraph/mdRegular">
                <p>Too Long Password</p>
              </Typography>
              <PasswordInput
                name="tooLong"
                isNewPassword
                errorFormatter={defaultErrorFormatter}
              />
            </div>
          </div>
        </section>
      </div>
    </FormProvider>
  )
}

const showcaseMeta: Meta<typeof PasswordValidationShowcase> = {
  title: "Core Components/PasswordInput",
  component: PasswordValidationShowcase,
  parameters: {
    layout: "fullscreen",
  },
}

type ShowcaseStory = StoryObj<typeof PasswordValidationShowcase>

export const AllValidationStates: ShowcaseStory = {
  render: () => <PasswordValidationShowcase />,
  parameters: {
    ...showcaseMeta.parameters,
  },
}
