'use client'

import { useState, ChangeEvent, FormEvent } from 'react'
import toast from 'react-hot-toast'
import { ValidationRules, ValidationErrors } from '../types'

type FormValue = string | number | boolean | string[] | number[] | null

type CustomChangeEvent = {
  target: {
    id: string
    value: FormValue
    type?: string
    checked?: boolean
  }
}

export function useForm<T extends Record<string, FormValue>>(
  initialValues: T,
  validationRules?: { [K in keyof T]?: ValidationRules },
  onSubmit?: (values: T) => void
) {
  const [values, setValues] = useState<T>(initialValues)
  const [errors, setErrors] = useState<ValidationErrors>({})
  const [isVisible, setIsVisible] = useState(false)

  const handleChange = (
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> | CustomChangeEvent
  ) => {
    const { id, value, type } = e.target
    const isCheckbox = type === 'checkbox' && 'checked' in e.target

    setValues(prev => ({
      ...prev,
      [id]: isCheckbox ? (e.target as HTMLInputElement).checked : value,
    }))

    // скидываем ошибки
    if (errors[id]) {
      setErrors(prev => {
        const newErrors = { ...prev }
        delete newErrors[id]
        return newErrors
      })
    }
  }

  const resetField = (fieldName: keyof T, value: FormValue = '') => {
    setValues(prev => ({
      ...prev,
      [fieldName]: value,
    }))

    // очищаем ошибки для этого поля, если они есть
    if (errors[fieldName as string]) {
      setErrors(prev => {
        const newErrors = { ...prev }
        delete newErrors[fieldName as string]
        return newErrors
      })
    }
  }

  const fieldNames: { [key: string]: string } = {
    login: 'Логин',
    password: 'Пароль',
    accountType: 'Роль',
  }

  const validate = () => {
    if (!validationRules) return true

    const newErrors: ValidationErrors = {}

    Object.keys(validationRules).forEach(key => {
      const value = values[key]
      const rules = validationRules[key as keyof T]

      if (rules?.required && !value) {
        newErrors[key] = 'Это поле обязательно'
        toast.error(`Поле "${fieldNames[key] || key}" обязательно для заполнения`, {
          duration: 2000,
          position: 'top-right',
          style: {
            background: '#FEE2E2',
            color: '#991B1B',
            padding: '16px',
            borderRadius: '8px',
          },
        })
      }

      if (rules?.minLength && typeof value === 'string' && value.length < rules.minLength) {
        newErrors[key] = `Минимальная длина ${rules.minLength} символов`
        toast.error(
          `Минимальная длина поля "${fieldNames[key] || key}" - ${rules.minLength} символов`,
          {
            duration: 2000,
            position: 'top-right',
            style: {
              background: '#FEE2E2',
              color: '#991B1B',
              padding: '16px',
              borderRadius: '8px',
            },
          }
        )
      }

      if (rules?.pattern && typeof value === 'string' && !rules.pattern.test(value)) {
        newErrors[key] = 'Неверный формат'
        toast.error(`Поле "${fieldNames[key] || key}" заполнено некорректно`, {
          duration: 2000,
          position: 'top-right',
          style: {
            background: '#FEE2E2',
            color: '#991B1B',
            padding: '16px',
            borderRadius: '8px',
          },
        })
      }
    })

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleSubmit = (e: FormEvent) => {
    e.preventDefault()
    if (validate() && onSubmit) {
      onSubmit(values)
    }
  }

  const togglePasswordVisibility = () => {
    setIsVisible(!isVisible)
  }

  return {
    values,
    errors,
    isVisible,
    setValues,
    handleChange,
    handleSubmit,
    togglePasswordVisibility,
    resetField,
  }
}
