'use client'

import { useEffect, useMemo, useState } from 'react'
import { useRouter } from 'next/navigation'
import { authFetch, clearToken, getApiBase, getToken } from '../../lib/auth'
import AdminShell from '../../ui/AdminShell'

type NotificationUser = {
  username: string
  role?: string | null
  authProvider?: string | null
  jellyseerrUserId?: number | null
  isBlocked?: boolean
  notifyEnabled?: boolean
  notifyCount?: number
}

type SendResult = {
  username: string
  status: string
}

const formatStatus = (user: NotificationUser) => {
  if (user.isBlocked) return 'Blocked'
  if (!user.notifyEnabled) return 'Disabled'
  if (user.notifyCount && user.notifyCount > 0) return `Enabled (${user.notifyCount})`
  return 'No targets'
}

export default function AdminNotificationsPage() {
  const router = useRouter()
  const [users, setUsers] = useState<NotificationUser[]>([])
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [title, setTitle] = useState('')
  const [message, setMessage] = useState('')
  const [loading, setLoading] = useState(false)
  const [sending, setSending] = useState(false)
  const [status, setStatus] = useState<string | null>(null)
  const [sendResults, setSendResults] = useState<SendResult[]>([])

  const selectedCount = selected.size
  const selectableUsers = useMemo(
    () => users.filter((user) => user.username && !user.isBlocked),
    [users]
  )

  const load = async () => {
    if (!getToken()) {
      router.push('/login')
      return
    }
    setLoading(true)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/admin/notifications/users`)
      if (!response.ok) {
        if (response.status === 401) {
          clearToken()
          router.push('/login')
          return
        }
        if (response.status === 403) {
          router.push('/')
          return
        }
        throw new Error('Load failed')
      }
      const data = await response.json()
      const fetched = Array.isArray(data?.users) ? data.users : []
      setUsers(fetched)
      setSelected(new Set())
    } catch (err) {
      console.error(err)
      setStatus('Unable to load notification targets.')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void load()
  }, [])

  const toggleUser = (username: string) => {
    setSelected((current) => {
      const next = new Set(current)
      if (next.has(username)) {
        next.delete(username)
      } else {
        next.add(username)
      }
      return next
    })
  }

  const selectAll = () => {
    const next = new Set<string>()
    for (const user of selectableUsers) {
      if (user.username) {
        next.add(user.username)
      }
    }
    setSelected(next)
  }

  const selectEnabled = () => {
    const next = new Set<string>()
    for (const user of selectableUsers) {
      if (user.username && user.notifyEnabled && (user.notifyCount ?? 0) > 0) {
        next.add(user.username)
      }
    }
    setSelected(next)
  }

  const clearSelection = () => {
    setSelected(new Set())
  }

  const send = async () => {
    setStatus(null)
    setSendResults([])
    if (selectedCount === 0) {
      setStatus('Select at least one user.')
      return
    }
    if (!message.trim()) {
      setStatus('Message cannot be empty.')
      return
    }
    setSending(true)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/admin/notifications/send`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          usernames: Array.from(selected),
          title: title.trim() || 'Magent admin message',
          message: message.trim(),
        }),
      })
      if (!response.ok) {
        const text = await response.text()
        throw new Error(text || 'Send failed')
      }
      const data = await response.json()
      const results = Array.isArray(data?.results) ? data.results : []
      setSendResults(results)
      setStatus(
        `Sent ${data?.sent ?? 0}. Skipped ${data?.skipped ?? 0}. Failed ${data?.failed ?? 0}.`
      )
    } catch (err) {
      console.error(err)
      const message =
        err instanceof Error && err.message
          ? err.message.replace(/^\\{\"detail\":\"|\"\\}$/g, '')
          : 'Send failed.'
      setStatus(message)
    } finally {
      setSending(false)
    }
  }

  return (
    <AdminShell
      title="User notifications"
      subtitle="Send admin messages to users via their Apprise targets."
      actions={
        <button type="button" onClick={() => router.push('/admin')}>
          Back to settings
        </button>
      }
    >
      <section className="admin-section">
        <div className="admin-toolbar">
          <div className="admin-toolbar-info">
            <span>{users.length.toLocaleString()} users</span>
            <span>{selectedCount.toLocaleString()} selected</span>
          </div>
          <div className="admin-toolbar-actions">
            <button type="button" onClick={selectAll} disabled={loading}>
              Select all
            </button>
            <button type="button" onClick={selectEnabled} disabled={loading}>
              Select enabled
            </button>
            <button type="button" className="ghost-button" onClick={clearSelection}>
              Clear
            </button>
          </div>
        </div>
        {loading ? (
          <div className="status-banner">Loading notification targets…</div>
        ) : users.length === 0 ? (
          <div className="status-banner">No users found.</div>
        ) : (
          <div className="admin-table">
            <div className="admin-table-head">
              <span>Select</span>
              <span>User</span>
              <span>Role</span>
              <span>Status</span>
            </div>
            {users.map((user) => {
              const username = user.username || 'Unknown'
              const isChecked = selected.has(username)
              return (
                <div key={username} className="admin-table-row">
                  <span>
                    <input
                      type="checkbox"
                      checked={isChecked}
                      onChange={() => toggleUser(username)}
                      disabled={!username || user.isBlocked}
                    />
                  </span>
                  <span>{username}</span>
                  <span>{user.role || 'user'}</span>
                  <span>{formatStatus(user)}</span>
                </div>
              )
            })}
          </div>
        )}
      </section>
      <section className="admin-section">
        <div className="section-header">
          <h2>Message</h2>
        </div>
        <div className="admin-form">
          <label>
            <span className="label-row">
              <span>Title</span>
              <span className="meta">Optional</span>
            </span>
            <input
              type="text"
              value={title}
              onChange={(event) => setTitle(event.target.value)}
              placeholder="Magent admin message"
            />
          </label>
          <label>
            <span className="label-row">
              <span>Message</span>
              <span className="meta">Required</span>
            </span>
            <textarea
              rows={4}
              value={message}
              onChange={(event) => setMessage(event.target.value)}
              placeholder="Write the message you want to send."
            />
          </label>
        </div>
        {status && <div className="status-banner">{status}</div>}
        <div className="admin-actions">
          <button type="button" onClick={send} disabled={sending}>
            {sending ? 'Sending…' : 'Send message'}
          </button>
        </div>
        {sendResults.length > 0 && (
          <div className="admin-table">
            <div className="admin-table-head">
              <span>User</span>
              <span>Result</span>
            </div>
            {sendResults.map((result) => (
              <div key={`${result.username}-${result.status}`} className="admin-table-row">
                <span>{result.username}</span>
                <span>{result.status}</span>
              </div>
            ))}
          </div>
        )}
      </section>
    </AdminShell>
  )
}
