import { useCallback, useEffect, useState } from 'react'
import { api } from '../../../api/client.js'
import { useSite } from '../../../contexts/SiteContext.jsx'

// Email delivery panel (Gmail over OAuth2), rendered as a section on the Settings
// page. Sending is authorized by an in-app "Connect Gmail" consent flow that
// captures a refresh token server-side — the token is write-only over the API
// (stored encrypted, never returned). Reuses the Google SSO OAuth client, so it
// requires the Google provider to be configured on the Authentication page first.

const STATUS_COLOR = {
  connected: '#7fd0a4',
  error: '#d98b84',
  unconfigured: 'var(--muted)',
}

// Human-friendly text for the ?email_error=<code> the callback may redirect with.
const ERROR_TEXT = {
  denied: 'Google sign-in was cancelled or denied.',
  bad_state: 'The connect session expired. Please try again.',
  no_client: 'The Google OAuth client is not configured.',
  no_refresh_token:
    'Google did not return a refresh token. Remove this app under your Google Account → Security → Third-party access, then reconnect.',
  no_email: 'Could not read the Gmail address from Google.',
  error: 'Could not connect the Gmail account. Please try again.',
}

function StatusPanel({ config }) {
  const color = STATUS_COLOR[config.status] || 'var(--muted)'
  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 10, padding: 16, display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span style={{ width: 9, height: 9, borderRadius: '50%', background: color, boxShadow: `0 0 8px ${color}` }} />
        <span className="sans" style={{ fontSize: '0.9rem', color: 'var(--ink)', textTransform: 'capitalize' }}>
          {config.status || 'unconfigured'}
        </span>
      </div>
      {config.senderEmail && (
        <p className="sans" style={{ margin: 0, fontSize: '0.85rem', color: 'var(--ink)' }}>
          Sending as <strong>{config.senderEmail}</strong>
        </p>
      )}
      {config.statusDetail && (
        <p className="sans" style={{ margin: 0, fontSize: '0.82rem', color: 'var(--muted)' }}>{config.statusDetail}</p>
      )}
      {config.lastVerifiedAt && (
        <p className="sans dim" style={{ margin: 0, fontSize: '0.78rem' }}>
          Last verified: {new Date(config.lastVerifiedAt).toLocaleString()}
        </p>
      )}
    </div>
  )
}

export default function EmailDelivery() {
  const { siteTitle } = useSite()
  const [config, setConfig] = useState(null)
  const [error, setError] = useState('')
  const [senderName, setSenderName] = useState('')
  const [enabled, setEnabled] = useState(false)
  const [busy, setBusy] = useState('')
  const [msg, setMsg] = useState('')
  const [actionError, setActionError] = useState('')
  const [banner, setBanner] = useState(null) // fields kind ('ok' or 'err') and text

  const load = useCallback(async (seedForm = false) => {
    try {
      const c = await api.admin.getEmailConfig()
      setConfig(c)
      if (seedForm) {
        setSenderName(c.senderName || '')
        setEnabled(c.enabled)
      }
      return c
    } catch {
      setError('Could not load email settings.')
      return null
    }
  }, [])

  // On mount, surface the outcome of a just-completed connect redirect, strip the
  // query params so a refresh doesn't replay the banner, then load config.
  useEffect(() => {
    const params = new URLSearchParams(window.location.search)
    if (params.has('email_connected')) {
      setBanner({ kind: 'ok', text: 'Gmail account connected.' })
    } else if (params.has('email_error')) {
      setBanner({ kind: 'err', text: ERROR_TEXT[params.get('email_error')] || 'Could not connect email.' })
    }
    if (params.has('email_connected') || params.has('email_error')) {
      params.delete('email_connected')
      params.delete('email_error')
      const qs = params.toString()
      window.history.replaceState({}, '', window.location.pathname + (qs ? `?${qs}` : ''))
    }
    load(true)
  }, [load])

  async function connect() {
    setBusy('connect')
    setActionError('')
    try {
      const { url } = await api.admin.emailConnectUrl()
      window.location.href = url
    } catch (err) {
      setActionError(err.message || 'Could not start the connect flow.')
      setBusy('')
    }
  }

  async function save() {
    setBusy('save')
    setMsg('')
    setActionError('')
    try {
      const saved = await api.admin.saveEmailConfig({ senderName, enabled })
      setConfig(saved)
      setMsg('Saved.')
    } catch (err) {
      setActionError(err.message || 'Could not save.')
    } finally {
      setBusy('')
    }
  }

  async function sendTest() {
    setBusy('test')
    setMsg('')
    setActionError('')
    try {
      const r = await api.admin.testEmail()
      setMsg(`Test email sent to ${r.to}.`)
      await load()
    } catch (err) {
      setActionError(err.message || 'Could not send the test email.')
    } finally {
      setBusy('')
    }
  }

  async function disconnect() {
    setBusy('disconnect')
    setMsg('')
    setActionError('')
    try {
      const c = await api.admin.disconnectEmail()
      setConfig(c)
      setEnabled(false)
      setMsg('Disconnected.')
    } catch (err) {
      setActionError(err.message || 'Could not disconnect.')
    } finally {
      setBusy('')
    }
  }

  if (error) return <p className="sans" style={{ color: '#d98b84' }}>{error}</p>
  if (!config) return null

  const connected = config.hasRefreshToken

  return (
    <section style={{ maxWidth: 620, display: 'flex', flexDirection: 'column', gap: 16, marginTop: 40, borderTop: '1px solid var(--line-soft)', paddingTop: 30 }}>
      <div>
        <h2 className="display" style={{ margin: 0, fontSize: '1.2rem', color: 'var(--head)' }}>Email delivery</h2>
        <p className="sans dim" style={{ margin: '6px 0 0', fontSize: '0.82rem' }}>
          Sends the contact form through Gmail over OAuth2, delivered to the
          <strong> Contact email</strong> above. Reuses the Google authentication
          client — configure that on the Authentication page first.
        </p>
      </div>

      {banner && (
        <div
          className="sans"
          style={{
            fontSize: '0.85rem',
            borderRadius: 8,
            padding: '10px 12px',
            border: `1px solid ${banner.kind === 'ok' ? '#3f6b52' : '#7a4440'}`,
            color: banner.kind === 'ok' ? '#7fd0a4' : '#d98b84',
          }}
        >
          {banner.text}
        </div>
      )}

      <StatusPanel config={config} />

      {!config.googleConfigured && (
        <p className="sans" style={{ margin: 0, fontSize: '0.82rem', color: '#e0b070' }}>
          The Google authentication provider needs a client ID and secret before
          you can connect a Gmail account.
        </p>
      )}

      {!connected ? (
        <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>
          <button onClick={connect} disabled={busy === 'connect' || !config.googleConfigured} className="btn btn-primary btn-sq">
            {busy === 'connect' ? 'Redirecting…' : 'Connect Gmail'}
          </button>
        </div>
      ) : (
        <>
          <label className="sans" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, cursor: 'pointer', fontSize: '0.9rem', color: 'var(--ink)' }}>
            <input type="checkbox" checked={enabled} onChange={(e) => setEnabled(e.target.checked)} />
            Enable email sending
          </label>

          <label style={{ display: 'block' }}>
            <span className="field-label">From display name (optional)</span>
            <input
              type="text"
              value={senderName}
              onChange={(e) => setSenderName(e.target.value)}
              className="input"
              autoComplete="off"
              placeholder={siteTitle}
            />
          </label>

          <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            <button onClick={save} disabled={busy === 'save'} className="btn btn-primary btn-sq">
              {busy === 'save' ? 'Saving…' : 'Save changes'}
            </button>
            <button onClick={sendTest} disabled={busy === 'test'} className="pill">
              {busy === 'test' ? 'Sending…' : 'Send test'}
            </button>
            <button onClick={connect} disabled={busy === 'connect'} className="pill">
              Reconnect
            </button>
            <button onClick={disconnect} disabled={busy === 'disconnect'} className="pill">
              Disconnect
            </button>
          </div>
        </>
      )}

      <div style={{ minHeight: 18 }}>
        {msg && <span className="sans" style={{ color: '#7fd0a4', fontSize: '0.85rem' }}>{msg}</span>}
        {actionError && <span className="sans" style={{ color: '#d98b84', fontSize: '0.85rem' }}>{actionError}</span>}
      </div>
    </section>
  )
}
