import { lazy, Suspense, useEffect, useState } from 'react'
import { Loading, ErrorState } from '../../../components/PageState.jsx'
import { api } from '../../../api/client.js'
import { useSite } from '../../../contexts/SiteContext.jsx'
import EmailDelivery from './EmailDelivery.jsx'

// Lazy-loaded so the heavy rich-text editor stays code-split (matches PostEditor).
const RichTextEditor = lazy(() => import('../../../components/RichTextEditor.jsx'))

// Editable settings shown on this screen (key -> label + control type).
const FIELDS = [
  { key: 'site_title', label: 'Site title' },
  {
    key: 'homepage_teaser',
    label: 'Homepage teaser',
    rich: true,
    help: 'Rich text shown under the hero heading on the portal (when no custom hero layout is published).',
  },
  { key: 'maintenance_message', label: 'Maintenance message', long: true },
  { key: 'status_message', label: 'Status message' },
  {
    key: 'contact_email',
    label: 'Contact email',
    help: 'Where contact-form messages (and test emails) are delivered. Also the address shown when email delivery is unconfigured and the form falls back to a mailto: link.',
  },
  {
    key: 'player_registration',
    label: 'Player registration',
    help: 'Who can create a player account, and how. Off by default.',
    options: [
      { value: 'disabled', label: 'Disabled — no self-registration' },
      { value: 'password', label: 'Password — username + password sign-up' },
      { value: 'sso', label: 'SSO — sign up with a linked provider' },
      { value: 'both', label: 'Both — password and SSO' },
    ],
    fallback: 'disabled',
  },
  {
    key: 'game_account_signup',
    label: 'Game-account creation',
    help: 'Whether players can create a GAME account (for the game client) from the site. The game server’s own SignupMode (Bridge.cfg) must agree: website/hybrid accept site-created accounts, game refuses them. When enabled, a “Create a game account” form appears in the player portal.',
    options: [
      { value: 'disabled', label: 'Disabled — link an existing account only' },
      { value: 'website', label: 'Website — the site creates game accounts' },
      { value: 'hybrid', label: 'Hybrid — site or in-game (recommended)' },
      { value: 'game', label: 'Game only — created in the game client, not the site' },
    ],
    fallback: 'disabled',
  },
]

export default function SettingsAdmin() {
  const { refresh: refreshSite } = useSite()
  const [values, setValues] = useState(null)
  const [initial, setInitial] = useState({})
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [busy, setBusy] = useState(false)
  const [saved, setSaved] = useState(false)

  useEffect(() => {
    let active = true
    api.admin
      .getSettings()
      .then((all) => {
        if (!active) return
        const v = {}
        FIELDS.forEach((f) => (v[f.key] = all[f.key] ?? f.fallback ?? ''))
        setValues(v)
        setInitial(v)
      })
      .catch(() => active && setError('Could not load settings.'))
      .finally(() => active && setLoading(false))
    return () => {
      active = false
    }
  }, [])

  if (loading) return <Loading />
  if (error) return <ErrorState message={error} />

  // setRaw takes the next value directly (rich editor onChange), set adapts a
  // DOM change event onto it.
  const setRaw = (k) => (val) => {
    setValues((v) => ({ ...v, [k]: val }))
    setSaved(false)
  }
  const set = (k) => (e) => setRaw(k)(e.target.value)

  async function save() {
    setBusy(true)
    setError('')
    try {
      await api.admin.updateSettings(values)
      setInitial(values)
      setSaved(true)
      await refreshSite()
    } catch (err) {
      setError(err.message || 'Could not save settings.')
    } finally {
      setBusy(false)
    }
  }

  return (
    <section style={{ maxWidth: 620 }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
        {FIELDS.map((f) => {
          // A rich field can't live inside a <label> (nested toolbar buttons +
          // contenteditable), so it uses a plain <div> wrapper instead.
          const Wrap = f.rich ? 'div' : 'label'
          let field
          if (f.rich) {
            field = (
              <Suspense fallback={<span className="spin" />}>
                <RichTextEditor value={values[f.key]} onChange={setRaw(f.key)} variant="post" />
              </Suspense>
            )
          } else if (f.options) {
            field = (
              <select value={values[f.key]} onChange={set(f.key)} className="select">
                {f.options.map((o) => (
                  <option key={o.value} value={o.value}>
                    {o.label}
                  </option>
                ))}
              </select>
            )
          } else if (f.long) {
            field = <textarea value={values[f.key]} onChange={set(f.key)} className="textarea" style={{ minHeight: 90 }} />
          } else {
            field = <input type="text" value={values[f.key]} onChange={set(f.key)} className="input" />
          }
          return (
          <Wrap key={f.key} style={{ display: 'block' }}>
            <span className="field-label">{f.label}</span>
            {field}
            {f.help && (
              <span className="sans dim" style={{ display: 'block', marginTop: 6, fontSize: '0.76rem' }}>
                {f.help}
              </span>
            )}
          </Wrap>
          )
        })}
        <div style={{ display: 'flex', gap: 10, marginTop: 6, alignItems: 'center' }}>
          <button onClick={save} disabled={busy} className="btn btn-primary btn-sq">
            {busy ? 'Saving…' : 'Save changes'}
          </button>
          <button onClick={() => setValues(initial)} disabled={busy} className="pill">
            Reset
          </button>
          {saved && <span className="sans" style={{ color: '#7fd0a4', fontSize: '0.85rem' }}>Saved.</span>}
          {error && <span className="sans" style={{ color: '#d98b84', fontSize: '0.85rem' }}>{error}</span>}
        </div>
      </div>

      <EmailDelivery />
    </section>
  )
}
