import React, { useEffect, useMemo, useRef, useState } from 'react'
import { usePage } from '@inertiajs/react'
import SettingsLayout from '../../Layouts/SettingsLayout'
import TextInput from '../../components/ui/TextInput'
import Textarea from '../../components/ui/Textarea'
import Button from '../../components/ui/Button'
import Toggle from '../../components/ui/Toggle'
import Select from '../../components/ui/Select'
import Modal from '../../components/ui/Modal'
import { RadioGroup } from '../../components/ui/Radio'
import { buildBotFingerprint } from '../../lib/security/botFingerprint'
import TurnstileField from '../../components/security/TurnstileField'

const SETTINGS_SECTIONS = [
  { key: 'profile', label: 'Profile', icon: 'fa-solid fa-user-astronaut', description: 'Public identity and avatar.' },
  { key: 'account', label: 'Account', icon: 'fa-solid fa-id-badge', description: 'Username and email address.' },
  { key: 'personal', label: 'Personal', icon: 'fa-solid fa-address-card', description: 'Optional personal information.' },
  { key: 'notifications', label: 'Notifications', icon: 'fa-solid fa-bell', description: 'Manage notification preferences.' },
  { key: 'security', label: 'Security', icon: 'fa-solid fa-shield-halved', description: 'Password and account security.' },
  { key: 'danger', label: 'Danger Zone', icon: 'fa-solid fa-triangle-exclamation', description: 'Destructive account actions.' },
]

const MONTHS = [
  { value: '1', label: 'January' },
  { value: '2', label: 'February' },
  { value: '3', label: 'March' },
  { value: '4', label: 'April' },
  { value: '5', label: 'May' },
  { value: '6', label: 'June' },
  { value: '7', label: 'July' },
  { value: '8', label: 'August' },
  { value: '9', label: 'September' },
  { value: '10', label: 'October' },
  { value: '11', label: 'November' },
  { value: '12', label: 'December' },
]

const GENDER_OPTIONS = [
  { value: 'm', label: 'Male' },
  { value: 'f', label: 'Female' },
  { value: 'x', label: 'Prefer not to say' },
]

const AVATAR_POSITION_OPTIONS = [
  { value: 'top-left', label: 'Top Left' },
  { value: 'top', label: 'Top' },
  { value: 'top-right', label: 'Top Right' },
  { value: 'left', label: 'Left' },
  { value: 'center', label: 'Center' },
  { value: 'right', label: 'Right' },
  { value: 'bottom-left', label: 'Bottom Left' },
  { value: 'bottom', label: 'Bottom' },
  { value: 'bottom-right', label: 'Bottom Right' },
]

const USERNAME_REGEX = /^[a-zA-Z0-9_]{3,20}$/

function getCsrfToken() {
  return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''
}

async function botHeaders(extra = {}, captcha = {}) {
  const fingerprint = await buildBotFingerprint()

  return {
    ...extra,
    'X-Bot-Fingerprint': fingerprint,
    ...(captcha?.token ? { 'X-Captcha-Token': captcha.token } : {}),
  }
}

function toIsoDate(day, month, year) {
  if (!day || !month || !year) return ''
  return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
}

function fromIsoDate(iso) {
  if (!iso || typeof iso !== 'string' || !iso.includes('-')) {
    return { day: '', month: '', year: '' }
  }

  const [year, month, day] = iso.split('-')
  return {
    day: String(parseInt(day || '', 10) || ''),
    month: String(parseInt(month || '', 10) || ''),
    year: String(year || ''),
  }
}

function equalsObject(a, b) {
  return JSON.stringify(a) === JSON.stringify(b)
}

function positionToObjectPosition(position) {
  const map = {
    'top-left': '0% 0%',
    top: '50% 0%',
    'top-right': '100% 0%',
    left: '0% 50%',
    center: '50% 50%',
    right: '100% 50%',
    'bottom-left': '0% 100%',
    bottom: '50% 100%',
    'bottom-right': '100% 100%',
  }

  return map[position] || '50% 50%'
}

function SectionCard({ title, description, children, actionSlot }) {
  return (
    <section className="rounded-xl border border-white/5 bg-white/[0.03] p-6">
      <header className="flex flex-col gap-3 border-b border-white/5 pb-4 md:flex-row md:items-start md:justify-between">
        <div>
          <h2 className="text-base font-semibold text-white">{title}</h2>
          {description ? <p className="mt-1 text-sm text-slate-400">{description}</p> : null}
        </div>
        {actionSlot ? <div>{actionSlot}</div> : null}
      </header>
      <div className="pt-5">{children}</div>
    </section>
  )
}

export default function ProfileEdit() {
  const { props } = usePage()
  const {
    user,
    avatarUrl: initialAvatarUrl,
    birthDay,
    birthMonth,
    birthYear,
    countries = [],
    usernameCooldownDays = 30,
    usernameCooldownRemainingDays = 0,
    usernameCooldownActive = false,
    captcha: initialCaptcha = {},
    flash = {},
  } = props

  const fallbackDate = toIsoDate(
    birthDay ? parseInt(String(birthDay), 10) : '',
    birthMonth ? parseInt(String(birthMonth), 10) : '',
    birthYear ? String(birthYear) : '',
  )

  const [activeSection, setActiveSection] = useState('profile')

  const [profileForm, setProfileForm] = useState({
    display_name: user?.name || '',
    website: user?.homepage || '',
    bio: user?.about_me || '',
    signature: user?.signature || '',
    description: user?.description || '',
  })
  const [accountForm, setAccountForm] = useState({
    username: user?.username || '',
    email: user?.email || '',
  })
  const [usernameAvailability, setUsernameAvailability] = useState({
    status: 'idle',
    message: '',
  })
  const [showEmailChangeModal, setShowEmailChangeModal] = useState(false)
  const [emailChangeStep, setEmailChangeStep] = useState('request')
  const [emailChangeLoading, setEmailChangeLoading] = useState(false)
  const [emailChangeForm, setEmailChangeForm] = useState({
    new_email: '',
    code: '',
  })
  const [emailChangeError, setEmailChangeError] = useState('')
  const [emailChangeInfo, setEmailChangeInfo] = useState('')
  const [personalForm, setPersonalForm] = useState(() => {
    const fromUser = fromIsoDate(user?.birthday || '')
    const fromProps = {
      day: birthDay ? String(parseInt(String(birthDay), 10) || '') : '',
      month: birthMonth ? String(parseInt(String(birthMonth), 10) || '') : '',
      year: birthYear ? String(birthYear) : '',
    }

    return {
      day: fromUser.day || fromProps.day || '',
      month: fromUser.month || fromProps.month || '',
      year: fromUser.year || fromProps.year || '',
      gender: String(user?.gender || '').toLowerCase() || '',
      country: user?.country_code || '',
    }
  })
  const [notificationForm, setNotificationForm] = useState({
    email_notifications: !!user?.email_notifications,
    upload_notifications: !!user?.upload_notifications,
    follower_notifications: !!user?.follower_notifications,
    comment_notifications: !!user?.comment_notifications,
    newsletter: !!user?.newsletter,
  })
  const [securityForm, setSecurityForm] = useState({
    current_password: '',
    new_password: '',
    new_password_confirmation: '',
  })

  const [savingSection, setSavingSection] = useState('')
  const [savedMessage, setSavedMessage] = useState({ section: '', text: '' })
  const [errorsBySection, setErrorsBySection] = useState({
    profile: {},
    account: {},
    personal: {},
    notifications: {},
    security: {},
  })
  const [captchaState, setCaptchaState] = useState({
    required: !!flash?.botCaptchaRequired,
    section: '',
    token: '',
    message: '',
    nonce: 0,
    provider: initialCaptcha?.provider || '',
    siteKey: initialCaptcha?.siteKey || '',
    inputName: initialCaptcha?.inputName || 'cf-turnstile-response',
    scriptUrl: initialCaptcha?.scriptUrl || '',
  })

  const [avatarUrl, setAvatarUrl] = useState(initialAvatarUrl || '')
  const [avatarFile, setAvatarFile] = useState(null)
  const [avatarPosition, setAvatarPosition] = useState('center')
  const [dragActive, setDragActive] = useState(false)
  const [removeAvatar, setRemoveAvatar] = useState(false)
  const avatarInputRef = useRef(null)

  const [showDeleteModal, setShowDeleteModal] = useState(false)
  const [deletePassword, setDeletePassword] = useState('')
  const [deleteError, setDeleteError] = useState('')
  const [deleting, setDeleting] = useState(false)

  const initialRef = useRef({
    profileForm,
    accountForm,
    personalForm,
    notificationForm,
    avatarUrl: initialAvatarUrl || '',
  })

  const dirtyMap = useMemo(() => {
    return {
      profile:
        !equalsObject(profileForm, initialRef.current.profileForm) ||
        !!avatarFile ||
        (avatarFile && avatarPosition !== 'center') ||
        removeAvatar ||
        avatarUrl !== initialRef.current.avatarUrl,
      account: !equalsObject(accountForm, initialRef.current.accountForm),
      personal: !equalsObject(personalForm, initialRef.current.personalForm),
      notifications: !equalsObject(notificationForm, initialRef.current.notificationForm),
      security:
        !!securityForm.current_password ||
        !!securityForm.new_password ||
        !!securityForm.new_password_confirmation,
      danger: false,
    }
  }, [profileForm, accountForm, personalForm, notificationForm, securityForm, avatarFile, avatarPosition, removeAvatar, avatarUrl])

  const hasUnsavedChanges = useMemo(
    () => Object.entries(dirtyMap).some(([key, dirty]) => key !== 'danger' && dirty),
    [dirtyMap],
  )

  useEffect(() => {
    const beforeUnload = (event) => {
      if (!hasUnsavedChanges) return
      event.preventDefault()
      event.returnValue = ''
    }

    window.addEventListener('beforeunload', beforeUnload)
    return () => window.removeEventListener('beforeunload', beforeUnload)
  }, [hasUnsavedChanges])

  useEffect(() => {
    if (usernameCooldownActive) {
      setUsernameAvailability({ status: 'idle', message: '' })
      return
    }

    const candidate = String(accountForm.username || '').trim().toLowerCase()
    const current = String(initialRef.current.accountForm.username || '').trim().toLowerCase()

    if (!candidate || candidate === current) {
      setUsernameAvailability({ status: 'idle', message: '' })
      return
    }

    if (!USERNAME_REGEX.test(candidate)) {
      setUsernameAvailability({ status: 'invalid', message: 'Use 3-20 letters, numbers, or underscores.' })
      return
    }

    setUsernameAvailability({ status: 'checking', message: 'Checking availability...' })

    const controller = new AbortController()
    const timeout = window.setTimeout(async () => {
      try {
        const response = await fetch(`/api/username/check?username=${encodeURIComponent(candidate)}`, {
          credentials: 'same-origin',
          headers: { Accept: 'application/json' },
          signal: controller.signal,
        })

        const payload = await response.json().catch(() => ({}))
        if (!response.ok) {
          const msg = payload?.errors?.username?.[0] || 'Username is not available.'
          setUsernameAvailability({ status: 'invalid', message: msg })
          return
        }

        if (payload.available) {
          setUsernameAvailability({ status: 'available', message: 'Username is available.' })
          return
        }

        setUsernameAvailability({ status: 'taken', message: 'Username is already taken.' })
      } catch (error) {
        if (error?.name !== 'AbortError') {
          setUsernameAvailability({ status: 'invalid', message: 'Unable to check username right now.' })
        }
      }
    }, 300)

    return () => {
      controller.abort()
      window.clearTimeout(timeout)
    }
  }, [accountForm.username, usernameCooldownActive])

  const openEmailChangeModal = () => {
    setShowEmailChangeModal(true)
    setEmailChangeStep('request')
    setEmailChangeError('')
    setEmailChangeInfo('')
    setEmailChangeForm({ new_email: '', code: '' })
  }

  const closeEmailChangeModal = () => {
    if (emailChangeLoading) return
    setShowEmailChangeModal(false)
    setEmailChangeStep('request')
    setEmailChangeError('')
    setEmailChangeInfo('')
    setEmailChangeForm({ new_email: '', code: '' })
  }

  const countryOptions = (countries || []).map((c) => ({
    value: c.country_code || c.code || c.id || '',
    label: c.country_name || c.name || '',
  }))

  const yearOptions = useMemo(() => {
    const current = new Date().getFullYear()
    return Array.from({ length: 100 }, (_, index) => {
      const year = String(current - index)
      return { value: year, label: year }
    })
  }, [])

  const dayOptions = useMemo(
    () => Array.from({ length: 31 }, (_, i) => ({ value: String(i + 1), label: String(i + 1) })),
    [],
  )

  const clearSectionStatus = (section) => {
    setSavedMessage((prev) => (prev.section === section ? { section: '', text: '' } : prev))
    setErrorsBySection((prev) => ({ ...prev, [section]: {} }))
  }

  const resetCaptchaState = () => {
    setCaptchaState((prev) => ({
      ...prev,
      required: false,
      section: '',
      token: '',
      message: '',
      nonce: prev.nonce + 1,
    }))
  }

  const captureCaptchaRequirement = (section, payload = {}) => {
    const requiresCaptcha = !!(payload?.requires_captcha || payload?.requiresCaptcha)

    if (!requiresCaptcha) {
      return false
    }

    const nextCaptcha = payload?.captcha || {}
    const message = payload?.errors?.captcha?.[0] || payload?.message || 'Complete the captcha challenge to continue.'

    setCaptchaState((prev) => ({
      required: true,
      section,
      token: '',
      message,
      nonce: prev.nonce + 1,
      provider: nextCaptcha.provider || payload?.captcha_provider || prev.provider || initialCaptcha?.provider || 'turnstile',
      siteKey: nextCaptcha.siteKey || payload?.captcha_site_key || prev.siteKey || initialCaptcha?.siteKey || '',
      inputName: nextCaptcha.inputName || payload?.captcha_input || prev.inputName || initialCaptcha?.inputName || 'cf-turnstile-response',
      scriptUrl: nextCaptcha.scriptUrl || payload?.captcha_script_url || prev.scriptUrl || initialCaptcha?.scriptUrl || '',
    }))

    updateSectionErrors(section, {
      _general: [message],
      captcha: [message],
    })

    return true
  }

  const applyCaptchaPayload = (payload = {}) => {
    if (!captchaState.required || !captchaState.inputName) {
      return payload
    }

    return {
      ...payload,
      [captchaState.inputName]: captchaState.token || '',
    }
  }

  const applyCaptchaFormData = (formData) => {
    if (captchaState.required && captchaState.inputName) {
      formData.set(captchaState.inputName, captchaState.token || '')
    }
  }

  const renderCaptchaChallenge = (section, placement = 'section') => {
    if (!captchaState.required || !captchaState.siteKey || activeSection !== section) {
      return null
    }

    if (section === 'account' && showEmailChangeModal && placement !== 'modal') {
      return null
    }

    if (section === 'account' && !showEmailChangeModal && placement === 'modal') {
      return null
    }

    return (
      <div className="rounded-xl border border-amber-400/20 bg-amber-500/10 p-4">
        <p className="mb-3 text-sm text-amber-100">{captchaState.message || 'Complete the captcha challenge to continue.'}</p>
        <TurnstileField
          key={`${section}-${placement}-${captchaState.nonce}`}
          provider={captchaState.provider}
          siteKey={captchaState.siteKey}
          scriptUrl={captchaState.scriptUrl}
          onToken={(token) => setCaptchaState((prev) => ({ ...prev, token }))}
          className="rounded-lg border border-white/10 bg-black/20 p-3"
        />
      </div>
    )
  }

  const switchSection = (nextSection) => {
    if (activeSection === nextSection) return
    if (dirtyMap[activeSection]) {
      const shouldContinue = window.confirm('You have unsaved changes in this section. Leave without saving?')
      if (!shouldContinue) return
    }
    setActiveSection(nextSection)
  }

  const handleAvatarSelect = (file) => {
    if (!file) return
    if (!file.type.startsWith('image/')) return
    setAvatarFile(file)
    setRemoveAvatar(false)
    setAvatarUrl(URL.createObjectURL(file))
    clearSectionStatus('profile')
  }

  const dragHandler = (event) => {
    event.preventDefault()
    event.stopPropagation()
  }

  const handleDrop = (event) => {
    dragHandler(event)
    setDragActive(false)
    const file = event.dataTransfer?.files?.[0]
    if (file) handleAvatarSelect(file)
  }

  const updateSectionErrors = (section, errors = {}) => {
    setErrorsBySection((prev) => ({ ...prev, [section]: errors }))
  }

  const saveProfileSection = async (event) => {
    event.preventDefault()
    setSavingSection('profile')
    clearSectionStatus('profile')

    try {
      const formData = new FormData()
      formData.append('display_name', profileForm.display_name || '')
      formData.append('website', profileForm.website || '')
      formData.append('bio', profileForm.bio || '')
      formData.append('signature', profileForm.signature || '')
      formData.append('description', profileForm.description || '')
      formData.append('remove_avatar', removeAvatar ? '1' : '0')
      formData.append('avatar_position', avatarPosition)
      if (avatarFile) {
        formData.append('avatar', avatarFile)
      }
      applyCaptchaFormData(formData)

      const response = await fetch('/settings/profile/update', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: formData,
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('profile', payload)) {
          return
        }
        updateSectionErrors('profile', payload.errors || { _general: [payload.message || 'Unable to save profile section.'] })
        return
      }

      const nextAvatarUrl = payload.avatarUrl || avatarUrl || initialAvatarUrl
      initialRef.current.profileForm = { ...profileForm }
      initialRef.current.avatarUrl = nextAvatarUrl || ''
      setAvatarUrl(nextAvatarUrl || '')
      setAvatarFile(null)
      setAvatarPosition('center')
      setRemoveAvatar(false)
      resetCaptchaState()
      setSavedMessage({ section: 'profile', text: payload.message || 'Profile updated successfully.' })
    } catch (error) {
      updateSectionErrors('profile', { _general: ['Request failed. Please try again.'] })
    } finally {
      setSavingSection('')
    }
  }

  const saveAccountSection = async (event) => {
    event.preventDefault()

    if (usernameCooldownActive && accountForm.username !== initialRef.current.accountForm.username) {
      updateSectionErrors('account', {
        username: [`Username can be changed again in ${usernameCooldownRemainingDays} days.`],
      })
      return
    }

    setSavingSection('account')
    clearSectionStatus('account')

    try {
      const response = await fetch('/settings/account/username', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({ username: accountForm.username, homepage_url: '' })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('account', payload)) {
          return
        }
        updateSectionErrors('account', payload.errors || { _general: [payload.message || 'Unable to save account section.'] })
        return
      }

      initialRef.current.accountForm = { ...accountForm }
      resetCaptchaState()
      setSavedMessage({ section: 'account', text: payload.message || 'Account updated successfully.' })
    } catch (error) {
      updateSectionErrors('account', { _general: ['Request failed. Please try again.'] })
    } finally {
      setSavingSection('')
    }
  }

  const requestEmailChange = async () => {
    setEmailChangeLoading(true)
    setEmailChangeError('')
    setEmailChangeInfo('')

    try {
      const response = await fetch('/settings/email/request', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({ new_email: emailChangeForm.new_email, homepage_url: '' })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('account', payload)) {
          setEmailChangeError(payload?.errors?.captcha?.[0] || payload?.message || 'Complete the captcha challenge to continue.')
          return
        }
        setEmailChangeError(payload?.errors?.new_email?.[0] || payload?.message || 'Unable to request email change.')
        return
      }

      setEmailChangeStep('verify')
      resetCaptchaState()
      setEmailChangeInfo(payload.message || 'Verification code sent to your new email address.')
    } catch (error) {
      setEmailChangeError('Request failed. Please try again.')
    } finally {
      setEmailChangeLoading(false)
    }
  }

  const verifyEmailChange = async () => {
    setEmailChangeLoading(true)
    setEmailChangeError('')
    setEmailChangeInfo('')

    try {
      const response = await fetch('/settings/email/verify', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({ code: emailChangeForm.code, homepage_url: '' })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('account', payload)) {
          setEmailChangeError(payload?.errors?.captcha?.[0] || payload?.message || 'Complete the captcha challenge to continue.')
          return
        }
        setEmailChangeError(payload?.errors?.code?.[0] || payload?.message || 'Verification failed.')
        return
      }

      const nextEmail = payload.email || emailChangeForm.new_email
      setAccountForm((prev) => ({ ...prev, email: nextEmail }))
      initialRef.current.accountForm = { ...initialRef.current.accountForm, email: nextEmail }
      setShowEmailChangeModal(false)
      setEmailChangeStep('request')
      setEmailChangeForm({ new_email: '', code: '' })
      resetCaptchaState()
      setSavedMessage({ section: 'account', text: payload.message || 'Email updated successfully.' })
    } catch (error) {
      setEmailChangeError('Request failed. Please try again.')
    } finally {
      setEmailChangeLoading(false)
    }
  }

  const savePersonalSection = async (event) => {
    event.preventDefault()
    setSavingSection('personal')
    clearSectionStatus('personal')

    try {
      const response = await fetch('/settings/personal/update', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({
          birthday: toIsoDate(personalForm.day, personalForm.month, personalForm.year) || null,
          gender: personalForm.gender || null,
          country: personalForm.country || null,
          homepage_url: '',
        })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('personal', payload)) {
          return
        }
        updateSectionErrors('personal', payload.errors || { _general: [payload.message || 'Unable to save personal details.'] })
        return
      }

      initialRef.current.personalForm = { ...personalForm }
      resetCaptchaState()
      setSavedMessage({ section: 'personal', text: payload.message || 'Personal details saved successfully.' })
    } catch (error) {
      updateSectionErrors('personal', { _general: ['Request failed. Please try again.'] })
    } finally {
      setSavingSection('')
    }
  }

  const saveNotificationsSection = async (event) => {
    event.preventDefault()
    setSavingSection('notifications')
    clearSectionStatus('notifications')

    try {
      const response = await fetch('/settings/notifications/update', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({ ...notificationForm, homepage_url: '' })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('notifications', payload)) {
          return
        }
        updateSectionErrors('notifications', payload.errors || { _general: [payload.message || 'Unable to save notifications.'] })
        return
      }

      initialRef.current.notificationForm = { ...notificationForm }
      resetCaptchaState()
      setSavedMessage({ section: 'notifications', text: payload.message || 'Notification settings saved successfully.' })
    } catch (error) {
      updateSectionErrors('notifications', { _general: ['Request failed. Please try again.'] })
    } finally {
      setSavingSection('')
    }
  }

  const saveSecuritySection = async (event) => {
    event.preventDefault()
    setSavingSection('security')
    clearSectionStatus('security')

    try {
      const response = await fetch('/settings/security/password', {
        method: 'POST',
        credentials: 'same-origin',
        headers: await botHeaders({
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        }, captchaState),
        body: JSON.stringify(applyCaptchaPayload({ ...securityForm, homepage_url: '' })),
      })

      const payload = await response.json().catch(() => ({}))
      if (!response.ok) {
        if (captureCaptchaRequirement('security', payload)) {
          return
        }
        updateSectionErrors('security', payload.errors || { _general: [payload.message || 'Unable to update password.'] })
        return
      }

      setSecurityForm({
        current_password: '',
        new_password: '',
        new_password_confirmation: '',
      })
      resetCaptchaState()
      setSavedMessage({ section: 'security', text: payload.message || 'Password updated successfully.' })
    } catch (error) {
      updateSectionErrors('security', { _general: ['Request failed. Please try again.'] })
    } finally {
      setSavingSection('')
    }
  }

  const handleDeleteAccount = async () => {
    setDeleting(true)
    setDeleteError('')

    try {
      const response = await fetch('/profile', {
        method: 'DELETE',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json',
          Accept: 'application/json',
          'X-CSRF-TOKEN': getCsrfToken(),
        },
        body: JSON.stringify({ password: deletePassword }),
      })

      if (response.ok || response.status === 302) {
        window.location.href = '/'
        return
      }

      const payload = await response.json().catch(() => ({}))
      setDeleteError(payload.errors?.password?.[0] || payload.message || 'Deletion failed.')
    } catch (error) {
      setDeleteError('Request failed.')
    } finally {
      setDeleting(false)
    }
  }

  const sectionSaved = savedMessage.section === activeSection ? savedMessage.text : ''

  return (
    <SettingsLayout
      title="Settings"
      sections={SETTINGS_SECTIONS}
      activeSection={activeSection}
      onSectionChange={switchSection}
    >
      <div className="space-y-4">
        <div className="flex flex-col gap-2 rounded-xl border border-white/5 bg-white/[0.02] p-4 md:flex-row md:items-center md:justify-between">
          <p className="text-sm text-slate-300">
            Configure your account by section. Each card saves independently.
          </p>
          {dirtyMap[activeSection] ? (
            <span className="inline-flex items-center rounded-full border border-amber-400/30 bg-amber-400/10 px-3 py-1 text-xs font-medium text-amber-300">
              Unsaved changes
            </span>
          ) : null}
        </div>

        {activeSection === 'profile' ? (
          <form className="space-y-4" onSubmit={saveProfileSection}>
            <SectionCard
              title="Profile"
              description="Manage your public identity and profile presentation."
              actionSlot={
                <Button type="submit" variant="accent" size="sm" loading={savingSection === 'profile'}>
                  Save Profile
                </Button>
              }
            >
              <div className="grid gap-6 lg:grid-cols-[260px,1fr]">
                <div className="space-y-3">
                  <div className="rounded-xl border border-white/10 bg-black/20 p-4">
                    <div
                      className="mx-auto overflow-hidden rounded-full border border-white/15 bg-white/5"
                      style={{ width: 144, height: 144, minWidth: 144, minHeight: 144 }}
                    >
                      {avatarUrl ? (
                        <img
                          src={avatarUrl}
                          alt="Avatar preview"
                          className="block h-full w-full object-cover object-center"
                          style={{ aspectRatio: '1 / 1', objectPosition: positionToObjectPosition(avatarPosition) }}
                        />
                      ) : (
                        <div className="flex h-full w-full items-center justify-center text-slate-500">No avatar</div>
                      )}
                    </div>
                    <p className="mt-3 text-center text-xs text-slate-400">Recommended size: 256 x 256</p>
                  </div>

                  <div className="rounded-xl border border-white/10 bg-black/20 p-3">
                    <Select
                      label="Avatar crop position"
                      value={avatarPosition}
                      onChange={(e) => {
                        setAvatarPosition(e.target.value)
                        clearSectionStatus('profile')
                      }}
                      options={AVATAR_POSITION_OPTIONS}
                      hint="Applies when saving a newly selected avatar"
                    />
                  </div>

                  <div
                    className={`rounded-xl border-2 border-dashed p-4 text-center transition ${
                      dragActive ? 'border-accent/60 bg-accent/10' : 'border-white/15 bg-white/[0.02]'
                    }`}
                    onDragEnter={(e) => {
                      dragHandler(e)
                      setDragActive(true)
                    }}
                    onDragLeave={(e) => {
                      dragHandler(e)
                      setDragActive(false)
                    }}
                    onDragOver={dragHandler}
                    onDrop={handleDrop}
                  >
                    <p className="text-sm text-white">Drag and drop avatar here</p>
                    <p className="mt-1 text-xs text-slate-400">JPG, PNG, WEBP up to 2 MB</p>
                    <input
                      ref={avatarInputRef}
                      type="file"
                      className="hidden"
                      accept="image/jpeg,image/png,image/webp"
                      onChange={(e) => handleAvatarSelect(e.target.files?.[0])}
                    />
                    <div className="mt-3 flex items-center justify-center gap-2">
                      <Button
                        type="button"
                        size="xs"
                        variant="secondary"
                        onClick={() => avatarInputRef.current?.click()}
                      >
                        Upload avatar
                      </Button>
                      <Button
                        type="button"
                        size="xs"
                        variant="ghost"
                        onClick={() => {
                          setAvatarFile(null)
                          setRemoveAvatar(true)
                          setAvatarUrl('')
                        }}
                      >
                        Remove avatar
                      </Button>
                    </div>
                  </div>
                </div>

                <div className="space-y-4">
                  {errorsBySection.profile._general ? (
                    <div className="rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
                      {errorsBySection.profile._general[0]}
                    </div>
                  ) : null}

                  {sectionSaved ? (
                    <div className="rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
                      {sectionSaved}
                    </div>
                  ) : null}

                  <TextInput
                    label="Display Name"
                    value={profileForm.display_name}
                    onChange={(e) => {
                      setProfileForm((prev) => ({ ...prev, display_name: e.target.value }))
                      clearSectionStatus('profile')
                    }}
                    error={errorsBySection.profile.display_name?.[0]}
                    maxLength={60}
                    required
                  />

                  <TextInput
                    label="Website"
                    value={profileForm.website}
                    onChange={(e) => {
                      setProfileForm((prev) => ({ ...prev, website: e.target.value }))
                      clearSectionStatus('profile')
                    }}
                    placeholder="https://"
                    error={errorsBySection.profile.website?.[0]}
                  />

                  <Textarea
                    label="Bio"
                    value={profileForm.bio}
                    onChange={(e) => {
                      setProfileForm((prev) => ({ ...prev, bio: e.target.value }))
                      clearSectionStatus('profile')
                    }}
                    rows={4}
                    maxLength={200}
                    error={errorsBySection.profile.bio?.[0]}
                    hint={`${(profileForm.bio || '').length}/200`}
                  />

                  <Textarea
                    label="Signature"
                    value={profileForm.signature}
                    onChange={(e) => {
                      setProfileForm((prev) => ({ ...prev, signature: e.target.value }))
                      clearSectionStatus('profile')
                    }}
                    rows={3}
                    error={errorsBySection.profile.signature?.[0]}
                  />

                  <Textarea
                    label="Description"
                    value={profileForm.description}
                    onChange={(e) => {
                      setProfileForm((prev) => ({ ...prev, description: e.target.value }))
                      clearSectionStatus('profile')
                    }}
                    rows={3}
                    error={errorsBySection.profile.description?.[0]}
                  />

                  {renderCaptchaChallenge('profile')}
                </div>
              </div>
            </SectionCard>
          </form>
        ) : null}

        {activeSection === 'account' ? (
          <form className="space-y-4" onSubmit={saveAccountSection}>
            <SectionCard
              title="Account"
              description="Update your core account identity details."
              actionSlot={
                <Button
                  type="submit"
                  variant="accent"
                  size="sm"
                  loading={savingSection === 'account'}
                  disabled={usernameCooldownActive}
                >
                  Save Username
                </Button>
              }
            >
              {errorsBySection.account._general ? (
                <div className="mb-4 rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
                  {errorsBySection.account._general[0]}
                </div>
              ) : null}

              {sectionSaved ? (
                <div className="mb-4 rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
                  {sectionSaved}
                </div>
              ) : null}

              <div className="grid gap-4 md:grid-cols-2">
                <TextInput
                  label="Username"
                  value={accountForm.username}
                  onChange={(e) => {
                    setAccountForm((prev) => ({ ...prev, username: e.target.value }))
                    clearSectionStatus('account')
                  }}
                  disabled={usernameCooldownActive}
                  error={errorsBySection.account.username?.[0]}
                  hint={usernameCooldownActive ? `Username can be changed again in ${usernameCooldownRemainingDays} days.` : 'Allowed: letters, numbers, underscores (3-20).'}
                  required
                />
                <div className="rounded-xl border border-white/10 bg-black/20 p-4">
                  <p className="text-xs uppercase tracking-wide text-slate-400">Current Email</p>
                  <p className="mt-1 text-sm font-medium text-white">{accountForm.email || 'No email set'}</p>
                  <div className="mt-3">
                    <Button type="button" variant="secondary" size="sm" onClick={openEmailChangeModal}>
                      Change Email
                    </Button>
                  </div>
                </div>
              </div>

              {usernameAvailability.status !== 'idle' ? (
                <p
                  className={`mt-4 rounded-lg border px-3 py-2 text-xs ${
                    usernameAvailability.status === 'available'
                      ? 'border-emerald-400/30 bg-emerald-500/10 text-emerald-300'
                      : usernameAvailability.status === 'checking'
                        ? 'border-sky-400/30 bg-sky-500/10 text-sky-300'
                        : 'border-red-400/30 bg-red-500/10 text-red-300'
                  }`}
                >
                  {usernameAvailability.message}
                </p>
              ) : null}

              <p className="mt-4 rounded-lg border border-white/10 bg-white/[0.02] px-3 py-2 text-xs text-slate-300">
                You can change your username once every {usernameCooldownDays} days.
              </p>

              {renderCaptchaChallenge('account')}
            </SectionCard>
          </form>
        ) : null}

        {activeSection === 'personal' ? (
          <form className="space-y-4" onSubmit={savePersonalSection}>
            <SectionCard
              title="Personal Details"
              description="Optional information shown only when you decide to provide it."
              actionSlot={
                <Button type="submit" variant="accent" size="sm" loading={savingSection === 'personal'}>
                  Save Personal Details
                </Button>
              }
            >
              {errorsBySection.personal._general ? (
                <div className="mb-4 rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
                  {errorsBySection.personal._general[0]}
                </div>
              ) : null}

              {sectionSaved ? (
                <div className="mb-4 rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
                  {sectionSaved}
                </div>
              ) : null}

              <div className="space-y-4">
                <div>
                  <label className="mb-1.5 block text-sm font-medium text-white/85">Birthday</label>
                  <div className="grid max-w-lg grid-cols-3 gap-3">
                    <Select
                      placeholder="Day"
                      value={personalForm.day}
                      onChange={(e) => {
                        setPersonalForm((prev) => ({ ...prev, day: e.target.value }))
                        clearSectionStatus('personal')
                      }}
                      options={dayOptions}
                    />
                    <Select
                      placeholder="Month"
                      value={personalForm.month}
                      onChange={(e) => {
                        setPersonalForm((prev) => ({ ...prev, month: e.target.value }))
                        clearSectionStatus('personal')
                      }}
                      options={MONTHS}
                    />
                    <Select
                      placeholder="Year"
                      value={personalForm.year}
                      onChange={(e) => {
                        setPersonalForm((prev) => ({ ...prev, year: e.target.value }))
                        clearSectionStatus('personal')
                      }}
                      options={yearOptions}
                    />
                  </div>
                  {errorsBySection.personal.birthday?.[0] ? (
                    <p className="mt-1 text-xs text-red-300">{errorsBySection.personal.birthday[0]}</p>
                  ) : null}
                </div>

                <RadioGroup
                  label="Gender"
                  name="gender"
                  options={GENDER_OPTIONS}
                  value={personalForm.gender}
                  onChange={(value) => {
                    setPersonalForm((prev) => ({ ...prev, gender: value }))
                    clearSectionStatus('personal')
                  }}
                  direction="horizontal"
                  error={errorsBySection.personal.gender?.[0]}
                />

                {countryOptions.length > 0 ? (
                  <Select
                    label="Country"
                    value={personalForm.country}
                    onChange={(e) => {
                      setPersonalForm((prev) => ({ ...prev, country: e.target.value }))
                      clearSectionStatus('personal')
                    }}
                    options={countryOptions}
                    placeholder="Select country"
                    error={errorsBySection.personal.country?.[0]}
                  />
                ) : (
                  <TextInput
                    label="Country"
                    value={personalForm.country}
                    onChange={(e) => {
                      setPersonalForm((prev) => ({ ...prev, country: e.target.value }))
                      clearSectionStatus('personal')
                    }}
                    placeholder="Country code (e.g. US, DE, TR)"
                    error={errorsBySection.personal.country?.[0]}
                  />
                )}

                {renderCaptchaChallenge('personal')}
              </div>
            </SectionCard>
          </form>
        ) : null}

        {activeSection === 'notifications' ? (
          <form className="space-y-4" onSubmit={saveNotificationsSection}>
            <SectionCard
              title="Notifications"
              description="Choose how and when Skinbase should notify you."
              actionSlot={
                <Button type="submit" variant="accent" size="sm" loading={savingSection === 'notifications'}>
                  Save Notification Settings
                </Button>
              }
            >
              {errorsBySection.notifications._general ? (
                <div className="mb-4 rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
                  {errorsBySection.notifications._general[0]}
                </div>
              ) : null}

              {sectionSaved ? (
                <div className="mb-4 rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
                  {sectionSaved}
                </div>
              ) : null}

              <div className="space-y-3">
                {[
                  ['email_notifications', 'Email notifications', 'General email alerts for account activity.'],
                  ['upload_notifications', 'Upload notifications', 'Notify me when followed creators upload.'],
                  ['follower_notifications', 'Follower notifications', 'Notify me when someone follows me.'],
                  ['comment_notifications', 'Comment notifications', 'Notify me about comments on my content.'],
                  ['newsletter', 'Newsletter', 'Receive occasional community and product updates.'],
                ].map(([field, label, hint]) => (
                  <div key={field} className="flex items-center justify-between rounded-lg border border-white/5 bg-white/[0.02] px-3 py-2">
                    <div>
                      <p className="text-sm font-medium text-white/90">{label}</p>
                      <p className="text-xs text-slate-400">{hint}</p>
                    </div>
                    <Toggle
                      checked={!!notificationForm[field]}
                      onChange={(e) => {
                        setNotificationForm((prev) => ({ ...prev, [field]: e.target.checked }))
                        clearSectionStatus('notifications')
                      }}
                      variant="accent"
                    />
                  </div>
                ))}

                {renderCaptchaChallenge('notifications')}
              </div>
            </SectionCard>
          </form>
        ) : null}

        {activeSection === 'security' ? (
          <form className="space-y-4" onSubmit={saveSecuritySection}>
            <SectionCard
              title="Security"
              description="Update password. Additional security controls can be added here later."
              actionSlot={
                <Button type="submit" variant="accent" size="sm" loading={savingSection === 'security'}>
                  Update Password
                </Button>
              }
            >
              {errorsBySection.security._general ? (
                <div className="mb-4 rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
                  {errorsBySection.security._general[0]}
                </div>
              ) : null}

              {sectionSaved ? (
                <div className="mb-4 rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
                  {sectionSaved}
                </div>
              ) : null}

              <div className="grid max-w-2xl gap-4">
                <TextInput
                  label="Current Password"
                  type="password"
                  value={securityForm.current_password}
                  onChange={(e) => {
                    setSecurityForm((prev) => ({ ...prev, current_password: e.target.value }))
                    clearSectionStatus('security')
                  }}
                  error={errorsBySection.security.current_password?.[0]}
                  autoComplete="current-password"
                />
                <TextInput
                  label="New Password"
                  type="password"
                  value={securityForm.new_password}
                  onChange={(e) => {
                    setSecurityForm((prev) => ({ ...prev, new_password: e.target.value }))
                    clearSectionStatus('security')
                  }}
                  error={errorsBySection.security.new_password?.[0]}
                  hint="Minimum 8 characters"
                  autoComplete="new-password"
                />
                <TextInput
                  label="Confirm Password"
                  type="password"
                  value={securityForm.new_password_confirmation}
                  onChange={(e) => {
                    setSecurityForm((prev) => ({ ...prev, new_password_confirmation: e.target.value }))
                    clearSectionStatus('security')
                  }}
                  error={errorsBySection.security.new_password_confirmation?.[0]}
                  autoComplete="new-password"
                />

                <div className="rounded-lg border border-white/5 bg-white/[0.02] p-3 text-xs text-slate-400">
                  Future security controls: Two-factor authentication, active sessions, and login history.
                </div>

                {renderCaptchaChallenge('security')}
              </div>
            </SectionCard>
          </form>
        ) : null}

        {activeSection === 'danger' ? (
          <SectionCard
            title="Danger Zone"
            description="This action cannot be undone."
            actionSlot={
              <Button variant="danger" size="sm" onClick={() => setShowDeleteModal(true)}>
                Delete Account
              </Button>
            }
          >
            <p className="text-sm text-slate-300">
              Deleting your account permanently removes your artworks, comments, and profile data.
            </p>
          </SectionCard>
        ) : null}
      </div>

      <Modal
        open={showEmailChangeModal}
        onClose={closeEmailChangeModal}
        title="Change Email"
        size="sm"
        footer={
          <div className="ml-auto flex items-center gap-2">
            <Button type="button" variant="ghost" size="sm" onClick={closeEmailChangeModal} disabled={emailChangeLoading}>
              Cancel
            </Button>
            {emailChangeStep === 'request' ? (
              <Button
                type="button"
                variant="accent"
                size="sm"
                loading={emailChangeLoading}
                onClick={requestEmailChange}
              >
                Send Code
              </Button>
            ) : (
              <Button
                type="button"
                variant="accent"
                size="sm"
                loading={emailChangeLoading}
                onClick={verifyEmailChange}
              >
                Verify and Update
              </Button>
            )}
          </div>
        }
      >
        <div className="space-y-4">
          {emailChangeError ? (
            <div className="rounded-lg border border-red-400/30 bg-red-500/10 px-3 py-2 text-sm text-red-300">
              {emailChangeError}
            </div>
          ) : null}

          {emailChangeInfo ? (
            <div className="rounded-lg border border-emerald-400/30 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300">
              {emailChangeInfo}
            </div>
          ) : null}

          {renderCaptchaChallenge('account', 'modal')}

          {emailChangeStep === 'request' ? (
            <TextInput
              label="Enter new email address"
              type="email"
              value={emailChangeForm.new_email}
              onChange={(e) => setEmailChangeForm((prev) => ({ ...prev, new_email: e.target.value }))}
              autoComplete="email"
              required
            />
          ) : (
            <>
              <p className="text-sm text-slate-300">Enter the 6-digit verification code sent to {emailChangeForm.new_email}.</p>
              <TextInput
                label="Verification Code"
                value={emailChangeForm.code}
                onChange={(e) => setEmailChangeForm((prev) => ({ ...prev, code: e.target.value }))}
                inputMode="numeric"
                maxLength={6}
                required
              />
            </>
          )}
        </div>
      </Modal>

      <Modal
        open={showDeleteModal}
        onClose={() => setShowDeleteModal(false)}
        title="Delete Account"
        size="sm"
        footer={
          <div className="ml-auto flex items-center gap-2">
            <Button variant="ghost" size="sm" onClick={() => setShowDeleteModal(false)}>
              Cancel
            </Button>
            <Button variant="danger" size="sm" loading={deleting} onClick={handleDeleteAccount}>
              Permanently Delete
            </Button>
          </div>
        }
      >
        <div className="space-y-4">
          <p className="text-sm text-slate-300">Confirm your password to permanently delete your account.</p>
          <TextInput
            label="Password"
            type="password"
            value={deletePassword}
            onChange={(e) => setDeletePassword(e.target.value)}
            error={deleteError}
            autoComplete="current-password"
          />
        </div>
      </Modal>
    </SettingsLayout>
  )
}
