'use client'

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

type ProfileOption = {
  id: number
  name: string
}

type Invite = {
  id: number
  code: string
  label?: string | null
  description?: string | null
  profile_id?: number | null
  profile?: ProfileOption | null
  role?: 'user' | 'admin' | null
  max_uses?: number | null
  use_count: number
  remaining_uses?: number | null
  enabled: boolean
  expires_at?: string | null
  is_expired?: boolean
  is_usable?: boolean
  created_at?: string | null
}

type InviteForm = {
  code: string
  label: string
  description: string
  profile_id: string
  role: '' | 'user' | 'admin'
  max_uses: string
  enabled: boolean
  expires_at: string
}

const defaultForm = (): InviteForm => ({
  code: '',
  label: '',
  description: '',
  profile_id: '',
  role: '',
  max_uses: '',
  enabled: true,
  expires_at: '',
})

const formatDate = (value?: string | null) => {
  if (!value) return 'Never'
  const date = new Date(value)
  if (Number.isNaN(date.valueOf())) return value
  return date.toLocaleString()
}

export default function AdminInvitesPage() {
  const router = useRouter()
  const [invites, setInvites] = useState<Invite[]>([])
  const [profiles, setProfiles] = useState<ProfileOption[]>([])
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [status, setStatus] = useState<string | null>(null)
  const [editingId, setEditingId] = useState<number | null>(null)
  const [form, setForm] = useState<InviteForm>(defaultForm())

  const signupBaseUrl = useMemo(() => {
    if (typeof window === 'undefined') return '/signup'
    return `${window.location.origin}/signup`
  }, [])

  const handleAuthResponse = (response: Response) => {
    if (response.status === 401) {
      clearToken()
      router.push('/login')
      return true
    }
    if (response.status === 403) {
      router.push('/')
      return true
    }
    return false
  }

  const loadData = async () => {
    if (!getToken()) {
      router.push('/login')
      return
    }
    setLoading(true)
    setError(null)
    try {
      const baseUrl = getApiBase()
      const [inviteRes, profileRes] = await Promise.all([
        authFetch(`${baseUrl}/admin/invites`),
        authFetch(`${baseUrl}/admin/profiles`),
      ])
      if (!inviteRes.ok) {
        if (handleAuthResponse(inviteRes)) return
        throw new Error(`Failed to load invites (${inviteRes.status})`)
      }
      if (!profileRes.ok) {
        if (handleAuthResponse(profileRes)) return
        throw new Error(`Failed to load profiles (${profileRes.status})`)
      }
      const [inviteData, profileData] = await Promise.all([inviteRes.json(), profileRes.json()])
      setInvites(Array.isArray(inviteData?.invites) ? inviteData.invites : [])
      const profileRows = Array.isArray(profileData?.profiles) ? profileData.profiles : []
      setProfiles(
        profileRows.map((profile: any) => ({
          id: Number(profile.id ?? 0),
          name: String(profile.name ?? 'Unnamed'),
        }))
      )
    } catch (err) {
      console.error(err)
      setError('Could not load invites.')
    } finally {
      setLoading(false)
    }
  }

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

  const resetEditor = () => {
    setEditingId(null)
    setForm(defaultForm())
  }

  const editInvite = (invite: Invite) => {
    setEditingId(invite.id)
    setForm({
      code: invite.code ?? '',
      label: invite.label ?? '',
      description: invite.description ?? '',
      profile_id:
        typeof invite.profile_id === 'number' && invite.profile_id > 0
          ? String(invite.profile_id)
          : '',
      role: (invite.role ?? '') as '' | 'user' | 'admin',
      max_uses: typeof invite.max_uses === 'number' ? String(invite.max_uses) : '',
      enabled: invite.enabled !== false,
      expires_at: invite.expires_at ?? '',
    })
    setStatus(null)
    setError(null)
  }

  const saveInvite = async (event: React.FormEvent) => {
    event.preventDefault()
    setSaving(true)
    setError(null)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const payload = {
        code: form.code || null,
        label: form.label || null,
        description: form.description || null,
        profile_id: form.profile_id || null,
        role: form.role || null,
        max_uses: form.max_uses || null,
        enabled: form.enabled,
        expires_at: form.expires_at || null,
      }
      const url =
        editingId == null ? `${baseUrl}/admin/invites` : `${baseUrl}/admin/invites/${editingId}`
      const response = await authFetch(url, {
        method: editingId == null ? 'POST' : 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      })
      if (!response.ok) {
        if (handleAuthResponse(response)) return
        const text = await response.text()
        throw new Error(text || 'Save failed')
      }
      setStatus(editingId == null ? 'Invite created.' : 'Invite updated.')
      resetEditor()
      await loadData()
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not save invite.')
    } finally {
      setSaving(false)
    }
  }

  const deleteInvite = async (invite: Invite) => {
    if (!window.confirm(`Delete invite "${invite.code}"?`)) return
    setError(null)
    setStatus(null)
    try {
      const baseUrl = getApiBase()
      const response = await authFetch(`${baseUrl}/admin/invites/${invite.id}`, {
        method: 'DELETE',
      })
      if (!response.ok) {
        if (handleAuthResponse(response)) return
        const text = await response.text()
        throw new Error(text || 'Delete failed')
      }
      if (editingId === invite.id) resetEditor()
      setStatus(`Deleted invite ${invite.code}.`)
      await loadData()
    } catch (err) {
      console.error(err)
      setError(err instanceof Error ? err.message : 'Could not delete invite.')
    }
  }

  const copyInviteLink = async (invite: Invite) => {
    const url = `${signupBaseUrl}?code=${encodeURIComponent(invite.code)}`
    try {
      if (navigator.clipboard?.writeText) {
        await navigator.clipboard.writeText(url)
        setStatus(`Copied invite link for ${invite.code}.`)
      } else {
        window.prompt('Copy invite link', url)
      }
    } catch (err) {
      console.error(err)
      window.prompt('Copy invite link', url)
    }
  }

  return (
    <AdminShell
      title="Invites"
      subtitle="Create invite-based sign-up links for Magent accounts."
      actions={
        <div className="admin-inline-actions">
          <button type="button" onClick={loadData} disabled={loading}>
            {loading ? 'Loading…' : 'Reload'}
          </button>
          <button type="button" className="ghost-button" onClick={resetEditor}>
            New invite
          </button>
        </div>
      }
    >
      <section className="admin-section">
        {error && <div className="error-banner">{error}</div>}
        {status && <div className="status-banner">{status}</div>}
        <div className="admin-split-grid">
          <div className="admin-panel">
            <h2>{editingId == null ? 'Create invite' : 'Edit invite'}</h2>
            <p className="lede">
              Link an invite to a profile to apply account defaults at sign-up.
            </p>
            <form onSubmit={saveInvite} className="admin-form compact-form">
              <div className="admin-fields-grid">
                <label>
                  Code (optional)
                  <input
                    value={form.code}
                    onChange={(e) => setForm((current) => ({ ...current, code: e.target.value }))}
                    placeholder="Leave blank to auto-generate"
                  />
                </label>
                <label>
                  Label
                  <input
                    value={form.label}
                    onChange={(e) => setForm((current) => ({ ...current, label: e.target.value }))}
                    placeholder="Staff invite batch"
                  />
                </label>
              </div>
              <label>
                Description
                <textarea
                  rows={3}
                  value={form.description}
                  onChange={(e) =>
                    setForm((current) => ({ ...current, description: e.target.value }))
                  }
                  placeholder="Optional note shown on the signup page"
                />
              </label>
              <div className="admin-fields-grid">
                <label>
                  Profile
                  <select
                    value={form.profile_id}
                    onChange={(e) =>
                      setForm((current) => ({ ...current, profile_id: e.target.value }))
                    }
                  >
                    <option value="">None</option>
                    {profiles.map((profile) => (
                      <option key={profile.id} value={profile.id}>
                        {profile.name}
                      </option>
                    ))}
                  </select>
                </label>
                <label>
                  Role override
                  <select
                    value={form.role}
                    onChange={(e) =>
                      setForm((current) => ({
                        ...current,
                        role: e.target.value as '' | 'user' | 'admin',
                      }))
                    }
                  >
                    <option value="">Use profile/default</option>
                    <option value="user">User</option>
                    <option value="admin">Admin</option>
                  </select>
                </label>
              </div>
              <div className="admin-fields-grid">
                <label>
                  Max uses
                  <input
                    value={form.max_uses}
                    onChange={(e) =>
                      setForm((current) => ({ ...current, max_uses: e.target.value }))
                    }
                    inputMode="numeric"
                    placeholder="Blank = unlimited"
                  />
                </label>
                <label>
                  Invite expiry (ISO datetime)
                  <input
                    value={form.expires_at}
                    onChange={(e) =>
                      setForm((current) => ({ ...current, expires_at: e.target.value }))
                    }
                    placeholder="2026-03-01T12:00:00+00:00"
                  />
                </label>
              </div>
              <label className="inline-checkbox">
                <input
                  type="checkbox"
                  checked={form.enabled}
                  onChange={(e) =>
                    setForm((current) => ({ ...current, enabled: e.target.checked }))
                  }
                />
                Invite is enabled
              </label>
              <div className="admin-inline-actions">
                <button type="submit" disabled={saving}>
                  {saving ? 'Saving…' : editingId == null ? 'Create invite' : 'Save invite'}
                </button>
                {editingId != null && (
                  <button type="button" className="ghost-button" onClick={resetEditor}>
                    Cancel edit
                  </button>
                )}
              </div>
            </form>
          </div>
          <div className="admin-panel">
            <h2>Existing invites</h2>
            <p className="lede">Each invite can be copied as a direct sign-up link.</p>
            {loading ? (
              <div className="status-banner">Loading invites…</div>
            ) : invites.length === 0 ? (
              <div className="status-banner">No invites created yet.</div>
            ) : (
              <div className="admin-list">
                {invites.map((invite) => (
                  <div key={invite.id} className="admin-list-item">
                    <div className="admin-list-item-main">
                      <div className="admin-list-item-title-row">
                        <code className="invite-code">{invite.code}</code>
                        <span className={`small-pill ${invite.is_usable ? '' : 'is-muted'}`}>
                          {invite.is_usable ? 'Usable' : 'Unavailable'}
                        </span>
                        {invite.profile?.name && <span className="small-pill">{invite.profile.name}</span>}
                      </div>
                      {invite.label && <p className="admin-list-item-text">{invite.label}</p>}
                      {invite.description && (
                        <p className="admin-list-item-text admin-list-item-text--muted">
                          {invite.description}
                        </p>
                      )}
                      <div className="admin-meta-row">
                        <span>Uses: {invite.use_count}{typeof invite.max_uses === 'number' ? ` / ${invite.max_uses}` : ''}</span>
                        <span>Remaining: {invite.remaining_uses ?? 'Unlimited'}</span>
                        <span>Expires: {formatDate(invite.expires_at)}</span>
                        <span>Created: {formatDate(invite.created_at)}</span>
                      </div>
                    </div>
                    <div className="admin-inline-actions">
                      <button type="button" className="ghost-button" onClick={() => copyInviteLink(invite)}>
                        Copy link
                      </button>
                      <button type="button" className="ghost-button" onClick={() => editInvite(invite)}>
                        Edit
                      </button>
                      <button type="button" onClick={() => deleteInvite(invite)}>
                        Delete
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>
      </section>
    </AdminShell>
  )
}

