import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';

export interface FileInfo {
  id: string;
  filename: string;
  upload_date: string;
  file_type: string;
  status: string;
}

interface FileContextType {
  files: FileInfo[];
  uploadFile: (file: File, signal?: AbortSignal) => Promise<string | null>;
  uploadMultipleFiles: (files: FileList) => Promise<{success: number, error: number, results: any[]}>;
  deleteFile: (fileId: string) => Promise<boolean>;
  refreshFiles: () => Promise<void>;
  searchFiles: (searchTerm: string) => Promise<void>;
  isLoading: boolean;
  isFileLoading: boolean; // 파일 관련 작업만을 위한 독립적인 로딩 상태
}

const FileContext = createContext<FileContextType | undefined>(undefined);

export const useFiles = () => {
  const context = useContext(FileContext);
  if (context === undefined) {
    throw new Error('useFiles must be used within a FileProvider');
  }
  return context;
};

export const FileProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [files, setFiles] = useState<FileInfo[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [isFileLoading, setIsFileLoading] = useState(false); // 파일 관련 작업만을 위한 독립적인 로딩 상태

  const fetchFiles = useCallback(async (searchTerm?: string) => {
    try {
      setIsFileLoading(true); // 파일 관련 작업만을 위한 독립적인 로딩 상태 사용
      console.log('📁 파일 목록 조회 시작');
      
      let url = 'http://localhost:8000/files';
      
      console.log(`📋 검색어: '${searchTerm}'`);
      
      // 검색어가 있으면 쿼리 파라미터 추가
      if (searchTerm && searchTerm.trim()) {
        const encodedSearch = encodeURIComponent(searchTerm.trim());
        url += `?search=${encodedSearch}`;
        console.log(`🔍 검색 URL: ${url}`);
        console.log(`📋 원본 검색어: '${searchTerm}'`);
        console.log(`📋 인코딩된 검색어: '${encodedSearch}'`);
      }
      
      console.log(`📤 최종 요청 URL: ${url}`);
      
      // 인증 없이 요청 (파일 목록은 누구나 조회 가능)
      console.log('📋 인증 없이 파일 목록 요청합니다.');
      
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
        // 타임아웃 설정 (10초)
        signal: AbortSignal.timeout(10000)
      });

      console.log(`📥 응답 받음: ${response.status} ${response.statusText}`);

      if (response.ok) {
        console.log('✅ 파일 조회 성공');
        const data = await response.json();
        const filesArray = data.files || []; // Extract files array
        
        // 파일 정보 형식 정규화
        const normalizedFiles = filesArray.map((file: any) => ({
          id: file.id?.toString() || '',
          filename: file.filename || '',
          upload_date: file.upload_time || file.upload_date || '',
          file_type: file.file_type || 'PDF',
          status: file.status || '완료'
        }));
        
        setFiles(normalizedFiles);
        console.log(`📁 파일 조회 완료: ${normalizedFiles.length}개 (검색어: ${searchTerm || '전체'})`);
        console.log(`📋 반환된 파일들:`, normalizedFiles.map((f: FileInfo) => f.filename));
      } else {
        console.error('❌ 파일 조회 실패');
        console.error(`📋 상태 코드: ${response.status} ${response.statusText}`);
        const errorText = await response.text();
        console.error(`📋 오류 내용: ${errorText}`);
        
        // 오류 시 빈 배열로 설정하여 "등록된 문서가 없습니다" 메시지 표시
        setFiles([]);
      }
    } catch (error) {
      console.error('❌ 파일 목록 조회 네트워크 오류');
      console.error('📋 오류 타입:', error instanceof Error ? error.name : typeof error);
      console.error('📋 오류 메시지:', error instanceof Error ? error.message : String(error));
      console.error('📋 전체 오류:', error);
      
      // 네트워크 오류 시에도 빈 배열로 설정
      setFiles([]);
    } finally {
      setIsFileLoading(false); // 파일 관련 작업만을 위한 독립적인 로딩 상태 사용
    }
  }, []);

  const searchFiles = useCallback(async (searchTerm: string) => {
    console.log('🔍 서버 검색 실행:', searchTerm);
    await fetchFiles(searchTerm);
  }, [fetchFiles]);

  const uploadFile = async (file: File, signal?: AbortSignal): Promise<string | null> => {
    try {
      console.log('📤 파일 업로드 시작');
      console.log('📋 파일명:', file.name);
      console.log('📋 파일 크기:', file.size, 'bytes');
      console.log('📋 파일 타입:', file.type);
      
      const token = localStorage.getItem('auth_token');
      
      // 파일 업로드는 로그인이 필요함
      if (!token) {
        console.log('🔒 파일 업로드를 위해서는 로그인이 필요합니다.');
        alert('파일 업로드를 위해서는 로그인이 필요합니다.');
        return null;
      }
      
      setIsLoading(true);
      const formData = new FormData();
      formData.append('file', file);

      console.log('📤 업로드 요청 전송 중...');
      console.log('📋 요청 URL: http://localhost:8000/upload');
      console.log('📋 인증 토큰 존재:', !!token);
      
      const response = await fetch('http://localhost:8000/upload', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
        },
        body: formData,
        signal: signal, // AbortSignal 추가
      });
      
      console.log('📥 업로드 응답 받음');
      console.log('📋 응답 상태:', response.status, response.statusText);

      if (response.ok) {
        console.log('✅ 파일 업로드 성공');
        const responseData = await response.json();
        const fileId = responseData.file_id;
        console.log('📋 업로드된 파일 ID:', fileId);
        
        // 업로드 성공 후 파일 목록 새로고침
        await new Promise(resolve => setTimeout(resolve, 1000)); // 1초 대기
        await fetchFiles();
        console.log('📁 파일 목록 새로고침 완료');
        return fileId;
      } else {
        console.log('❌ 파일 업로드 실패');
        
        // 499 상태 코드 처리 (클라이언트 연결 끊어짐)
        if (response.status === 499) {
          console.log('🛑 클라이언트 연결 끊어짐 - 업로드 중단됨');
          return null;
        }
        
        const errorData = await response.json();
        console.error('📋 오류 데이터:', errorData);
        alert(`파일 업로드 실패: ${errorData.detail || '알 수 없는 오류가 발생했습니다.'}`);
        return null;
      }
    } catch (error) {
      // AbortError 처리 (업로드 중단)
      if (error instanceof Error && error.name === 'AbortError') {
        console.log('🛑 파일 업로드 중단됨 (AbortError)');
        return null;
      }
      
      console.error('❌ 파일 업로드 네트워크 오류');
      console.error('📋 오류 타입:', error instanceof Error ? error.name : typeof error);
      console.error('📋 오류 메시지:', error instanceof Error ? error.message : String(error));
      console.error('📋 전체 오류:', error);
      const errorMessage = error instanceof Error ? error.message : '네트워크 오류가 발생했습니다.';
      alert(`파일 업로드 실패: ${errorMessage}`);
      return null;
    } finally {
      console.log('🏁 파일 업로드 완료');
      setIsLoading(false);
    }
  };

  const uploadMultipleFiles = async (files: FileList): Promise<{success: number, error: number, results: any[]}> => {
    try {
      console.log('멀티파일 업로드 시작:', files.length, '개 파일');
      setIsLoading(true);
      const token = localStorage.getItem('auth_token');
      const formData = new FormData();
      
      // 모든 파일을 FormData에 추가
      for (let i = 0; i < files.length; i++) {
        formData.append('files', files[i]);
      }

      console.log('멀티파일 업로드 요청 전송 중...');
      const response = await fetch('http://localhost:8000/upload-multiple', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
        },
        body: formData,
      });
      
      console.log('멀티파일 업로드 응답 받음:', response.status, response.statusText);

      if (response.ok) {
        const result = await response.json();
        console.log('멀티파일 업로드 결과:', result);
        
        // 업로드 성공 후 파일 목록 새로고침
        await fetchFiles();
        
        return {
          success: result.success_count,
          error: result.error_count,
          results: result.results
        };
      } else {
        console.error('멀티파일 업로드 실패:', response.status, response.statusText);
        const errorText = await response.text();
        console.error('오류 내용:', errorText);
        return {success: 0, error: files.length, results: []};
      }
    } catch (error) {
      console.error('멀티파일 업로드 중 오류 발생:', error);
      return {success: 0, error: files.length, results: []};
    } finally {
      setIsLoading(false);
    }
  };

  const deleteFile = async (fileId: string): Promise<boolean> => {
    try {
      console.log('🗑️ 파일 삭제 시작');
      console.log('📋 파일 ID:', fileId);
      const token = localStorage.getItem('auth_token');
      
      // 파일 삭제는 로그인이 필요함
      if (!token) {
        console.log('🔒 파일 삭제를 위해서는 로그인이 필요합니다.');
        alert('파일 삭제를 위해서는 로그인이 필요합니다.');
        return false;
      }
      
      console.log('📤 삭제 요청 전송 중...');
      console.log('📋 요청 URL:', `http://localhost:8000/files/${fileId}`);
      console.log('📋 인증 토큰 존재:', !!token);
      
      const response = await fetch(`http://localhost:8000/files/${fileId}`, {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${token}`,
        },
      });

      console.log('📥 삭제 응답 받음');
      console.log('📋 응답 상태:', response.status, response.statusText);

      if (response.ok) {
        console.log('✅ 파일 삭제 성공');
        console.log('📁 목록 새로고침 중...');
        // 즉시 UI 업데이트를 위해 파일 목록에서 해당 파일 제거
        setFiles(prevFiles => prevFiles.filter(file => file.id !== fileId));
        // 백그라운드에서 파일 목록 새로고침
        fetchFiles();
        console.log('📁 파일 목록 새로고침 완료');
        return true;
      } else {
        console.log('❌ 파일 삭제 실패');
        const errorData = await response.json();
        console.error('📋 오류 데이터:', errorData);
        return false;
      }
    } catch (error) {
      console.error('❌ 파일 삭제 네트워크 오류');
      console.error('📋 오류 타입:', error instanceof Error ? error.name : typeof error);
      console.error('📋 오류 메시지:', error instanceof Error ? error.message : String(error));
      console.error('📋 전체 오류:', error);
      return false;
    }
  };

  const refreshFiles = useCallback(async () => {
    console.log('🔄 파일 목록 새로고침 시작');
    await fetchFiles();
    console.log('✅ 파일 목록 새로고침 완료');
  }, [fetchFiles]);

  useEffect(() => {
    console.log('🚀 FileContext 초기화 - 파일 목록 조회 시작');
    fetchFiles();
  }, [fetchFiles]);

  return (
    <FileContext.Provider value={{ files, uploadFile, uploadMultipleFiles, deleteFile, refreshFiles, searchFiles, isLoading, isFileLoading }}>
      {children}
    </FileContext.Provider>
  );
};
