import React, { useState, useEffect, useCallback } from 'react';
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
import { AuthProvider, useAuth } from './contexts/AuthContext';
import LoginForm from './components/LoginForm';
import ProtectedRoute from './components/ProtectedRoute';
import DocumentUpload from './components/DocumentUpload';
import DocumentList from './components/DocumentList';
import DocumentViewer from './components/DocumentViewer';
import Analytics from './components/Analytics';
import UploadMonitoringDashboard from './components/UploadMonitoringDashboard';
import LogoutButton from './components/LogoutButton';
import { documentService, GCSErrorHandler, GCSError } from './services/documentService';
// import { debugAuth, testAPIAuth } from './utils/authDebug';

import { 
  Home, 
  Upload, 
  FileText, 
  BarChart3, 
  Plus,
  Search,
  TrendingUp,
  Activity
} from 'lucide-react';
import { cn } from './utils/cn';

// Dashboard component
const Dashboard: React.FC = () => {
  const { user, token } = useAuth();
  const [documents, setDocuments] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [viewingDocument, setViewingDocument] = useState<string | null>(null);
  const [searchTerm, setSearchTerm] = useState('');
  const [activeTab, setActiveTab] = useState<'overview' | 'documents' | 'upload' | 'analytics' | 'monitoring'>('overview');

  // Map backend status to frontend status
  const mapBackendStatus = (backendStatus: string): string => {
    switch (backendStatus) {
      case 'uploaded':
        return 'uploaded';
      case 'extracting_text':
      case 'processing_llm':
      case 'generating_pdf':
        return 'processing';
      case 'completed':
        return 'completed';
      case 'failed':
        return 'error';
      default:
        return 'pending';
    }
  };

  // Fetch documents from API
  const fetchDocuments = useCallback(async () => {
    try {
      setLoading(true);
      console.log('Fetching documents with token:', token ? 'Token available' : 'No token');
      console.log('User state:', user);
      console.log('Token preview:', token ? `${token.substring(0, 20)}...` : 'No token');
      
      if (!token) {
        console.error('No authentication token available');
        return;
      }
      
      const response = await fetch(`${import.meta.env.VITE_API_BASE_URL}/documents`, {
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });
      
      console.log('API response status:', response.status);
      
      if (response.ok) {
        const result = await response.json();
        // The API returns documents wrapped in a documents property
        const documentsArray = result.documents || result;
        if (Array.isArray(documentsArray)) {
          // Transform backend data to frontend format
          const transformedDocs = documentsArray.map((doc: any) => ({
            id: doc.id,
            name: doc.name || doc.originalName || 'Unknown',
            originalName: doc.originalName || doc.name || 'Unknown',
            status: mapBackendStatus(doc.status),
            uploadedAt: doc.uploadedAt,
            processedAt: doc.processedAt,
            uploadedBy: user?.name || user?.email || 'Unknown',
            fileSize: parseInt(doc.fileSize) || 0,
            summary: doc.summary,
            error: doc.error,
            analysisData: doc.extractedData, // Include the enhanced BPCP CIM Review Template data
          }));
          setDocuments(transformedDocs);
        }
      } else {
        console.error('API request failed:', response.status, response.statusText);
        const errorText = await response.text();
        console.error('Error response body:', errorText);
      }
    } catch (error) {
      console.error('Failed to fetch documents:', error);
    } finally {
      setLoading(false);
    }
  }, [user?.name, user?.email, token]);

  // Poll for status updates on documents that are being processed
  const pollDocumentStatus = useCallback(async (documentId: string) => {
    // Guard against undefined or null document IDs
    if (!documentId || documentId === 'undefined' || documentId === 'null') {
      console.warn('Attempted to poll for document with invalid ID:', documentId);
      return false; // Stop polling
    }
    
    try {
      if (!token) {
        console.error('No authentication token available');
        return false;
      }
      
      const response = await fetch(`https://us-central1-cim-summarizer.cloudfunctions.net/api/documents/${documentId}/progress`, {
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
      });

      if (response.ok) {
        const result = await response.json();
        if (result.success) {
          const progress = result.data;
          
          // Update the document status based on progress
          setDocuments(prev => prev.map(doc => {
            if (doc.id === documentId) {
              let newStatus = doc.status;
              
              if (progress.status === 'processing') {
                newStatus = 'processing';
              } else if (progress.status === 'completed') {
                newStatus = 'completed';
              } else if (progress.status === 'error') {
                newStatus = 'error';
              }
              
              return {
                ...doc,
                status: newStatus,
                progress: progress.progress || 0,
                message: progress.message || doc.message,
              };
            }
            return doc;
          }));
          
          // Stop polling if completed or error
          if (progress.status === 'completed' || progress.status === 'error') {
            // Refresh the documents list to get the latest data including summary
            fetchDocuments();
            return false; // Stop polling
          }
        }
      }
    } catch (error) {
      console.error('Failed to fetch document progress:', error);
    }
    
    return true; // Continue polling
  }, [token]);

  // Set up polling for documents that are being processed or uploaded (might be processing)
  useEffect(() => {
    const processingDocuments = documents.filter(doc => 
      (doc.status === 'processing' || doc.status === 'uploaded' || doc.status === 'extracting_text') && doc.id
    );
    
    if (processingDocuments.length === 0) {
      return;
    }

    const pollIntervals: NodeJS.Timeout[] = [];

    processingDocuments.forEach(doc => {
      // Skip if document ID is undefined or null
      if (!doc.id) {
        console.warn('Skipping polling for document with undefined ID:', doc);
        return;
      }
      
      const interval = setInterval(async () => {
        const shouldContinue = await pollDocumentStatus(doc.id);
        if (!shouldContinue) {
          clearInterval(interval);
        }
      }, 3000); // Poll every 3 seconds
      
      pollIntervals.push(interval);
    });

    // Cleanup intervals on unmount or when documents change
    return () => {
      pollIntervals.forEach(interval => clearInterval(interval));
    };
  }, [documents, pollDocumentStatus]);

  // Load documents on component mount and refresh periodically
  React.useEffect(() => {
    fetchDocuments();
    
    // Refresh documents every 30 seconds to catch any updates
    const refreshInterval = setInterval(() => {
      fetchDocuments();
    }, 30000);
    
    return () => clearInterval(refreshInterval);
  }, [fetchDocuments]);

  const handleUploadComplete = (documentId: string) => {
    console.log('Upload completed:', documentId);
    // Add the new document to the list with a "processing" status
    // Since we only have the ID, we'll create a minimal document object
    const newDocument = {
      id: documentId,
      status: 'processing',
      name: 'Processing...',
      originalName: 'Processing...',
      uploadedAt: new Date().toISOString(),
      fileSize: 0,
      user_id: user?.id || '',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString()
    };
    setDocuments(prev => [...prev, newDocument]);
  };

  const handleUploadError = (error: string) => {
    console.error('Upload error:', error);
    // In a real app, this would show an error notification
  };

  const handleViewDocument = (documentId: string) => {
    setViewingDocument(documentId);
  };

  const handleDownloadDocument = async (documentId: string) => {
    try {
      console.log('Downloading document:', documentId);
      const blob = await documentService.downloadDocument(documentId);
      
      // Create download link
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `document-${documentId}.pdf`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      
      console.log('Download completed');
    } catch (error) {
      console.error('Download failed:', error);
      
      // Handle GCS-specific errors
      if (GCSErrorHandler.isGCSError(error)) {
        const gcsError = error as GCSError;
        alert(`Download failed: ${GCSErrorHandler.getErrorMessage(gcsError)}`);
      } else {
        alert('Failed to download document. Please try again.');
      }
    }
  };

  const handleDeleteDocument = async (documentId: string) => {
    // Show confirmation dialog
    const confirmed = window.confirm('Are you sure you want to delete this document? This action cannot be undone.');
    if (!confirmed) {
      return;
    }

    try {
      // Call the backend API to delete the document
      await documentService.deleteDocument(documentId);
      
      // Remove from local state
      setDocuments(prev => prev.filter(doc => doc.id !== documentId));
      
      // Show success message
      alert('Document deleted successfully');
    } catch (error) {
      console.error('Failed to delete document:', error);
      alert('Failed to delete document. Please try again.');
    }
  };

  const handleRetryProcessing = (documentId: string) => {
    console.log('Retrying processing for document:', documentId);
    // In a real app, this would retry the processing
  };

  const handleBackFromViewer = () => {
    setViewingDocument(null);
  };

  // Debug functions (commented out for now)
  // const handleDebugAuth = async () => {
  //   await debugAuth();
  // };

  // const handleTestAPIAuth = async () => {
  //   await testAPIAuth();
  // };

  const filteredDocuments = documents.filter(doc =>
    (doc.name?.toLowerCase() || '').includes(searchTerm.toLowerCase()) ||
    (doc.originalName?.toLowerCase() || '').includes(searchTerm.toLowerCase())
  );

  const stats = {
    totalDocuments: documents.length,
    completedDocuments: documents.filter(d => d.status === 'completed').length,
    processingDocuments: documents.filter(d => d.status === 'processing').length,
    errorDocuments: documents.filter(d => d.status === 'error').length,
  };

  if (viewingDocument) {
    const document = documents.find(d => d.id === viewingDocument);
    if (!document) return null;



    // The new analysisData is already in the BPCP template format
    const cimReviewData = document.analysisData;

    const extractedData = cimReviewData ? {
      companyName: cimReviewData?.dealOverview?.targetCompanyName || 'Not specified',
      industry: cimReviewData?.dealOverview?.industrySector || 'Not specified',
      // For revenue and ebitda, we'll take the most recent value from the financial summary.
      revenue: cimReviewData?.financialSummary?.financials?.ltm?.revenue || 'N/A',
      ebitda: cimReviewData?.financialSummary?.financials?.ltm?.ebitda || 'N/A',
      employees: cimReviewData?.dealOverview?.employeeCount || 'Not specified',
      founded: 'Not specified', // This field is not in the new schema
      location: cimReviewData?.dealOverview?.geography || 'Not specified',
      summary: cimReviewData?.preliminaryInvestmentThesis?.keyAttractions || 'No summary available',
      keyMetrics: {
        'Transaction Type': cimReviewData?.dealOverview?.transactionType || 'Not specified',
        'Deal Source': cimReviewData?.dealOverview?.dealSource || 'Not specified',
      },
      financials: {
        revenue: [
          cimReviewData?.financialSummary?.financials?.fy3?.revenue || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy2?.revenue || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy1?.revenue || 'N/A',
          cimReviewData?.financialSummary?.financials?.ltm?.revenue || 'N/A',
        ],
        ebitda: [
          cimReviewData?.financialSummary?.financials?.fy3?.ebitda || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy2?.ebitda || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy1?.ebitda || 'N/A',
          cimReviewData?.financialSummary?.financials?.ltm?.ebitda || 'N/A',
        ],
        margins: [
          cimReviewData?.financialSummary?.financials?.fy3?.ebitdaMargin || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy2?.ebitdaMargin || 'N/A',
          cimReviewData?.financialSummary?.financials?.fy1?.ebitdaMargin || 'N/A',
          cimReviewData?.financialSummary?.financials?.ltm?.ebitdaMargin || 'N/A',
        ],
      },
      risks: [cimReviewData?.preliminaryInvestmentThesis?.potentialRisks || 'Not specified'],
      opportunities: [cimReviewData?.preliminaryInvestmentThesis?.valueCreationLevers || 'Not specified'],
    } : undefined;

    return (
      <DocumentViewer
        documentId={document.id}
        documentName={document.name}
        extractedData={extractedData}
        cimReviewData={cimReviewData}
        onBack={handleBackFromViewer}
        onDownload={() => handleDownloadDocument(document.id)}
        onShare={() => console.log('Share document:', document.id)}
      />
    );
  }

  return (
    <div className="min-h-screen bg-gray-50">
      {/* Navigation */}
      <nav className="bg-primary-600 shadow-soft border-b border-primary-700">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex justify-between h-16">
            <div className="flex items-center">
              <h1 className="text-xl font-semibold text-white">
                CIM Document Processor
              </h1>
            </div>
            <div className="flex items-center space-x-4">
              <span className="text-sm text-white">
                Welcome, {user?.name || user?.email}
              </span>
              <LogoutButton variant="button" className="bg-error-500 hover:bg-error-600 text-white" />
            </div>
          </div>
        </div>
      </nav>
      
      <div className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
        {/* Tab Navigation */}
        <div className="bg-white shadow-soft border-b border-gray-200 mb-6">
          <div className="px-4 sm:px-6 lg:px-8">
            <nav className="-mb-px flex space-x-8">
              <button
                onClick={() => setActiveTab('overview')}
                className={cn(
                  'flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200',
                  activeTab === 'overview'
                    ? 'border-primary-600 text-primary-700'
                    : 'border-transparent text-gray-500 hover:text-primary-600 hover:border-primary-300'
                )}
              >
                <Home className="h-4 w-4 mr-2" />
                Overview
              </button>
              <button
                onClick={() => setActiveTab('documents')}
                className={cn(
                  'flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200',
                  activeTab === 'documents'
                    ? 'border-primary-600 text-primary-700'
                    : 'border-transparent text-gray-500 hover:text-primary-600 hover:border-primary-300'
                )}
              >
                <FileText className="h-4 w-4 mr-2" />
                Documents
              </button>
              <button
                onClick={() => setActiveTab('upload')}
                className={cn(
                  'flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200',
                  activeTab === 'upload'
                    ? 'border-primary-600 text-primary-700'
                    : 'border-transparent text-gray-500 hover:text-primary-600 hover:border-primary-300'
                )}
              >
                <Upload className="h-4 w-4 mr-2" />
                Upload
              </button>
              <button
                onClick={() => setActiveTab('analytics')}
                className={cn(
                  'flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200',
                  activeTab === 'analytics'
                    ? 'border-primary-600 text-primary-700'
                    : 'border-transparent text-gray-500 hover:text-primary-600 hover:border-primary-300'
                )}
              >
                <TrendingUp className="h-4 w-4 mr-2" />
                Analytics
              </button>
              <button
                onClick={() => setActiveTab('monitoring')}
                className={cn(
                  'flex items-center py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200',
                  activeTab === 'monitoring'
                    ? 'border-primary-600 text-primary-700'
                    : 'border-transparent text-gray-500 hover:text-primary-600 hover:border-primary-300'
                )}
              >
                <Activity className="h-4 w-4 mr-2" />
                Monitoring
              </button>
            </nav>
          </div>
        </div>

        {/* Content */}
        <div className="px-4 sm:px-0">
          {activeTab === 'overview' && (
            <div className="space-y-6">
              {/* Stats Cards */}
              <div className="grid grid-cols-1 md:grid-cols-4 gap-6">
                <div className="bg-white overflow-hidden shadow-soft rounded-lg border border-gray-100">
                  <div className="p-5">
                    <div className="flex items-center">
                      <div className="flex-shrink-0">
                        <FileText className="h-6 w-6 text-primary-500" />
                      </div>
                      <div className="ml-5 w-0 flex-1">
                        <dl>
                          <dt className="text-sm font-medium text-gray-600 truncate">
                            Total Documents
                          </dt>
                          <dd className="text-lg font-semibold text-primary-800">
                            {stats.totalDocuments}
                          </dd>
                        </dl>
                      </div>
                    </div>
                  </div>
                </div>

                <div className="bg-white overflow-hidden shadow-soft rounded-lg border border-gray-100">
                  <div className="p-5">
                    <div className="flex items-center">
                      <div className="flex-shrink-0">
                        <BarChart3 className="h-6 w-6 text-success-500" />
                      </div>
                      <div className="ml-5 w-0 flex-1">
                        <dl>
                          <dt className="text-sm font-medium text-gray-600 truncate">
                            Completed
                          </dt>
                          <dd className="text-lg font-semibold text-primary-800">
                            {stats.completedDocuments}
                          </dd>
                        </dl>
                      </div>
                    </div>
                  </div>
                </div>

                <div className="bg-white overflow-hidden shadow-soft rounded-lg border border-gray-100">
                  <div className="p-5">
                    <div className="flex items-center">
                      <div className="flex-shrink-0">
                        <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-accent-500" />
                      </div>
                      <div className="ml-5 w-0 flex-1">
                        <dl>
                          <dt className="text-sm font-medium text-gray-600 truncate">
                            Processing
                          </dt>
                          <dd className="text-lg font-semibold text-primary-800">
                            {stats.processingDocuments}
                          </dd>
                        </dl>
                      </div>
                    </div>
                  </div>
                </div>

                <div className="bg-white overflow-hidden shadow-soft rounded-lg border border-gray-100">
                  <div className="p-5">
                    <div className="flex items-center">
                      <div className="flex-shrink-0">
                        <div className="h-6 w-6 text-error-500">⚠️</div>
                      </div>
                      <div className="ml-5 w-0 flex-1">
                        <dl>
                          <dt className="text-sm font-medium text-gray-600 truncate">
                            Errors
                          </dt>
                          <dd className="text-lg font-semibold text-primary-800">
                            {stats.errorDocuments}
                          </dd>
                        </dl>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              {/* Recent Documents */}
              <div className="bg-white shadow-soft rounded-lg border border-gray-100">
                <div className="px-4 py-5 sm:p-6">
                  <h3 className="text-lg leading-6 font-medium text-primary-800 mb-4">
                    Recent Documents
                  </h3>
                  <DocumentList
                    documents={documents.slice(0, 3)}
                    onViewDocument={handleViewDocument}
                    onDownloadDocument={handleDownloadDocument}
                    onDeleteDocument={handleDeleteDocument}
                    onRetryProcessing={handleRetryProcessing}
                    onRefresh={fetchDocuments}
                  />
                </div>
              </div>
            </div>
          )}

          {activeTab === 'documents' && (
            <div className="space-y-6">
              {/* Search and Actions */}
              <div className="bg-white shadow-soft rounded-lg border border-gray-100 p-6">
                <div className="flex items-center justify-between">
                  <div className="flex-1 max-w-lg">
                    <label htmlFor="search" className="sr-only">
                      Search documents
                    </label>
                    <div className="relative">
                      <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                        <Search className="h-5 w-5 text-gray-400" />
                      </div>
                      <input
                        id="search"
                        name="search"
                        className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-primary-500 focus:border-primary-500 sm:text-sm transition-colors duration-200"
                        placeholder="Search documents..."
                        type="search"
                        value={searchTerm}
                        onChange={(e) => setSearchTerm(e.target.value)}
                      />
                    </div>
                  </div>
                  <div className="flex space-x-3">
                    <button
                      onClick={fetchDocuments}
                      disabled={loading}
                      className="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md shadow-soft text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 disabled:opacity-50 transition-colors duration-200"
                    >
                      <div className={`h-4 w-4 mr-2 ${loading ? 'animate-spin' : ''}`}>🔄</div>
                      Refresh
                    </button>
                    <button
                      onClick={() => setActiveTab('upload')}
                      className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-soft text-white bg-accent-500 hover:bg-accent-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-500 transition-colors duration-200"
                    >
                      <Plus className="h-4 w-4 mr-2" />
                      Upload New
                    </button>
                  </div>
                </div>
              </div>

              {/* Documents List */}
              {loading ? (
                <div className="text-center py-12">
                  <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-accent-500 mx-auto mb-4"></div>
                  <p className="text-gray-600">Loading documents...</p>
                </div>
              ) : (
                <DocumentList
                  documents={filteredDocuments}
                  onViewDocument={handleViewDocument}
                  onDownloadDocument={handleDownloadDocument}
                  onDeleteDocument={handleDeleteDocument}
                  onRetryProcessing={handleRetryProcessing}
                  onRefresh={fetchDocuments}
                />
              )}
            </div>
          )}

          {activeTab === 'upload' && (
            <div className="bg-white shadow-soft rounded-lg border border-gray-100 p-6">
              <h3 className="text-lg leading-6 font-medium text-primary-800 mb-6">
                Upload CIM Documents
              </h3>
              <DocumentUpload
                onUploadComplete={handleUploadComplete}
                onUploadError={handleUploadError}
              />
            </div>
          )}

          {activeTab === 'analytics' && (
            <Analytics />
          )}

          {activeTab === 'monitoring' && (
            <UploadMonitoringDashboard />
          )}
        </div>
      </div>
    </div>
  );
};

// Login page component
const LoginPage: React.FC = () => {
  const { user } = useAuth();

  // Redirect to dashboard if already authenticated
  if (user) {
    return <Navigate to="/dashboard" replace />;
  }

  return (
    <div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
      <div className="sm:mx-auto sm:w-full sm:max-w-md">
        <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
          CIM Document Processor
        </h2>
      </div>
      <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
        <LoginForm />
      </div>
    </div>
  );
};

// Unauthorized page component
const UnauthorizedPage: React.FC = () => {
  return (
    <div className="min-h-screen bg-gray-50 flex flex-col justify-center py-12 sm:px-6 lg:px-8">
      <div className="sm:mx-auto sm:w-full sm:max-w-md">
        <div className="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
          <div className="text-center">
            <h2 className="text-2xl font-bold text-gray-900 mb-4">
              Access Denied
            </h2>
            <p className="text-gray-600 mb-6">
              You don't have permission to access this resource.
            </p>
            <LogoutButton />
          </div>
        </div>
      </div>
    </div>
  );
};

const App: React.FC = () => {
  return (
    <AuthProvider>
      <Router>
        <Routes>
          <Route path="/login" element={<LoginPage />} />
          <Route path="/unauthorized" element={<UnauthorizedPage />} />
          <Route
            path="/dashboard"
            element={
              <ProtectedRoute>
                <Dashboard />
              </ProtectedRoute>
            }
          />
          <Route path="/" element={<Navigate to="/dashboard" replace />} />
        </Routes>
      </Router>
    </AuthProvider>
  );
};

export default App;