import { useCallback, useEffect, useMemo, useState } from 'react'
import { numberedInvoke as invoke } from '../numbered-ipc'
import './styles.css'

interface PairedDevice {
  deviceId: string
  displayName: string
  platform: string
  createdAtUnixMs: number
  lastSeenAtUnixMs?: number
  state: 'ACTIVE' | 'REVOKED'
}

interface MobileSyncStatus {
  schema: string
  state: 'OFFLINE' | 'PAIRING_READY' | 'RUNNING'
  running: boolean
  lanAddress?: string
  port?: number
  pairingUri?: string
  pairingQrSvg?: string
  pairingExpiresAtUnixMs?: number
  pairedDevices: PairedDevice[]
  transport: string
  encryption: string
  desktopIsRootNode: boolean
  platformPrivateDataCustody: boolean
}

interface MobileCapture {
  cursor: number
  captureId: string
  title: string
  body: string
  sourceDeviceId: string
  createdAtUnixMs: number
}

interface MobileSyncSnapshot {
  state: string
  cursor: number
  generatedAtUnixMs: number
  desktopName: string
  rootNodeOnline: boolean
  personalChannel: { home: string; growthEventCount: number; integrity: string }
  webNovel: {
    workCount: number
    volumeCount: number
    chapterCount: number
    works: Array<{ workId: string; title: string; status: string; updatedAtUnixMs: number }>
  }
  education: {
    activeTableCount: number
    archivedTableCount: number
    unassignedTableCount: number
    sensitiveValuesIncluded: boolean
  }
  recentCaptures: MobileCapture[]
  boundary: {
    mobileRole: string
    remoteDesktopClone: boolean
    desktopOfflineExecution: boolean
    sensitiveEducationValues: string
    modelApi: string
  }
}

function formatTime(value?: number) {
  return value ? new Date(value).toLocaleString('zh-CN', { hour12: false }) : '尚未连接'
}

export function MobileSyncPanel({ onBack }: { onBack: () => void }) {
  const [status, setStatus] = useState<MobileSyncStatus | null>(null)
  const [snapshot, setSnapshot] = useState<MobileSyncSnapshot | null>(null)
  const [message, setMessage] = useState('手机是当前个人节点的远程入口，不是第二套人格系统。')
  const [pending, setPending] = useState(false)

  const refresh = useCallback(async () => {
    const next = await invoke<MobileSyncStatus>('get_mobile_sync_status')
    setStatus(next)
    if (next.running) setSnapshot(await invoke<MobileSyncSnapshot>('get_mobile_sync_snapshot'))
    else setSnapshot(null)
  }, [])

  useEffect(() => {
    let cancelled = false
    refresh().catch((error) => !cancelled && setMessage(String(error)))
    return () => { cancelled = true }
  }, [refresh])

  const run = async (action: () => Promise<unknown>, success: string) => {
    if (pending) return
    setPending(true)
    try {
      await action()
      setMessage(success)
      await refresh()
    } catch (error) {
      setMessage(String(error))
    } finally {
      setPending(false)
    }
  }

  const qrSource = useMemo(
    () => status?.pairingQrSvg ? `data:image/svg+xml;charset=utf-8,${encodeURIComponent(status.pairingQrSvg)}` : '',
    [status?.pairingQrSvg],
  )

  return <section className="mobile-sync-world" aria-label="HoloLake 多端同步">
    <header className="mobile-sync-worldbar">
      <button type="button" onClick={onBack}>← 返回我的频道</button>
      <div><span>HOLOLAKE / SAME PERSONA SYSTEM</span><b>iPhone 多端同步</b></div>
      <em>{status?.running ? '个人主节点在线' : '同步未开启'}</em>
    </header>

    <div className="mobile-sync-focus">
      <div className={`mobile-sync-orbit ${status?.running ? 'is-online' : ''}`} aria-hidden="true"><i/><i/><i/></div>
      <div><span>手机远程身体入口</span><h1>{status?.running ? '同一频道，正在等待 iPhone' : '由这台电脑守住唯一真相'}</h1><p>桌面保留身份、人格、数据与执行主权；手机只同步经过授权的投影与快速记录。</p></div>
    </div>

    {!status?.running ? <section className="mobile-sync-start">
      <b>同一局域网 · 应用层端到端加密</b>
      <p>开启后只在当前登录账号的数据根建立同步库。平台服务器不托管你的作品、教育数据、人格记忆或设备密钥。</p>
      <button type="button" disabled={pending} onClick={() => void run(() => invoke('start_mobile_sync'), 'iPhone 同步入口已开启。')}>{pending ? '正在开启…' : '开启 iPhone 同步'}</button>
    </section> : <div className="mobile-sync-grid">
      <section className="mobile-sync-pairing">
        <header><div><span>PAIRING</span><h2>配对这台 iPhone</h2></div><button type="button" disabled={pending} onClick={() => void run(() => invoke('rotate_mobile_pairing'), '已换成新的十分钟配对凭据。')}>换一枚配对凭据</button></header>
        {status.pairingUri ? <>
          {qrSource && <img src={qrSource} alt="HoloLake iPhone 配对二维码"/>}
          <p>用 iPhone 版 HoloLake 扫描。二维码内含一次性高强度配对密钥，十分钟后或使用一次后失效。</p>
          <button type="button" onClick={() => void navigator.clipboard.writeText(status.pairingUri || '').then(() => setMessage('配对链接已复制。'))}>复制配对链接</button>
          <small>到期：{formatTime(status.pairingExpiresAtUnixMs)}</small>
        </> : <div className="mobile-sync-pairing-used"><b>当前配对凭据已使用或到期</b><p>需要添加另一台手机时，再生成一枚新的凭据。</p></div>}
      </section>

      <section className="mobile-sync-projection">
        <header><span>ROOT NODE PROJECTION</span><h2>当前同步投影</h2></header>
        <div className="mobile-sync-metrics">
          <article><b>{snapshot?.webNovel.workCount ?? 0}</b><span>网文作品</span></article>
          <article><b>{snapshot?.webNovel.chapterCount ?? 0}</b><span>章节</span></article>
          <article><b>{snapshot?.education.activeTableCount ?? 0}</b><span>教育表格</span></article>
          <article><b>{snapshot?.personalChannel.growthEventCount ?? 0}</b><span>成长事件</span></article>
        </div>
        <p>教育敏感值：{snapshot?.education.sensitiveValuesIncluded ? '已包含' : '不会进入手机摘要'} · 电脑离线时手机不会冒充执行。</p>
      </section>

      <section className="mobile-sync-devices">
        <header><span>DEVICES</span><h2>已配对设备</h2></header>
        {status.pairedDevices.length ? status.pairedDevices.map((device) => <article key={device.deviceId}>
          <div><b>{device.displayName}</b><span>{device.platform} · {device.state === 'ACTIVE' ? `最近连接 ${formatTime(device.lastSeenAtUnixMs)}` : '已撤销'}</span></div>
          {device.state === 'ACTIVE' && <button type="button" disabled={pending} onClick={() => void run(() => invoke('revoke_mobile_sync_device', { input: { deviceId: device.deviceId } }), `已撤销 ${device.displayName}。`)}>撤销</button>}
        </article>) : <p>还没有完成配对的 iPhone。</p>}
      </section>

      <section className="mobile-sync-captures">
        <header><span>MOBILE CAPTURES</span><h2>手机快速记录</h2></header>
        {snapshot?.recentCaptures.length ? snapshot.recentCaptures.map((capture) => <article key={capture.captureId}><div><b>{capture.title || '未命名记录'}</b><time>{formatTime(capture.createdAtUnixMs)}</time></div><p>{capture.body}</p></article>) : <p>手机写下的想法会加密回到这台电脑，并出现在这里。</p>}
      </section>
    </div>}

    <footer className="mobile-sync-footer"><span>{message}</span><div><button type="button" disabled={pending} onClick={() => void run(refresh, '状态已从本机根节点重新读取。')}>刷新状态</button>{status?.running && <button type="button" disabled={pending} onClick={() => void run(() => invoke('stop_mobile_sync'), '同步入口已关闭；已配对设备登记仍保留，可单独撤销。')}>关闭本机同步入口</button>}</div></footer>
  </section>
}
