import { useEffect, useMemo, useRef, useState } from 'react';
import {
  ActivityIndicator,
  Image,
  Linking,
  Pressable,
  Share,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as Clipboard from 'expo-clipboard';
import { useTranslation } from 'react-i18next';
import type { ColorScheme } from '../../lib/theme';
import { apiFetch } from '../../lib/api';
import { useUserPlan } from '../../hooks/useUserPlan';
import { FormSheet } from '../FormSheet';
import { deviceImage } from './deviceIcon';

type PairResponse = {
  code: string;
  expiresAt: string;
  expiresInSeconds: number;
};

type MagicDevice = {
  deviceId: string;
  hostname: string;
  model: string | null;
  osVersion: string | null;
  magicEnrolledAt: string;
  /** "magic" = Desktop-Binding (Mac/Win), "locked" = Mobile, "protected" = Legacy-DNS */
  source?: 'magic' | 'locked' | 'protected';
};

type MagicInfo = {
  latestVersion: string;
  downloadUrl: string;
  dmgUrl: string;
  minMacosVersion: string;
  windowsInstallerUrl?: string;
  minWindowsVersion?: string;
};

type DesktopPlatform = 'mac' | 'windows';

/**
 * MagicSheet — Rebreak-Magic-Pairing-Flow als geteiltes FormSheet
 * (Bottom-Sheet mit Titel-Header). Wird aus settings.tsx getriggert.
 */
export function MagicSheet({
  visible,
  onClose,
  colors,
  initialPlatform = 'mac',
}: {
  visible: boolean;
  onClose: () => void;
  colors: ColorScheme;
  /** Vorauswahl wenn aus dem "Gerät hinzufügen"-Menü (Mac/Windows) geöffnet */
  initialPlatform?: DesktopPlatform;
}) {
  const [info, setInfo] = useState<MagicInfo | null>(null);
  const [platform, setPlatform] = useState<DesktopPlatform>(initialPlatform);

  // Bei jedem Öffnen auf die gewünschte Plattform zurücksetzen
  useEffect(() => {
    if (visible) setPlatform(initialPlatform);
  }, [visible, initialPlatform]);
  const [pair, setPair] = useState<PairResponse | null>(null);
  const [pairLoading, setPairLoading] = useState(false);
  const [pairError, setPairError] = useState<string | null>(null);
  const [now, setNow] = useState(Date.now());
  const [devices, setDevices] = useState<MagicDevice[] | null>(null);
  const tickRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const { t } = useTranslation();
  const { plan } = useUserPlan();
  // Desktop-Slots (Mac/Windows) — Mirror von backend plan-features.maxProtectedDevices
  const desktopLimit = plan === 'legend' ? 2 : 1;

  useEffect(() => {
    (async () => {
      try {
        const i = await apiFetch<MagicInfo>('/api/magic/info');
        setInfo(i);
      } catch {
        setInfo({
          latestVersion: '0.1.0',
          downloadUrl: 'https://staging.rebreak.org/download/rebreakmagic',
          dmgUrl: 'https://staging.rebreak.org/downloads/RebreakMagic-latest.dmg',
          minMacosVersion: '13.0',
          windowsInstallerUrl: 'https://staging.rebreak.org/downloads/RebreakMagic-Setup.exe',
          minWindowsVersion: '10 (21H2)',
        });
      }
      loadDevices();
    })();
    return () => {
      if (tickRef.current) clearInterval(tickRef.current);
    };
  }, []);

  useEffect(() => {
    if (pair) {
      if (tickRef.current) clearInterval(tickRef.current);
      tickRef.current = setInterval(() => setNow(Date.now()), 1000);
      return () => {
        if (tickRef.current) clearInterval(tickRef.current);
      };
    }
  }, [pair]);

  async function loadDevices() {
    try {
      const d = await apiFetch<MagicDevice[]>('/api/magic/devices');
      setDevices(d);
    } catch {
      setDevices([]);
    }
  }

  async function handleGenerateCode() {
    setPairLoading(true);
    setPairError(null);
    try {
      const res = await apiFetch<PairResponse>('/api/magic/pair/create', {
        method: 'POST',
        body: {},
      });
      setPair(res);
      setNow(Date.now());
    } catch (e: any) {
      setPairError(e?.message ?? t('magic.generate_error'));
    } finally {
      setPairLoading(false);
    }
  }

  async function handleCopyCode() {
    if (!pair) return;
    await Clipboard.setStringAsync(pair.code);
  }

  const remaining = useMemo(() => {
    if (!pair) return 0;
    const exp = new Date(pair.expiresAt).getTime();
    return Math.max(0, Math.floor((exp - now) / 1000));
  }, [pair, now]);

  const codeExpired = pair !== null && remaining <= 0;

  // Desktop-Geräte (Mac/Windows) — "locked" sind Mobile-Devices aus dem
  // merged /api/magic/devices-Endpoint und zählen NICHT auf Desktop-Slots.
  const desktopDevices = useMemo(
    () => (devices ?? []).filter((d) => d.source !== 'locked'),
    [devices],
  );
  const limitReached = desktopDevices.length >= desktopLimit;

  const isMac = platform === 'mac';
  const appName = t(isMac ? 'magic.app_mac' : 'magic.app_windows');
  const downloadHref = isMac
    ? info?.downloadUrl
    : (info?.windowsInstallerUrl ?? info?.downloadUrl);

  return (
    <FormSheet
      visible={visible}
      onClose={onClose}
      title="Rebreak Magic"
      growWithKeyboard={false}
    >
      <View style={{ paddingHorizontal: 20, paddingTop: 4, paddingBottom: 24 }}>
      {/* Sub-Header (Tagline) */}
      <Text style={{ fontSize: 13, color: colors.textMuted, marginBottom: 16, marginLeft: 4 }}>
        {t(isMac ? 'magic.tagline_mac' : 'magic.tagline_windows')}
      </Text>

      {/* Plattform-Wahl */}
      <SectionTitle text={t('magic.platform_question')} colors={colors} />
      <View style={{ flexDirection: 'row', gap: 10, marginBottom: 16 }}>
        <PlatformOption
          icon="laptop-outline"
          label="Mac"
          selected={isMac}
          onPress={() => setPlatform('mac')}
          colors={colors}
        />
        <PlatformOption
          icon="desktop-outline"
          label="Windows"
          selected={!isMac}
          onPress={() => setPlatform('windows')}
          colors={colors}
        />
      </View>

      {/* Step 1 — Download */}
      <SectionTitle text={t('magic.step1_title', { app: appName })} colors={colors} />
      <View style={cardStyle(colors)}>
        <Text style={{ fontSize: 14, color: colors.text, marginBottom: 12 }}>
          {isMac
            ? t('magic.step1_body_mac', { version: info?.minMacosVersion ?? '13.0' })
            : t('magic.step1_body_windows', { version: info?.minWindowsVersion ?? '10 (21H2)' })}
        </Text>
        <PrimaryButton
          icon="cloud-download-outline"
          label={t('magic.open_download')}
          onPress={() => downloadHref && Linking.openURL(downloadHref)}
        />
        <TouchableOpacity
          onPress={() => downloadHref && Share.share({ message: downloadHref })}
          style={{ marginTop: 10, alignSelf: 'flex-start' }}
        >
          <Text style={{ fontSize: 13, color: '#007AFF' }}>
            {t(isMac ? 'magic.send_link_mac' : 'magic.send_link_windows')}
          </Text>
        </TouchableOpacity>
      </View>

      {/* Step 2 — Pairing-Code */}
      <SectionTitle text={t('magic.step2_title')} colors={colors} />
      <View style={cardStyle(colors)}>
        {limitReached && (!pair || codeExpired) ? (
          <Text style={{ fontSize: 14, color: colors.textMuted }}>
            {t('magic.limit_reached', {
              count: desktopDevices.length,
              max: desktopLimit,
            })}{' '}
            {t(plan === 'legend' ? 'magic.limit_hint_legend' : 'magic.limit_hint_pro')}
          </Text>
        ) : !pair || codeExpired ? (
          <>
            <Text style={{ fontSize: 14, color: colors.text, marginBottom: 14 }}>
              {t('magic.code_explainer', { app: appName })}
            </Text>
            <PrimaryButton
              icon="key-outline"
              label={
                pairLoading
                  ? t('magic.generating')
                  : codeExpired
                    ? t('magic.generate_new')
                    : t('magic.generate')
              }
              onPress={handleGenerateCode}
              loading={pairLoading}
            />
            {pairError && (
              <Text style={{ marginTop: 10, color: colors.error, fontSize: 13 }}>{pairError}</Text>
            )}
          </>
        ) : (
          <>
            <Text
              style={{
                fontSize: 13,
                color: colors.textMuted,
                textAlign: 'center',
                marginBottom: 12,
              }}
            >
              {t('magic.enter_in_app', { app: appName })}
            </Text>
            <Pressable
              onPress={handleCopyCode}
              style={{
                flexDirection: 'row',
                justifyContent: 'center',
                gap: 8,
                paddingVertical: 18,
                borderRadius: 14,
                backgroundColor: colors.groupedBg,
                marginBottom: 12,
              }}
            >
              {pair.code.split('').map((d, i) => (
                <View
                  key={i}
                  style={{
                    width: 38,
                    height: 52,
                    borderRadius: 8,
                    backgroundColor: colors.card,
                    alignItems: 'center',
                    justifyContent: 'center',
                  }}
                >
                  <Text style={{ fontSize: 28, fontFamily: 'Nunito_700Bold', color: colors.text }}>
                    {d}
                  </Text>
                </View>
              ))}
            </Pressable>
            <View
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                justifyContent: 'space-between',
              }}
            >
              <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
                <Ionicons name="time-outline" size={14} color={colors.textMuted} />
                <Text style={{ fontSize: 13, color: colors.textMuted }}>
                  {t('magic.expires_in', { time: formatRemaining(remaining) })}
                </Text>
              </View>
              <TouchableOpacity onPress={handleCopyCode}>
                <Text style={{ fontSize: 13, color: '#007AFF', fontWeight: '600' }}>
                  {t('magic.copy')}
                </Text>
              </TouchableOpacity>
            </View>
            <TouchableOpacity
              onPress={() => {
                setPair(null);
                setPairError(null);
              }}
              style={{ marginTop: 14, alignSelf: 'center' }}
            >
              <Text style={{ fontSize: 13, color: colors.textMuted }}>
                {t('magic.discard_code')}
              </Text>
            </TouchableOpacity>
          </>
        )}
      </View>

      {/* Verbundene Computer + Slot-Anzeige */}
      <SectionTitle
        text={`${t('magic.connected_title')} \u00b7 ${desktopDevices.length}/${desktopLimit}`}
        colors={colors}
      />
      <View style={cardStyle(colors)}>
        {devices === null ? (
          <ActivityIndicator />
        ) : desktopDevices.length === 0 ? (
          <Text style={{ fontSize: 14, color: colors.textMuted }}>
            {t('magic.connected_empty')}
          </Text>
        ) : (
          desktopDevices.map((d, i) => (
            <View
              key={d.deviceId}
              style={{
                flexDirection: 'row',
                alignItems: 'center',
                paddingVertical: 12,
                borderTopWidth: i === 0 ? 0 : 1,
                borderTopColor: colors.border,
              }}
            >
              <View
                style={{
                  width: 36,
                  height: 36,
                  borderRadius: 9,
                  backgroundColor: colors.groupedBg,
                  alignItems: 'center',
                  justifyContent: 'center',
                  marginRight: 12,
                }}
              >
                <Image
                  source={deviceImage(undefined, d.model)}
                  style={{ width: 24, height: 24 }}
                  resizeMode="contain"
                />
              </View>
              <View style={{ flex: 1 }}>
                <Text style={{ fontSize: 15, color: colors.text, fontWeight: '600' }}>
                  {d.hostname}
                </Text>
                {d.model && (
                  <Text style={{ fontSize: 12, color: colors.textMuted, marginTop: 1 }}>
                    {d.model}
                  </Text>
                )}
              </View>
            </View>
          ))
        )}
      </View>
      </View>
    </FormSheet>
  );
}

// ─── Helpers ───────────────────────────────────────────────────────────────

function cardStyle(colors: ColorScheme) {
  return {
    backgroundColor: colors.card,
    borderRadius: 14,
    padding: 16,
    marginBottom: 16,
  } as const;
}

function SectionTitle({ text, colors }: { text: string; colors: ColorScheme }) {
  return (
    <Text
      style={{
        fontSize: 12,
        textTransform: 'uppercase',
        letterSpacing: 0.4,
        color: colors.textMuted,
        marginBottom: 8,
        marginLeft: 4,
        fontFamily: 'Nunito_700Bold',
      }}
    >
      {text}
    </Text>
  );
}

function PrimaryButton({
  icon,
  label,
  onPress,
  loading,
}: {
  icon: React.ComponentProps<typeof Ionicons>['name'];
  label: string;
  onPress: () => void;
  loading?: boolean;
}) {
  return (
    <TouchableOpacity
      onPress={onPress}
      disabled={loading}
      style={{
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
        backgroundColor: '#007AFF',
        paddingVertical: 12,
        paddingHorizontal: 16,
        borderRadius: 12,
        opacity: loading ? 0.6 : 1,
      }}
    >
      {loading ? (
        <ActivityIndicator color="#fff" />
      ) : (
        <Ionicons name={icon} size={18} color="#fff" />
      )}
      <Text style={{ color: '#fff', fontSize: 15, fontFamily: 'Nunito_700Bold' }}>{label}</Text>
    </TouchableOpacity>
  );
}

function PlatformOption({
  icon,
  label,
  selected,
  onPress,
  colors,
}: {
  icon: React.ComponentProps<typeof Ionicons>['name'];
  label: string;
  selected: boolean;
  onPress: () => void;
  colors: ColorScheme;
}) {
  return (
    <TouchableOpacity
      onPress={onPress}
      activeOpacity={0.7}
      style={{
        flex: 1,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
        paddingVertical: 14,
        borderRadius: 12,
        backgroundColor: colors.card,
        borderWidth: 2,
        borderColor: selected ? '#007AFF' : colors.border,
      }}
    >
      <Ionicons name={icon} size={18} color={selected ? '#007AFF' : colors.textMuted} />
      <Text
        style={{
          fontSize: 15,
          fontFamily: 'Nunito_700Bold',
          color: selected ? '#007AFF' : colors.text,
        }}
      >
        {label}
      </Text>
    </TouchableOpacity>
  );
}

function formatRemaining(seconds: number): string {
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  return `${m}:${String(s).padStart(2, '0')}`;
}
