'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { AdminChatMessage, ChatMessage, fetchChatMediaUrl } from '@/lib/api';
import { createBlobObjectUrl, fetchAuthenticatedMediaBlob, revokeBlobObjectUrl } from '@/lib/authenticated-media';
import { parseChatMediaMetadata } from '@/lib/chat-media-album';

export type AdminChatMediaEntry = {
  blobUrl?: string;
  fileName?: string;
  mimeType?: string;
  status?: 'loading' | 'ready' | 'error';
  errorMessage?: string;
};

export function adminMessageToChatMessage(message: AdminChatMessage, roomId: string): ChatMessage {
  return {
    id: message.id,
    roomId: message.roomId ?? roomId,
    senderId: message.senderId,
    senderName: message.senderName,
    senderHasAvatar: false,
    type: message.type,
    content: message.content ?? undefined,
    storageKey: message.storageKey,
    mimeType: message.mimeType,
    metadataJson: message.metadataJson,
    createdAt: message.createdAt,
    editedAt: message.editedAt,
    isDeleted: message.isDeleted,
    isEncrypted: message.isEncrypted
  };
}

export function useAdminChatMedia(token: string | null, roomId: string | null, messages: AdminChatMessage[]) {
  const [mediaUrls, setMediaUrls] = useState<Record<string, AdminChatMediaEntry>>({});
  const mediaUrlsRef = useRef<Record<string, AdminChatMediaEntry>>({});
  const inFlightRef = useRef(new Set<string>());

  useEffect(() => {
    mediaUrlsRef.current = mediaUrls;
  }, [mediaUrls]);

  const loadMedia = useCallback(
    async (message: AdminChatMessage, force = false) => {
      if (!token || !roomId || !message.storageKey || message.isEncrypted || message.isDeleted) return;
      const storageKey = message.storageKey;
      const existing = mediaUrlsRef.current[storageKey];
      if (!force && existing?.status === 'ready' && existing.blobUrl) {
        return;
      }
      if (inFlightRef.current.has(storageKey) && !force) {
        return;
      }

      inFlightRef.current.add(storageKey);
      setMediaUrls((current) => ({
        ...current,
        [storageKey]: { ...current[storageKey], status: 'loading', errorMessage: undefined }
      }));

      const meta = parseChatMediaMetadata(message.metadataJson);
      const fileName = meta.fileName || message.content || undefined;

      try {
        const access = await fetchChatMediaUrl(roomId, storageKey, token, fileName);
        const blob = await fetchAuthenticatedMediaBlob(access.accessUrl, token, message.mimeType);
        const blobUrl = createBlobObjectUrl(blob);
        setMediaUrls((current) => {
          revokeBlobObjectUrl(current[storageKey]?.blobUrl);
          return {
            ...current,
            [storageKey]: {
              blobUrl,
              fileName,
              mimeType: message.mimeType,
              status: 'ready'
            }
          };
        });
      } catch (error) {
        setMediaUrls((current) => ({
          ...current,
          [storageKey]: {
            ...current[storageKey],
            status: 'error',
            errorMessage: error instanceof Error ? error.message : 'Не удалось загрузить файл'
          }
        }));
      } finally {
        inFlightRef.current.delete(storageKey);
      }
    },
    [roomId, token]
  );

  useEffect(() => {
    if (!token || !roomId) return;
    messages.forEach((message) => {
      if (message.storageKey && message.type === 'IMAGE') {
        void loadMedia(message);
      }
    });
  }, [loadMedia, messages, roomId, token]);

  useEffect(() => {
    return () => {
      Object.values(mediaUrlsRef.current).forEach((entry) => revokeBlobObjectUrl(entry.blobUrl));
    };
  }, []);

  return { mediaUrls, loadMedia };
}
