import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { fn } from 'storybook/test'
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 { Button } from '../Button'
import { Typography } from '../Typography'
import { passwordValidator } from '@scandic-hotels/common/utils/zod/passwordValidator'

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

// ============================================================================
// Password Form with New Password Validation
// ============================================================================

const passwordFormSchema = z
  .object({
    currentPassword: z.string().optional(),
    newPassword: z.literal('').optional().or(passwordValidator()),
    confirmPassword: z.string().optional(),
  })
  .superRefine((data, ctx) => {
    if (data.newPassword && data.newPassword !== data.confirmPassword) {
      ctx.addIssue({
        code: 'custom',
        message: 'Passwords do not match',
        path: ['confirmPassword'],
      })
    }
  })

type PasswordFormData = z.infer<typeof passwordFormSchema>

interface PasswordInputProps {
  onSubmit?: (data: PasswordFormData) => void
  showErrors?: boolean
  defaultNewPassword?: string
}

function PasswordInputComponent({
  onSubmit,
  showErrors = false,
  defaultNewPassword = '',
}: PasswordInputProps) {
  const methods = useForm<PasswordFormData>({
    resolver: zodResolver(passwordFormSchema),
    defaultValues: {
      currentPassword: '',
      newPassword: defaultNewPassword,
      confirmPassword: '',
    },
    mode: 'all',
    criteriaMode: 'all',
    reValidateMode: 'onChange',
  })

  // Trigger validation on mount if showErrors is true
  useEffect(() => {
    if (showErrors) {
      methods.trigger()
    }
  }, [showErrors, methods])

  const handleSubmit = methods.handleSubmit((data) => {
    onSubmit?.(data)
  })

  return (
    <FormProvider {...methods}>
      <form
        onSubmit={handleSubmit}
        style={{
          display: 'flex',
          flexDirection: 'column',
          gap: '1.5rem',
          maxWidth: '500px',
        }}
      >
        <Typography variant="Title/md">
          <h2>Change Password</h2>
        </Typography>

        <PasswordInput
          name="currentPassword"
          label="Current password"
          errorFormatter={defaultErrorFormatter}
        />

        <PasswordInput
          name="newPassword"
          isNewPassword
          errorFormatter={defaultErrorFormatter}
        />

        <PasswordInput
          name="confirmPassword"
          label="Confirm new password"
          errorFormatter={defaultErrorFormatter}
        />

        <Button type="submit" variant="Primary" size="lg">
          Update password
        </Button>
      </form>
    </FormProvider>
  )
}

const passwordFormMeta: Meta<typeof PasswordInputComponent> = {
  title: 'Core Components/PasswordInput',
  component: PasswordInputComponent,
  parameters: {
    layout: 'padded',
  },
  argTypes: {
    showErrors: {
      control: 'boolean',
      description: 'Show validation errors on mount',
    },
    defaultNewPassword: {
      control: 'text',
      description: 'Default value for new password field',
    },
  },
}

export default passwordFormMeta

type PasswordFormStory = StoryObj<typeof PasswordInputComponent>

export const Default: PasswordFormStory = {
  render: (args) => <PasswordInputComponent {...args} />,
  args: {
    onSubmit: fn(),
    showErrors: false,
    defaultNewPassword: '',
  },
}

// ============================================================================
// 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/md">
            <h2>New 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>Weak Password (too short)</p>
              </Typography>
              <PasswordInput
                name="weak"
                isNewPassword
                errorFormatter={defaultErrorFormatter}
              />
            </div>

            <div>
              <Typography variant="Body/Paragraph/mdRegular">
                <p>Partial Password (missing requirements)</p>
              </Typography>
              <PasswordInput
                name="partial"
                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 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,
  },
}
