import React from "react";
import { ActivityIndicator, Linking, ScrollView, Switch, Text, View } from "react-native";
import { useQuery } from "@tanstack/react-query";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import Ionicons from "@react-native-vector-icons/ionicons";

import { api } from "@/src/api";
import { Focusable } from "@/src/components/Focusable";
import { usesNativeTabs } from "@/src/navigation";
import { makeStyles, useTheme } from "@/src/theme";
import { fs, radius, sidePad, space } from "@/src/ui";
import { useVpn, VpnPrefs, VpnServer } from "@/src/vpn/VpnContext";

const LABEL: Record<string, string> = {
  connected: "Protegido",
  connecting: "Conectando…",
  reconnecting: "Reconectando…",
  disconnected: "Desprotegido",
  error: "Falha na conexão",
  unavailable: "VPN indisponível neste ambiente",
};

export default function VpnScreen() {
  const styles = useStyles();
  const { colors } = useTheme();
  const insets = useSafeAreaInsets();
  const vpn = useVpn();
  const servers = useQuery({ queryKey: ["vpn-servers"], queryFn: () => api<VpnServer[]>("/vpn/servers") });
  const bottomChrome = usesNativeTabs ? insets.bottom : 0;
  const on = vpn.status === "connected";
  const busy = vpn.status === "connecting" || vpn.status === "reconnecting";
  const ring = on ? colors.success : busy ? colors.warning : vpn.status === "error" ? colors.error : colors.border;

  const prefRows: { key: keyof VpnPrefs; label: string; desc: string }[] = [
    { key: "autoReconnect", label: "Reconexão automática", desc: "Reconecta sozinho se a conexão cair" },
    { key: "dnsLeakProtection", label: "Proteção contra vazamento de DNS", desc: "Consultas DNS somente pelo túnel" },
    { key: "killSwitch", label: "Kill switch", desc: "Bloqueia a internet se a VPN cair" },
  ];

  return (
    <ScrollView style={styles.root} contentContainerStyle={{ paddingTop: insets.top + space.lg, paddingBottom: bottomChrome + space.xl, paddingHorizontal: sidePad }} testID="vpn-screen">
      <Text style={styles.title}>VPN</Text>

      <View style={styles.hero}>
        <Focusable
          testID="vpn-toggle-button"
          hasTVPreferredFocus
          style={[styles.shield, { borderColor: ring }]}
          focusScale={1.05}
          onPress={() => (on || busy ? vpn.disconnect() : vpn.connect())}
        >
          {busy ? <ActivityIndicator size="large" color={colors.warning} /> : <Ionicons name={on ? "shield-checkmark" : "shield-outline"} size={72} color={on ? colors.success : colors.muted} />}
          <Text style={styles.shieldText}>{on || busy ? "DESLIGAR" : "LIGAR"}</Text>
        </Focusable>
        <Text testID="vpn-status-text" style={[styles.status, { color: on ? colors.success : colors.onSurface }]}>{LABEL[vpn.status]}</Text>
        {!!vpn.error && <Text testID="vpn-error-text" style={styles.error}>{vpn.error}</Text>}
      </View>

      {!vpn.available && (
        <View style={styles.notice} testID="vpn-native-notice">
          <Ionicons name="construct-outline" size={20} color={colors.warning} />
          <Text style={styles.noticeText}>
            A VPN usa o VpnService do Android com WireGuard/OpenVPN e precisa de um build Android com o módulo nativo. No Expo Go e na web ela não funciona — nenhuma conexão é simulada.
          </Text>
        </View>
      )}

      <Text style={styles.section}>Servidores</Text>
      {servers.isLoading && <ActivityIndicator color={colors.brandPrimary} />}
      {servers.data?.length === 0 && <Text style={styles.muted}>Nenhum servidor configurado no painel.</Text>}
      {servers.data?.map((s) => {
        const sel = vpn.serverId === s.id;
        return (
          <Focusable key={s.id} testID={`vpn-server-${s.id}`} style={[styles.server, sel && { borderColor: colors.brandPrimary }]} focusScale={1.02} onPress={() => vpn.selectServer(s.id)}>
            <View style={styles.flag}>
              <Text style={styles.flagText}>{s.country}</Text>
            </View>
            <View style={{ flex: 1 }}>
              <Text style={styles.serverName}>{s.name}</Text>
              <Text style={styles.muted}>{s.protocol === "wireguard" ? "WireGuard" : "OpenVPN"} {s.endpoint ? `· ${s.endpoint}` : "· não configurado"}</Text>
            </View>
            <Ionicons name={sel ? "radio-button-on" : "radio-button-off"} size={22} color={sel ? colors.brandPrimary : colors.muted} />
          </Focusable>
        );
      })}

      <Text style={styles.section}>Conexão segura</Text>
      {prefRows.map((p) => (
        <View key={p.key} style={styles.prefRow}>
          <View style={{ flex: 1 }}>
            <Text style={styles.serverName}>{p.label}</Text>
            <Text style={styles.muted}>{p.desc}</Text>
          </View>
          <Switch
            testID={`vpn-pref-${p.key}`}
            value={vpn.prefs[p.key]}
            onValueChange={(v) => vpn.setPref(p.key, v)}
            trackColor={{ true: colors.brandPrimary, false: colors.border }}
            thumbColor={colors.onSurface}
          />
        </View>
      ))}
      <Focusable testID="vpn-system-settings" style={styles.linkBtn} onPress={() => Linking.openSettings()}>
        <Ionicons name="settings-outline" size={18} color={colors.onSurface} />
        <Text style={styles.linkText}>Configurações do sistema (VPN sempre ativa)</Text>
      </Focusable>
    </ScrollView>
  );
}

const useStyles = makeStyles((c) => ({
  root: { flex: 1, backgroundColor: c.surface },
  title: { color: c.onSurface, fontSize: fs(26), fontWeight: "800" },
  hero: { alignItems: "center", paddingVertical: space.xl },
  shield: { width: 180, height: 180, borderRadius: 90, borderWidth: 4, alignItems: "center", justifyContent: "center", backgroundColor: c.surfaceSecondary, gap: space.sm },
  shieldText: { color: c.onSurface, fontSize: fs(13), fontWeight: "800", letterSpacing: 2 },
  status: { fontSize: fs(20), fontWeight: "800", marginTop: space.lg },
  error: { color: c.error, fontSize: fs(13), textAlign: "center", marginTop: space.sm },
  notice: { flexDirection: "row", gap: space.md, backgroundColor: c.surfaceSecondary, borderRadius: radius.md, padding: space.lg, borderWidth: 1, borderColor: c.border },
  noticeText: { flex: 1, color: c.onSurfaceTertiary, fontSize: fs(13), lineHeight: fs(19) },
  section: { color: c.onSurface, fontSize: fs(17), fontWeight: "700", marginTop: space.xl, marginBottom: space.md },
  server: { flexDirection: "row", alignItems: "center", gap: space.md, backgroundColor: c.surfaceSecondary, borderRadius: radius.md, padding: space.md, marginBottom: space.sm, borderWidth: 2, borderColor: c.border },
  flag: { width: 40, height: 40, borderRadius: 20, backgroundColor: c.brandTertiary, alignItems: "center", justifyContent: "center" },
  flagText: { color: c.onBrandTertiary, fontWeight: "800", fontSize: fs(12) },
  serverName: { color: c.onSurface, fontSize: fs(15), fontWeight: "600" },
  muted: { color: c.muted, fontSize: fs(12), marginTop: 2 },
  prefRow: { flexDirection: "row", alignItems: "center", gap: space.md, paddingVertical: space.md, borderBottomWidth: 1, borderBottomColor: c.divider },
  linkBtn: { flexDirection: "row", alignItems: "center", gap: space.sm, marginTop: space.lg, minHeight: 44, borderRadius: radius.md, paddingHorizontal: space.sm },
  linkText: { color: c.onSurfaceSecondary, fontSize: fs(14) },
}));
