import { chat } from '@chat-app/shared';
import type { AttachmentHandle } from '@chat-app/shared/chat';
import { Buffer } from 'buffer';
import { useEffect, useState } from 'react';
import { ActivityIndicator, Image, StyleSheet, Text, View } from 'react-native';

import { getCachedAttachment, setCachedAttachment } from '../lib/attachmentCache';
import { supabase } from '../lib/supabase';
import { colors } from '../theme/colors';

interface Props {
  handle: AttachmentHandle;
  ownDeviceId: string;
  ownPrivateKey: Uint8Array;
}

// Decrypts an encrypted image attachment on first mount and renders it
// inline. Subsequent mounts hit the in-memory cache. Failure (key not
// shared yet for this device, network error, etc.) shows a small error
// placeholder rather than crashing the parent message bubble.
export function AttachmentImage({ handle }: Props) {
  const [dataUrl, setDataUrl] = useState<string | null>(() => getCachedAttachment(handle.id) ?? null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (dataUrl) return;
    let cancelled = false;
    void (async () => {
      try {
        const blob = await chat.downloadAndDecryptAttachment({
          client: supabase,
          handle,
        });
        const bytes = new Uint8Array(await blob.arrayBuffer());
        const b64 = Buffer.from(bytes as unknown as ArrayLike<number>).toString('base64');
        const url = 'data:' + handle.mimeType + ';base64,' + b64;
        if (cancelled) return;
        setCachedAttachment(handle.id, url);
        setDataUrl(url);
      } catch (err: unknown) {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : 'decrypt failed');
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [dataUrl, handle]);

  // Aspect ratio honoured if available; fall back to a 4:3 placeholder.
  const aspect =
    handle.width && handle.height && handle.height > 0 ? handle.width / handle.height : 4 / 3;

  if (error) {
    return (
      <View style={[styles.placeholder, { aspectRatio: aspect }]}>
        <Text style={styles.errorText}>🔒 {error}</Text>
      </View>
    );
  }
  if (!dataUrl) {
    return (
      <View style={[styles.placeholder, { aspectRatio: aspect }]}>
        <ActivityIndicator color={colors.accent} />
      </View>
    );
  }
  return (
    <Image
      source={{ uri: dataUrl }}
      style={[styles.image, { aspectRatio: aspect }]}
      resizeMode="cover"
    />
  );
}

const styles = StyleSheet.create({
  image: {
    width: '100%',
    borderRadius: 8,
    marginTop: 4,
  },
  placeholder: {
    width: '100%',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: colors.surface,
    borderRadius: 8,
    borderColor: colors.border,
    borderWidth: 1,
    marginTop: 4,
  },
  errorText: { color: colors.danger, fontSize: 12 },
});
