import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import {
  View,
  Text,
  TouchableOpacity,
  ActivityIndicator,
  Modal,
  Animated,
  StyleSheet,
  KeyboardAvoidingView,
  Platform,
  Image,
  ScrollView,
  Dimensions,
} from 'react-native';
import { useDubsTheme } from './theme';
import { useDubs } from '../provider';
import { useAuth } from '../hooks/useAuth';
import { usePushNotifications } from '../hooks/usePushNotifications';
import { AvatarEditor, getAvatarUrl, generateSeed, parseAvatarUrl } from './AvatarEditor';

function truncateAddress(address: string, chars = 4): string {
  if (address.length <= chars * 2 + 3) return address;
  return `${address.slice(0, chars)}...${address.slice(-chars)}`;
}

// ── Props ──

export interface UserProfileSheetProps {
  visible: boolean;
  onDismiss: () => void;
  user: {
    walletAddress: string;
    username?: string;
    avatar?: string | null;
    createdAt?: string;
  };
  onAvatarUpdated?: (newAvatarUrl: string) => void;
  onDisconnect?: () => void;
}

export function UserProfileSheet({
  visible,
  onDismiss,
  user,
  onAvatarUpdated,
  onDisconnect,
}: UserProfileSheetProps) {
  const t = useDubsTheme();
  const { client } = useDubs();
  const { refreshUser } = useAuth();
  const push = usePushNotifications();

  const overlayOpacity = useRef(new Animated.Value(0)).current;

  const parsed = useMemo(() => parseAvatarUrl(user.avatar), [user.avatar]);
  const [avatarStyle, setAvatarStyle] = useState(parsed.style);
  const [avatarSeed, setAvatarSeed] = useState(parsed.seed);
  const [bgColor, setBgColor] = useState(parsed.bg);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Re-sync when user prop changes
  useEffect(() => {
    const p = parseAvatarUrl(user.avatar);
    setAvatarStyle(p.style);
    setAvatarSeed(p.seed);
    setBgColor(p.bg);
  }, [user.avatar]);

  // Animate overlay
  useEffect(() => {
    Animated.timing(overlayOpacity, {
      toValue: visible ? 1 : 0,
      duration: 250,
      useNativeDriver: true,
    }).start();
  }, [visible, overlayOpacity]);

  // Reset error when sheet opens
  useEffect(() => {
    if (visible) setError(null);
  }, [visible]);

  const currentAvatarUrl = getAvatarUrl(avatarStyle, avatarSeed, bgColor);

  const saveAvatar = useCallback(async (newUrl: string) => {
    setSaving(true);
    setError(null);
    try {
      await client.updateProfile({ avatar: newUrl });
      await refreshUser();
      onAvatarUpdated?.(newUrl);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to update avatar');
    } finally {
      setSaving(false);
    }
  }, [client, refreshUser, onAvatarUpdated]);

  const handleStyleChange = useCallback((style: string) => {
    setAvatarStyle(style);
    saveAvatar(getAvatarUrl(style, avatarSeed, bgColor));
  }, [avatarSeed, bgColor, saveAvatar]);

  const handleShuffle = useCallback(() => {
    const newSeed = generateSeed();
    setAvatarSeed(newSeed);
    saveAvatar(getAvatarUrl(avatarStyle, newSeed, bgColor));
  }, [avatarStyle, bgColor, saveAvatar]);

  const handleBgChange = useCallback((color: string) => {
    setBgColor(color);
    saveAvatar(getAvatarUrl(avatarStyle, avatarSeed, color));
  }, [avatarStyle, avatarSeed, saveAvatar]);

  return (
    <Modal
      visible={visible}
      animationType="slide"
      transparent
      onRequestClose={onDismiss}
    >
      <Animated.View style={[styles.overlay, { opacity: overlayOpacity }]}>
        <TouchableOpacity style={styles.overlayTap} activeOpacity={1} onPress={onDismiss} />
      </Animated.View>

      <KeyboardAvoidingView
        style={styles.keyboardView}
        behavior={Platform.OS === 'ios' ? 'padding' : undefined}
      >
        <View style={styles.sheetPositioner}>
          <View style={[styles.sheet, { backgroundColor: t.background }]}>
            {/* Drag handle */}
            <View style={styles.handleRow}>
              <View style={[styles.handle, { backgroundColor: t.textMuted }]} />
            </View>

            {/* Header */}
            <View style={styles.header}>
              <Text style={[styles.headerTitle, { color: t.text }]}>Profile</Text>
              <TouchableOpacity onPress={onDismiss} activeOpacity={0.8}>
                <Text style={[styles.closeButton, { color: t.textMuted }]}>{'\u2715'}</Text>
              </TouchableOpacity>
            </View>

            <ScrollView
              style={styles.scrollContent}
              contentContainerStyle={styles.scrollContentInner}
              showsVerticalScrollIndicator={false}
              bounces={false}
            >
              {/* Avatar section */}
              <View style={styles.avatarSection}>
                <View style={[styles.avatarContainer, { borderColor: t.border }]}>
                  <Image
                    source={{ uri: currentAvatarUrl }}
                    style={styles.avatar}
                  />
                  {saving && (
                    <View style={styles.avatarLoading}>
                      <ActivityIndicator size="small" color="#FFFFFF" />
                    </View>
                  )}
                </View>
                {user.username ? (
                  <Text style={[styles.username, { color: t.text }]}>{user.username}</Text>
                ) : null}
                <Text style={[styles.walletAddress, { color: t.textMuted }]}>
                  {truncateAddress(user.walletAddress, 6)}
                </Text>
              </View>

              {/* Change Avatar */}
              <View style={styles.section}>
                <View style={styles.sectionHeaderRow}>
                  <Text style={[styles.sectionLabel, { color: t.textSecondary }]}>
                    Change Avatar
                  </Text>
                  <TouchableOpacity
                    style={[styles.shuffleButton, { borderColor: t.border }]}
                    onPress={handleShuffle}
                    activeOpacity={0.7}
                    disabled={saving}
                  >
                    <Text style={[styles.shuffleText, { color: t.accent }]}>Shuffle</Text>
                  </TouchableOpacity>
                </View>
                <AvatarEditor
                  style={avatarStyle}
                  seed={avatarSeed}
                  bg={bgColor}
                  onStyleChange={handleStyleChange}
                  onSeedChange={setAvatarSeed}
                  onBgChange={handleBgChange}
                  disabled={saving}
                />
              </View>

              {/* Error */}
              {error ? (
                <View style={[styles.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }]}>
                  <Text style={[styles.errorText, { color: t.errorText }]}>{error}</Text>
                </View>
              ) : null}

              {/* Push Notifications */}
              {push.enabled && (
                <View style={[styles.notifRow, { backgroundColor: t.surface, borderColor: t.border }]}>
                  <View style={styles.notifLeft}>
                    <Text style={[styles.notifLabel, { color: t.text }]}>Push Notifications</Text>
                    <Text
                      style={[
                        styles.notifStatus,
                        { color: push.hasPermission ? t.success : t.textMuted },
                      ]}
                    >
                      {push.hasPermission ? 'Enabled' : 'Disabled'}
                    </Text>
                  </View>
                  {!push.hasPermission && (
                    <TouchableOpacity
                      style={[styles.enableButton, { backgroundColor: t.accent }]}
                      onPress={push.register}
                      disabled={push.loading}
                      activeOpacity={0.8}
                    >
                      {push.loading ? (
                        <ActivityIndicator size="small" color="#FFFFFF" />
                      ) : (
                        <Text style={styles.enableText}>Enable</Text>
                      )}
                    </TouchableOpacity>
                  )}
                </View>
              )}

              {/* Push error */}
              {push.enabled && push.error ? (
                <View style={[styles.errorBox, { backgroundColor: t.errorBg, borderColor: t.errorBorder }]}>
                  <Text style={[styles.errorText, { color: t.errorText }]}>{push.error.message}</Text>
                </View>
              ) : null}

              {/* Disconnect */}
              {onDisconnect ? (
                <TouchableOpacity
                  style={[styles.disconnectButton, { borderColor: t.live }]}
                  onPress={onDisconnect}
                  activeOpacity={0.7}
                >
                  <Text style={[styles.disconnectText, { color: t.live }]}>Disconnect Wallet</Text>
                </TouchableOpacity>
              ) : null}
            </ScrollView>
          </View>
        </View>
      </KeyboardAvoidingView>
    </Modal>
  );
}

const styles = StyleSheet.create({
  overlay: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: 'rgba(0,0,0,0.5)',
  },
  overlayTap: {
    flex: 1,
  },
  keyboardView: {
    flex: 1,
    justifyContent: 'flex-end',
  },
  sheetPositioner: {
    justifyContent: 'flex-end',
  },
  sheet: {
    borderTopLeftRadius: 24,
    borderTopRightRadius: 24,
    paddingHorizontal: 20,
    paddingBottom: 0,
    height: Dimensions.get('window').height * 0.7,
  },
  handleRow: {
    alignItems: 'center',
    paddingTop: 10,
    paddingBottom: 8,
  },
  handle: {
    width: 36,
    height: 4,
    borderRadius: 2,
    opacity: 0.4,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingVertical: 12,
  },
  headerTitle: {
    fontSize: 20,
    fontWeight: '700',
  },
  closeButton: {
    fontSize: 20,
    padding: 4,
  },
  scrollContent: {
    flexGrow: 0,
  },
  scrollContentInner: {
    paddingBottom: 8,
  },
  avatarSection: {
    alignItems: 'center',
    paddingTop: 8,
    paddingBottom: 20,
    gap: 8,
  },
  avatarContainer: {
    width: 120,
    height: 120,
    borderRadius: 60,
    borderWidth: 2,
    overflow: 'hidden',
  },
  avatar: {
    width: '100%',
    height: '100%',
  },
  avatarLoading: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: 'rgba(0,0,0,0.35)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  username: {
    fontSize: 18,
    fontWeight: '700',
  },
  walletAddress: {
    fontSize: 13,
    fontFamily: 'monospace',
  },
  section: {
    marginBottom: 20,
    gap: 12,
  },
  sectionHeaderRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  sectionLabel: {
    fontSize: 14,
    fontWeight: '600',
  },
  shuffleButton: {
    paddingHorizontal: 14,
    paddingVertical: 6,
    borderRadius: 12,
    borderWidth: 1,
  },
  shuffleText: {
    fontSize: 13,
    fontWeight: '600',
  },
  errorBox: {
    marginBottom: 16,
    borderRadius: 12,
    borderWidth: 1,
    padding: 12,
  },
  errorText: {
    fontSize: 13,
    fontWeight: '500',
  },
  notifRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    borderRadius: 16,
    borderWidth: 1,
    paddingHorizontal: 16,
    paddingVertical: 14,
    marginBottom: 16,
  },
  notifLeft: {
    gap: 2,
  },
  notifLabel: {
    fontSize: 15,
    fontWeight: '600',
  },
  notifStatus: {
    fontSize: 13,
  },
  enableButton: {
    paddingHorizontal: 18,
    paddingVertical: 10,
    borderRadius: 12,
  },
  enableText: {
    color: '#FFFFFF',
    fontSize: 14,
    fontWeight: '700',
  },
  disconnectButton: {
    height: 52,
    borderRadius: 16,
    borderWidth: 1.5,
    justifyContent: 'center',
    alignItems: 'center',
  },
  disconnectText: {
    fontSize: 16,
    fontWeight: '700',
  },
});
