import { useState } from 'react'
import { Button, useToast } from '@sims/ui'

/**
 * Reveal-only secret cell: shows `••••••••` for a stored value, an owner/manager-gated
 * audited Reveal → Copy/Hide, and an optional inline Set/Update editor. Factors out the
 * three near-identical copies in ClientDetail (finding #4):
 *   - SupportCard      DB password      → onReveal: revealDbPassword(id),        onSave: patchClient(id, { dbPassword })
 *   - ServiceDataCard  portal password  → onReveal: revealModulePassword(cmId),  onSave: patchClientModule(cmId, { password })
 *   - SecretField      module secret     → onReveal: revealModuleSecret(cmId, k), onSave: setModuleSecret(cmId, k, v)
 *
 * Adoption note: ClientDetail.tsx is currently owned by another agent, so those three
 * are NOT rewired here — swap them to this component in a later pass to delete the copies.
 */
export function SecretField(props: {
  /** Uppercased eyebrow label (pass `${field.label} *` yourself for required fields). */
  label: string
  /** Whether a value is stored — drives `••••` vs "not set". */
  hasValue: boolean
  /** Owner/manager gate: Reveal + Set/Update render only when true. */
  canManage: boolean
  /** Decrypt-and-return the value (audited server-side). */
  onReveal: () => Promise<string>
  /** Store/replace the value ('' may clear server-side). Omit to hide the Set/Update editor. */
  onSave?: (value: string) => Promise<void>
  /** Toast shown after a successful save (default: `${label} stored (encrypted)`). */
  savedMessage?: string
  /** Set/Update input placeholder (default: the label). */
  placeholder?: string
  /** Extra classes for the value/input span (e.g. 'mono'). Defaults to 'mono'. */
  valueClassName?: string
}) {
  const toast = useToast()
  const { label, hasValue, canManage, onReveal, onSave } = props
  const cls = props.valueClassName ?? 'mono'
  const [revealed, setRevealed] = useState<string | undefined>()
  const [setting, setSetting] = useState(false)
  const [val, setVal] = useState('')
  const [busy, setBusy] = useState(false)

  const copy = (text: string) => {
    navigator.clipboard.writeText(text)
      .then(() => toast.ok(`${label} copied`))
      .catch(() => toast.err('Copy failed'))
  }
  const reveal = () => {
    if (busy) return
    setBusy(true)
    onReveal()
      .then((v) => setRevealed(v))
      .catch((e: Error) => toast.err(e.message))
      .finally(() => setBusy(false))
  }
  const save = () => {
    if (busy || onSave === undefined) return
    setBusy(true)
    onSave(val)
      .then(() => {
        toast.ok(props.savedMessage ?? `${label} stored (encrypted)`)
        setSetting(false); setVal(''); setRevealed(undefined)
      })
      .catch((e: Error) => toast.err(e.message))
      .finally(() => setBusy(false))
  }

  return (
    <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>
      <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: 0.5, opacity: 0.6 }}>{label}</span>
      {revealed !== undefined
        ? (
          <>
            <span className={cls}>{revealed}</span>
            <Button onClick={() => copy(revealed)}>Copy</Button>
            <Button onClick={() => setRevealed(undefined)}>Hide</Button>
          </>
        )
        : hasValue
          ? <><span className={cls}>••••••••</span>{canManage && <Button onClick={reveal}>{busy ? '…' : 'Reveal'}</Button>}</>
          : <span style={{ opacity: 0.6 }}>not set</span>}
      {onSave !== undefined && canManage && !setting && (
        <Button onClick={() => setSetting(true)}>{hasValue ? 'Update' : 'Set…'}</Button>
      )}
      {onSave !== undefined && canManage && setting && (
        <>
          <input
            className={`wf ${cls}`.trim()} type="password" style={{ width: 160 }}
            placeholder={props.placeholder ?? label} aria-label={label}
            value={val} onChange={(e) => setVal(e.target.value)}
          />
          <Button tone="primary" disabled={busy} onClick={save}>{busy ? 'Saving…' : 'Save'}</Button>
          <Button onClick={() => { setSetting(false); setVal('') }}>Cancel</Button>
        </>
      )}
    </span>
  )
}
