import React, { useState } from 'react'
import NovaConfirmDialog from '../ui/NovaConfirmDialog'

export default function FollowButton({
  username,
  initialFollowing = false,
  initialCount = 0,
  showCount = true,
  className = '',
  followingClassName = 'bg-white/[0.04] border border-white/[0.08] text-white/75 hover:bg-white/[0.08]',
  idleClassName = 'bg-accent text-deep hover:brightness-110',
  sizeClassName = 'px-4 py-2.5 text-sm',
  confirmMessage,
  onChange,
}) {
  const [following, setFollowing] = useState(Boolean(initialFollowing))
  const [count, setCount] = useState(Number(initialCount || 0))
  const [loading, setLoading] = useState(false)
  const [confirmOpen, setConfirmOpen] = useState(false)
  const [hovered, setHovered] = useState(false)

  const csrfToken = typeof document !== 'undefined'
    ? document.querySelector('meta[name="csrf-token"]')?.getAttribute('content')
    : null

  const persist = async (nextState) => {
    if (!username || loading) return
    setLoading(true)
    try {
      const response = await fetch(`/api/user/${encodeURIComponent(username)}/follow`, {
        method: nextState ? 'POST' : 'DELETE',
        headers: {
          Accept: 'application/json',
          'X-CSRF-TOKEN': csrfToken || '',
        },
        credentials: 'same-origin',
      })

      if (!response.ok) throw new Error('Follow request failed')
      const payload = await response.json()
      const nextFollowing = Boolean(payload?.following)
      const nextCount = Number(payload?.followers_count ?? count)
      setFollowing(nextFollowing)
      setCount(nextCount)
      onChange?.({ following: nextFollowing, followersCount: nextCount })
    } catch {
      // Keep previous state on failure.
    } finally {
      setLoading(false)
    }
  }

  const onToggle = async () => {
    if (!following) {
      await persist(true)
      return
    }

    setConfirmOpen(true)
  }

  const toneClassName = following ? followingClassName : idleClassName

  return (
    <>
      <button
        type="button"
        onClick={onToggle}
        onMouseEnter={() => setHovered(true)}
        onMouseLeave={() => setHovered(false)}
        disabled={loading || !username}
        aria-label={following ? 'Unfollow creator' : 'Follow creator'}
        className={[
          'inline-flex items-center justify-center gap-2 rounded-xl font-semibold transition-all disabled:cursor-not-allowed disabled:opacity-60',
          sizeClassName,
          toneClassName,
          className,
        ].join(' ')}
      >
        <i className={`fa-solid fa-fw ${loading ? 'fa-circle-notch fa-spin' : following ? (hovered ? 'fa-user-minus' : 'fa-user-check') : 'fa-user-plus'}`} />
        <span>{following ? (hovered ? 'Unfollow' : 'Following') : 'Follow'}</span>
        {showCount ? <span className="text-xs opacity-70">{count.toLocaleString()}</span> : null}
      </button>

      <NovaConfirmDialog
        open={confirmOpen}
        title="Unfollow creator?"
        message={confirmMessage || `You will stop seeing updates from @${username} in your following feed.`}
        confirmLabel="Unfollow"
        cancelLabel="Keep following"
        confirmTone="danger"
        onConfirm={async () => {
          setConfirmOpen(false)
          await persist(false)
        }}
        onClose={() => setConfirmOpen(false)}
      />
    </>
  )
}
