import { useState, useEffect } from 'react'
import { useWaste } from '../store'

interface Props {
  status: 'disconnected' | 'connecting' | 'connected'
}

// Parse URL search params for pre-filling the join form.
// Supports:
//   ?invite=waste:<b64>   waste: invite string (anchor + network name + net hash)
//   ?n=<name>             network name shorthand
//   ?network=<name>       network name
//   ?net=<64hex>          yaw2-style full network hash
//   ?a=<url>              anchor URL hint
function parseInviteParams(): { network: string; netHash: string; anchor: string; inviteString: string } {
  const p = new URLSearchParams(window.location.search)
  let inviteString = p.get('invite') ?? ''
  let network = p.get('n') ?? p.get('network') ?? ''
  let netHash = p.get('net') ?? ''
  let anchor = p.get('a') ?? p.get('anchor') ?? ''

  // Hash-based hang link: https://host/#waste:eyJ... (opaque, not sent to server)
  const hash = window.location.hash.slice(1) // strip leading #
  if (!inviteString && hash.startsWith('waste:')) {
    inviteString = hash
  }

  if (inviteString.startsWith('waste:')) {
    try {
      const json = JSON.parse(atob(inviteString.slice(6).replace(/-/g, '+').replace(/_/g, '/')))
      network = network || json.network || ''
      netHash = netHash || json.net || ''
      anchor = anchor || json.anchor || ''
    } catch { /* ignore bad invite */ }
  }

  return { network, netHash, anchor, inviteString }
}

const DEFAULT_ANCHOR = (() => {
  const cfg = (window as unknown as { WASTE_CONFIG?: { signalURL?: string } })['WASTE_CONFIG']
  return cfg?.signalURL ?? localStorage.getItem('waste_anchor_url') ?? ''
})()

const isLocal = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'

export function Onboarding({ status }: Props) {
  const { send, connect, connectBrowser, adapterMode, masterAlias, masterId, exportedBackup } = useWaste()

  const [network, setNetwork] = useState('')
  const [netHash, setNetHash] = useState('')
  const [inviteString, setInviteString] = useState('')
  const [anchorUrl, setAnchorUrl] = useState(DEFAULT_ANCHOR)
  const [nick, setNick] = useState(localStorage.getItem('waste_nick') || '')
  const [exportPass, setExportPass] = useState('')
  const [importJson, setImportJson] = useState('')
  const [importPass, setImportPass] = useState('')
  const [importStatus, setImportStatus] = useState('')
  const [showBackup, setShowBackup] = useState(false)
  const [daemonUrl, setDaemonUrl] = useState(localStorage.getItem('waste_daemon_ws') || 'ws://127.0.0.1:17338')

  useEffect(() => {
    const { network: n, netHash: nh, anchor: a, inviteString: inv } = parseInviteParams()
    if (n) setNetwork(n)
    if (nh) setNetHash(nh)
    if (a) setAnchorUrl(a)
    if (inv) setInviteString(inv)
  }, [])

  // Auto-rejoin when adapter is ready and we have saved session state
  useEffect(() => {
    if (adapterMode !== 'browser' || status !== 'connected') return
    const { network: n, netHash: nh } = parseInviteParams()
    if (n || nh) return // explicit invite — don't auto-join, show form
    // Rejoin all saved networks.
    const saved: Array<{name: string; anchor: string}> = JSON.parse(localStorage.getItem('waste_saved_networks') ?? '[]')
    if (saved.length > 0) {
      saved.forEach(s => doJoin(s.name, ''))
    } else {
      // Legacy single-network fallback.
      const savedNetwork = localStorage.getItem('waste_last_network')
      if (savedNetwork) doJoin(savedNetwork, '')
    }
  }, [adapterMode, status]) // eslint-disable-line react-hooks/exhaustive-deps

  function joinNetwork(e: React.FormEvent) {
    e.preventDefault()
    doJoin(network.trim(), netHash.trim())
  }

  function doJoin(name: string, hash: string) {
    if (!name && !hash) return

    if (adapterMode === 'browser') {
      localStorage.setItem('waste_anchor_url', anchorUrl)
      if (nick.trim()) localStorage.setItem('waste_nick', nick.trim())
      if (name) {
        // Persist to saved networks list.
        const saved: Array<{name: string; anchor: string}> = JSON.parse(localStorage.getItem('waste_saved_networks') ?? '[]')
        if (!saved.some(n => n.name === name)) {
          saved.push({ name, anchor: anchorUrl })
          localStorage.setItem('waste_saved_networks', JSON.stringify(saved))
        }
        // Keep legacy key for backward compat.
        localStorage.setItem('waste_last_network', name)
      }
    }

    if (hash.length === 64 && !name) {
      send({ type: 'join_network', network_hash: hash })
    } else {
      send({ type: 'join_network', network_name: name })
    }
  }

  function exportIdentity(e: React.FormEvent) {
    e.preventDefault()
    if (!exportPass.trim()) return
    send({ type: 'export_identity', passphrase: exportPass })
  }

  function importIdentity(e: React.FormEvent) {
    e.preventDefault()
    if (!importJson.trim() || !importPass.trim()) return
    setImportStatus('Verifying…')
    send({ type: 'import_identity', backup: importJson, passphrase: importPass })
  }

  function switchToDaemon() {
    localStorage.setItem('waste_daemon_ws', daemonUrl)
    connect(daemonUrl)
  }

  function switchToBrowser() {
    connectBrowser()
  }

  const shortId = masterId ? masterId.slice(0, 16).replace(/(.{4})/g, '$1 ').trim() : null
  const savedNetworks: Array<{name: string; anchor: string}> = JSON.parse(localStorage.getItem('waste_saved_networks') ?? '[]')

  // ── disconnected / connecting ────────────────────────────────────────────────
  if (status !== 'connected') {
    return (
      <div className="onboarding">
        <h1>waste</h1>
        {status === 'connecting' ? (
          <p className="status connecting">
            {adapterMode === 'browser' ? 'Loading crypto…' : 'Connecting to daemon…'}
          </p>
        ) : (
          <>
            <p className="status disconnected">Daemon not running</p>
            <p className="onboarding-hint">Start the daemon to use the web UI:</p>
            <pre className="onboarding-code">./launch-web.sh</pre>
            <p className="onboarding-hint muted">Or use browser mode (no install required):</p>
            <button className="primary" onClick={switchToBrowser}>Use browser mode</button>
          </>
        )}
      </div>
    )
  }

  // ── connected — join form ────────────────────────────────────────────────────
  return (
    <div className="onboarding">
      <h1>waste</h1>

      {masterAlias && (
        <div className="onboarding-identity">
          <span className="alias">{masterAlias}</span>
          {shortId && <span className="peer-id mono">{shortId}</span>}
          <span className="peer-id" style={{ opacity: 0.4, fontSize: '9px' }}>
            {adapterMode === 'browser' ? 'browser mode' : 'daemon mode'}
          </span>
        </div>
      )}

      {adapterMode === 'browser' && savedNetworks.length > 0 && (
        <div className="saved-networks">
          <span className="join-label">Saved networks</span>
          <div className="saved-network-chips">
            {savedNetworks.map(n => (
              <button key={n.name} className="network-chip" type="button" onClick={() => doJoin(n.name, '')}>
                {n.name}
              </button>
            ))}
          </div>
        </div>
      )}

      <form onSubmit={joinNetwork} className="join-form">
        <label className="join-label">{savedNetworks.length > 0 ? 'Join another network' : 'Join a network'}</label>

        {adapterMode === 'browser' && (
          <input
            value={nick}
            onChange={e => setNick(e.target.value)}
            placeholder="your name (optional)"
            autoComplete="nickname"
            style={{ marginBottom: '0.4rem' }}
          />
        )}

        {netHash && !network ? (
          <input
            value={netHash}
            onChange={e => setNetHash(e.target.value)}
            placeholder="network hash (64 hex)"
            autoComplete="off"
            autoFocus
            className="mono"
            style={{ fontSize: '0.72rem' }}
          />
        ) : (
          <input
            value={network}
            onChange={e => setNetwork(e.target.value)}
            placeholder="network name"
            autoComplete="off"
            autoFocus
          />
        )}

        {adapterMode === 'browser' && (
          <input
            value={anchorUrl}
            onChange={e => setAnchorUrl(e.target.value)}
            placeholder="signal server (wss://…)"
            autoComplete="url"
            className="mono"
            style={{ fontSize: '0.78rem' }}
          />
        )}

        {inviteString && (
          <p className="onboarding-hint muted mono" style={{ fontSize: '0.68rem', wordBreak: 'break-all' }}>
            {inviteString.slice(0, 48)}…
          </p>
        )}
        <button type="submit" className="primary" disabled={!network.trim() && netHash.length !== 64}>
          Join
        </button>
      </form>

      {/* Mode switcher — only shown when on localhost */}
      {isLocal && adapterMode !== null && (
        <div className="onboarding-section">
          {adapterMode === 'daemon' ? (
            <button className="toggle-link" onClick={switchToBrowser}>
              Switch to browser mode
            </button>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
              <button className="toggle-link" onClick={() => {}}>
                Switch to daemon mode
              </button>
              <input
                value={daemonUrl}
                onChange={e => setDaemonUrl(e.target.value)}
                placeholder="ws://127.0.0.1:17338"
                className="mono"
                style={{ fontSize: '0.78rem' }}
              />
              <button className="primary" onClick={switchToDaemon}>Connect</button>
            </div>
          )}
        </div>
      )}

      <div className="onboarding-section">
        <button
          className="toggle-link"
          onClick={() => setShowBackup(b => !b)}
        >
          {showBackup ? '▾' : '▸'} Identity backup
        </button>

        {showBackup && (
          <div className="backup-panel">
            <p className="onboarding-hint">
              Export your identity as an encrypted file. You can import it on
              any device — browser or TUI.
            </p>

            <form onSubmit={exportIdentity} className="backup-form">
              <input
                type="password"
                value={exportPass}
                onChange={e => setExportPass(e.target.value)}
                placeholder="passphrase for backup"
                autoComplete="new-password"
              />
              <button type="submit" disabled={!exportPass.trim()}>Export</button>
            </form>

            {exportedBackup && (
              <div className="export-result">
                <textarea
                  readOnly
                  value={exportedBackup}
                  rows={4}
                  className="mono"
                  onClick={e => (e.target as HTMLTextAreaElement).select()}
                />
                <button onClick={() => {
                  const a = document.createElement('a')
                  a.href = URL.createObjectURL(new Blob([exportedBackup], { type: 'application/json' }))
                  a.download = `waste-identity-${masterId?.slice(0, 8) ?? 'backup'}.json`
                  a.click()
                }}>Download file</button>
              </div>
            )}

            <details style={{ marginTop: '1rem' }}>
              <summary className="onboarding-hint" style={{ cursor: 'pointer' }}>Restore from backup</summary>
              <form onSubmit={importIdentity} className="backup-form" style={{ marginTop: '0.5rem' }}>
                <textarea
                  value={importJson}
                  onChange={e => setImportJson(e.target.value)}
                  placeholder='{"yaw":"yaw-key-backup-1", …}'
                  rows={3}
                  className="mono"
                />
                <input
                  type="password"
                  value={importPass}
                  onChange={e => setImportPass(e.target.value)}
                  placeholder="passphrase"
                  autoComplete="current-password"
                />
                <button type="submit" disabled={!importJson.trim() || !importPass.trim()}>
                  Verify & restore
                </button>
                {importStatus && <p className="onboarding-hint">{importStatus}</p>}
              </form>
            </details>
          </div>
        )}
      </div>
    </div>
  )
}
