import { useCallback, useRef, useState } from 'react'
import {
  View,
  Text,
  TextInput,
  Pressable,
  ScrollView,
  StyleSheet,
  Linking,
  Alert,
} from 'react-native'
import { CameraView, useCameraPermissions } from 'expo-camera'
import * as Clipboard from 'expo-clipboard'
import { LinearGradient } from 'expo-linear-gradient'
import { SafeAreaView } from 'react-native-safe-area-context'
import { Ionicons } from '@expo/vector-icons'

import { useBind } from '@/context/BindContext'
import { parseBindPayload, type BindPayload } from '@/lib/types'
import { theme } from '@/constants/theme'

const ET_RELEASE = 'https://github.com/EasyTier/EasyTier/releases'

export default function BindScreen() {
  const { bind, setBind, clear, ready } = useBind()
  const [paste, setPaste] = useState('')
  const [msg, setMsg] = useState('')
  const [scanOn, setScanOn] = useState(false)
  const [perm, requestPerm] = useCameraPermissions()
  const scannedRef = useRef(false)

  const applyPayload = useCallback(
    async (p: BindPayload | null) => {
      if (!p) {
        setMsg('无法解析：请确认扫到的是 PC 端「生成绑定二维码」的 JSON。')
        return
      }
      await setBind(p)
      setMsg('已保存配对。请到「录制」页操作。')
      setScanOn(false)
      scannedRef.current = false
    },
    [setBind],
  )

  const onBarCode = useCallback(
    async ({ data }: { data: string }) => {
      if (scannedRef.current) return
      scannedRef.current = true
      const p = parseBindPayload(data)
      await applyPayload(p)
    },
    [applyPayload],
  )

  const onPasteApply = useCallback(async () => {
    const p = parseBindPayload(paste.trim())
    await applyPayload(p)
  }, [paste, applyPayload])

  const copyEtJson = useCallback(async () => {
    if (!bind) return
    const chunk = {
      networkName: bind.easytier.networkName,
      networkSecret: bind.easytier.networkSecret,
      peerUrls: bind.easytier.peerUrls,
    }
    await Clipboard.setStringAsync(JSON.stringify(chunk, null, 2))
    setMsg('已复制 EasyTier 字段（可粘贴到官方客户端）。')
  }, [bind])

  const copyFull = useCallback(async () => {
    if (!bind) return
    await Clipboard.setStringAsync(JSON.stringify(bind, null, 2))
    setMsg('已复制完整 JSON。')
  }, [bind])

  const testConn = useCallback(async () => {
    if (!bind) return
    try {
      const r = await fetch(`${bind.baseUrl}/health`, {
        headers: bind.token ? { Authorization: `Bearer ${bind.token}` } : undefined,
      })
      const j = await r.json().catch(() => ({}))
      Alert.alert('连通测试', r.ok ? `OK: ${JSON.stringify(j)}` : `HTTP ${r.status}`)
    } catch (e) {
      Alert.alert('连通失败', e instanceof Error ? e.message : String(e))
    }
  }, [bind])

  if (!ready) {
    return (
      <SafeAreaView style={styles.safe}>
        <Text style={styles.muted}>加载中…</Text>
      </SafeAreaView>
    )
  }

  return (
    <SafeAreaView style={styles.safe} edges={['bottom']}>
      <ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
        <Text style={styles.h1}>配对与 EasyTier</Text>
        <Text style={styles.lead}>
          在 PC 控制台「网络 → 远程控制」开启远程并生成二维码，用手机扫描；无需公网，请确保手机与 PC 在同一 EasyTier
          虚拟网或局域网。
        </Text>

        {bind && (
          <LinearGradient colors={['#1e3a5f', theme.bgCard]} style={styles.card}>
            <Text style={styles.cardTitle}>当前已绑定</Text>
            <Text style={styles.mono}>{bind.baseUrl}</Text>
            <Text style={styles.mutedSmall}>组网名 · {bind.easytier.networkName}</Text>
            <View style={styles.row}>
              <Pressable style={styles.btn} onPress={() => void testConn()}>
                <Text style={styles.btnText}>测试 API</Text>
              </Pressable>
              <Pressable
                style={[styles.btn, styles.btnDanger]}
                onPress={() => {
                  Alert.alert('清除配对', '确定要清除本机保存的绑定信息？', [
                    { text: '取消', style: 'cancel' },
                    { text: '清除', style: 'destructive', onPress: () => void clear() },
                  ])
                }}
              >
                <Text style={styles.btnText}>清除</Text>
              </Pressable>
            </View>
          </LinearGradient>
        )}

        <View style={styles.block}>
          <Text style={styles.h2}>EasyTier 无公网互通</Text>
          <Text style={styles.body}>
            PC 端已内置 easytier-core 并写入组网名与密钥。手机需运行官方 EasyTier 客户端并填入
            <Text style={{ fontWeight: '700', color: theme.text }}>相同</Text>
            组网参数，获得虚拟 IP 后即可访问上方 API 地址（通常为 http://虚拟IP:8001）。
          </Text>
          <Pressable onPress={() => void Linking.openURL(ET_RELEASE)} style={styles.linkRow}>
            <Ionicons name="open-outline" size={18} color={theme.accent} />
            <Text style={styles.link}>EasyTier 发行版（含 Android）</Text>
          </Pressable>
          {bind && (
            <View style={styles.etActions}>
              <Pressable style={styles.btnSecondary} onPress={() => void copyEtJson()}>
                <Text style={styles.btnSecondaryText}>复制组网 JSON</Text>
              </Pressable>
              <Pressable style={styles.btnSecondary} onPress={() => void copyFull()}>
                <Text style={styles.btnSecondaryText}>复制完整绑定 JSON</Text>
              </Pressable>
            </View>
          )}
        </View>

        <View style={styles.block}>
          <Text style={styles.h2}>扫码</Text>
          {!scanOn ? (
            <Pressable
              style={styles.btnPrimary}
              onPress={async () => {
                const r = await requestPerm()
                if (!r.granted) {
                  setMsg('需要相机权限才能扫码')
                  return
                }
                scannedRef.current = false
                setScanOn(true)
              }}
            >
              <Ionicons name="qr-code-outline" size={22} color="#fff" style={{ marginRight: 8 }} />
              <Text style={styles.btnPrimaryText}>打开相机扫 PC 二维码</Text>
            </Pressable>
          ) : perm?.granted ? (
            <View style={styles.camWrap}>
              <CameraView
                style={styles.camera}
                facing="back"
                onBarcodeScanned={onBarCode}
                barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
              />
              <Pressable style={styles.camClose} onPress={() => setScanOn(false)}>
                <Text style={styles.btnPrimaryText}>关闭相机</Text>
              </Pressable>
            </View>
          ) : (
            <Text style={styles.muted}>无相机权限</Text>
          )}
        </View>

        <View style={styles.block}>
          <Text style={styles.h2}>手动粘贴 JSON</Text>
          <TextInput
            style={styles.input}
            multiline
            placeholder="粘贴 PC 端显示的绑定 JSON"
            placeholderTextColor={theme.muted}
            value={paste}
            onChangeText={setPaste}
          />
          <Pressable style={styles.btnPrimary} onPress={() => void onPasteApply()}>
            <Text style={styles.btnPrimaryText}>解析并保存</Text>
          </Pressable>
        </View>

        {!!msg && <Text style={styles.msg}>{msg}</Text>}
      </ScrollView>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  safe: { flex: 1, backgroundColor: theme.bg },
  scroll: { padding: 20, paddingBottom: 40 },
  h1: { fontSize: 22, fontWeight: '700', color: theme.text, marginBottom: 8 },
  lead: { fontSize: 14, color: theme.muted, lineHeight: 22, marginBottom: 16 },
  h2: { fontSize: 16, fontWeight: '600', color: theme.text, marginBottom: 8 },
  body: { fontSize: 14, color: theme.muted, lineHeight: 22, marginBottom: 10 },
  block: { marginBottom: 22 },
  card: {
    borderRadius: 12,
    padding: 16,
    marginBottom: 18,
    borderWidth: 1,
    borderColor: theme.border,
  },
  cardTitle: { fontSize: 13, fontWeight: '600', color: theme.accent, marginBottom: 8 },
  mono: { fontFamily: 'monospace', fontSize: 13, color: theme.text, marginBottom: 6 },
  muted: { color: theme.muted, fontSize: 14 },
  mutedSmall: { color: theme.muted, fontSize: 12, marginTop: 6 },
  row: { flexDirection: 'row', gap: 10, marginTop: 12 },
  etActions: { gap: 10, marginTop: 12 },
  btn: {
    backgroundColor: theme.bgElevated,
    paddingVertical: 10,
    paddingHorizontal: 14,
    borderRadius: 8,
    borderWidth: 1,
    borderColor: theme.border,
  },
  btnDanger: { backgroundColor: 'rgba(245,101,101,0.15)' },
  btnText: { color: theme.text, fontWeight: '600', fontSize: 14 },
  btnPrimary: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#3d7eff',
    paddingVertical: 14,
    borderRadius: 10,
  },
  btnPrimaryText: { color: '#fff', fontWeight: '700', fontSize: 15 },
  btnSecondary: {
    borderWidth: 1,
    borderColor: theme.border,
    borderRadius: 10,
    paddingVertical: 12,
    alignItems: 'center',
    backgroundColor: theme.bgCard,
  },
  btnSecondaryText: { color: theme.text, fontWeight: '600' },
  input: {
    minHeight: 120,
    borderWidth: 1,
    borderColor: theme.border,
    borderRadius: 10,
    padding: 12,
    color: theme.text,
    fontFamily: 'monospace',
    fontSize: 12,
    marginBottom: 12,
    backgroundColor: theme.bgCard,
  },
  camWrap: { borderRadius: 12, overflow: 'hidden', backgroundColor: '#000' },
  camera: { height: 280, width: '100%' },
  camClose: { padding: 12, alignItems: 'center', backgroundColor: '#111' },
  linkRow: { flexDirection: 'row', alignItems: 'center', gap: 6, marginVertical: 8 },
  link: { color: theme.accent, fontSize: 14 },
  msg: { color: theme.success, fontSize: 14, marginTop: 8 },
})
