import React, { useState, useCallback, useEffect } from 'react';
import { Classification, DocumentFile, Innovation, MeetingDoc } from './types';
import { backendService } from './services/backendService';
import FilterBar from './components/FilterBar';
import DocFilterBar from './components/DocFilterBar';
import StatsDashboard from './components/StatsDashboard';
import FileContentCard from './components/FileContentCard';
import InnovationCard from './components/InnovationCard';
import { LayoutDashboard, FileText, Settings, Play, CheckCircle2, CircleDashed } from 'lucide-react';
import { useLiveQuery } from 'dexie-react-hooks';

const App: React.FC = () => {
  // Application State
  const [files, setFiles] = useState<DocumentFile[]>([]);
  const [innovations, setInnovations] = useState<Innovation[]>([]);

  const [isFetchingDocs, setIsFetchingDocs] = useState(false);
  const [isProcessing, setIsProcessing] = useState(false);

  // Progress tracking
  const [processedCount, setProcessedCount] = useState(0);
  const [currentProcessingFile, setCurrentProcessingFile] = useState<string>("");

  const [currentView, setCurrentView] = useState<'list' | 'dashboard'>('list');

  // New state for raw docs from API
  const [rawDocs, setRawDocs] = useState<MeetingDoc[]>([]);

  // Pattern state
  const [patterns, setPatterns] = useState<any[]>([]);
  const [selectedPatternId, setSelectedPatternId] = useState<number | null>(null);
  const [isAnalyzing, setIsAnalyzing] = useState(false);

  const stopRef = React.useRef(false);

  // Metadata state for Backend
  const [selectedWG, setSelectedWG] = useState<string>("");
  const [selectedMeeting, setSelectedMeeting] = useState<string>("");

  useEffect(() => {
    const fetchPatterns = async () => {
      const data = await backendService.getPatterns();
      setPatterns(data);
      if (data.length > 0) {
        setSelectedPatternId(data[0].pattern_id);
      }
    };
    fetchPatterns();
  }, []);


  const handleFetchDocuments = useCallback(async (wg: string, meeting: string) => {
    setIsFetchingDocs(true);
    setFiles([]);
    setInnovations([]);
    setRawDocs([]);
    setProcessedCount(0);
    setSelectedWG(wg);
    setSelectedMeeting(meeting);

    try {
      const response = await fetch('https://organizedprogrammers-docxtract.hf.space/docs/get_meeting_docs', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ "working_group": wg, "meeting": meeting, "custom_url": null })
      });

      if (response.ok) {
        const data = await response.json();
        if (data.data && Array.isArray(data.data)) {
          setRawDocs(data.data);
        }
      } else {
        console.error("Failed to fetch docs");
      }
    } catch (error) {
      console.error("Error fetching docs:", error);
    } finally {
      setIsFetchingDocs(false);
    }
  }, []);

  const handleFilterChange = useCallback((filteredDocs: MeetingDoc[]) => {
    // Convert MeetingDoc to DocumentFile
    const newFiles: DocumentFile[] = filteredDocs.map((doc, index) => ({
      id: doc.TDoc || `doc-${index}`,
      filename: doc.TDoc ? `${doc.TDoc}.zip` : `Document ${index}`,
      size: 'Unknown', // API doesn't provide size
      type: doc.Type,
      uploaded: false,
      status: doc["TDoc Status"],
      agendaItem: doc["Agenda item description"],
      url: doc.URL
    }));

    setFiles(newFiles);
    setProcessedCount(0);
    setInnovations([]);
  }, []);

  const handleStop = () => {
    stopRef.current = true;
  };

  // Logic: Backend Processing Engine (Phase 2 - SQLite)
  const handleExtractInnovations = async () => {
    if (files.length === 0) return;
    setIsProcessing(true);

    let startIndex = 0;

    // Resume logic: If we have processed some but not all
    if (processedCount > 0 && processedCount < files.length) {
      startIndex = processedCount;
    } else {
      // Start fresh
      setInnovations([]);
      setProcessedCount(0);
      startIndex = 0;
    }

    stopRef.current = false;

    // Sequential Processing Logic
    for (let i = startIndex; i < files.length; i++) {
      if (stopRef.current) break;

      const file = files[i];
      setCurrentProcessingFile(file.filename);

      // Process individually via Backend
      const result = await backendService.processDocument(file, selectedWG, selectedMeeting);

      if (result) {
        setInnovations(prev => [...prev, result]);
      }

      setProcessedCount(prev => prev + 1);
    }

    setIsProcessing(false);
    setCurrentProcessingFile("");
    stopRef.current = false;
  };

  const handleClassify = async (id: string, classification: Classification) => {
    // Find the innovation by ID or result_id (since InnovationCard passes result_id)
    const numId = Number(id);
    const targetInv = innovations.find(i => i.id === id || (!isNaN(numId) && i.result_id === numId));

    if (!targetInv) return;

    // 1. Update Local State
    setInnovations(prev => prev.map(inv =>
      inv.id === targetInv.id ? { ...inv, classification } : inv
    ));

    // 2. Persist to Backend if we have a result_id
    if (targetInv.result_id) {
      await backendService.saveClassification(targetInv.result_id, classification);
    }
  };

  const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file && file.type === 'text/plain') {
      const reader = new FileReader();
      reader.onload = (event) => {
        const text = event.target?.result as string;
        const newInnovation: Innovation = {
          id: `uploaded-${Date.now()}`,
          file_name: file.name,
          answer: text,
          classification: Classification.UNCLASSIFIED
        };
        setInnovations(prev => [...prev, newInnovation]);
      };
      reader.readAsText(file);
    } else {
      alert("Please upload a .txt file");
    }
  };

  const handleAnalyze = async () => {
    if (!selectedPatternId) {
      alert("Please select a pattern");
      return;
    }

    if (innovations.length === 0) {
      alert("No documents to analyze.");
      return;
    }

    setIsAnalyzing(true);
    stopRef.current = false;

    try {
      // Use index to iterate
      const total = innovations.length;

      for (let i = 0; i < total; i++) {
        if (stopRef.current) break;

        // Always get fresh state in loop if needed, but here we can iterate by index
        // However, updates need to be functional
        // Let's just grab the item from current state reference if possible or just use the initial list
        // Since we are not adding items during analysis, looking up by ID is safer for updates
        // But iterating the initial list is fine.
        const inv = innovations[i]; // accessing closed-over innovations is fine as we only read static data from it for the request

        // Skip if already analyzed or classification is DELETE
        if (inv.classification === Classification.DELETE) continue; // optimization

        let analysisData: any = null;

        // If it's an uploaded file (id starts with uploaded-), pass text content
        if (inv.id.startsWith('uploaded-')) {
          const res = await backendService.analyzeContent(selectedPatternId, undefined, inv.answer);
          if (res) analysisData = res;
        } else {
          // It's a processed doc, pass the ID
          const res = await backendService.analyzeContent(selectedPatternId, inv.id);
          if (res) analysisData = res;
        }

        if (analysisData) {
          // Real-time update
          setInnovations(current =>
            current.map(item =>
              item.id === inv.id
                ? {
                  ...item,
                  analysis_result: analysisData.content,
                  result_id: analysisData.result_id,
                  methodology: analysisData.methodology,
                  context: analysisData.context,
                  problem: analysisData.problem,
                  pattern_name: analysisData.pattern_name
                }
                : item
            )
          );
        }
      }

    } catch (error) {
      console.error("Error during analysis:", error);
    } finally {
      setIsAnalyzing(false);
      stopRef.current = false;
    }
  };

  const pendingInnovations = innovations.filter(i => i.classification !== Classification.DELETE);
  const progressPercent = files.length > 0 ? (processedCount / files.length) * 100 : 0;

  return (
    <div className="min-h-screen bg-slate-50 font-sans text-slate-900">

      {/* 1. Header */}
      <header className="bg-slate-900 text-white shadow-md sticky top-0 z-50">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
          <div className="flex justify-between h-16 items-center">
            <div className="flex items-center">
              <div className="bg-blue-500 p-1.5 rounded mr-3">
                <FileText className="h-5 w-5 text-white" />
              </div>
              <div>
                <h1 className="text-lg font-bold tracking-tight">3GPP Innovation Extractor</h1>
                <p className="text-xs text-slate-400">SQLite Backend Powered</p>
              </div>
            </div>
            <nav className="flex space-x-4">
              <button
                onClick={() => setCurrentView('list')}
                className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${currentView === 'list' ? 'bg-slate-800 text-white' : 'text-slate-300 hover:text-white hover:bg-slate-800'}`}
              >
                Extraction
              </button>
              <button
                onClick={() => setCurrentView('dashboard')}
                className={`px-3 py-2 rounded-md text-sm font-medium transition-colors ${currentView === 'dashboard' ? 'bg-slate-800 text-white' : 'text-slate-300 hover:text-white hover:bg-slate-800'}`}
              >
                Analytics
              </button>
            </nav>
          </div>
        </div>
      </header>

      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">

        {/* View: Extraction List */}
        <div className={currentView === 'list' ? 'animate-fade-in' : 'hidden'}>
          <FilterBar onFetch={handleFetchDocuments} isFetching={isFetchingDocs} />

          {rawDocs.length > 0 && (
            <DocFilterBar docs={rawDocs} onFilterChange={handleFilterChange} />
          )}

          <div className="grid grid-cols-1 lg:grid-cols-12 gap-8">

            {/* Left Column: Files & Status */}
            <div className="lg:col-span-4 space-y-6">

              {/* File Stats Card */}
              <div className="bg-white rounded-lg shadow-sm border border-slate-200 p-5">
                <div className="flex items-center justify-between mb-4">
                  <h2 className="font-semibold text-slate-800">Documents</h2>
                  <span className="text-xs font-mono bg-slate-100 px-2 py-1 rounded text-slate-600">
                    {files.length} Files
                  </span>
                </div>

                {files.length === 0 ? (
                  <div className="text-center py-8 text-slate-400 text-sm border-2 border-dashed border-slate-100 rounded-lg">
                    No documents selected
                  </div>
                ) : (
                  <div className="mb-4">
                    <div className="flex justify-between text-xs text-slate-500 mb-1">
                      <span>Processing Progress</span>
                      <span>{processedCount} / {files.length}</span>
                    </div>
                    <div className="h-2 w-full bg-slate-100 rounded-full overflow-hidden">
                      <div className="h-full bg-blue-500 transition-all duration-300" style={{ width: `${progressPercent}%` }}></div>
                    </div>
                    {isProcessing && (
                      <p className="text-xs text-blue-500 mt-2 animate-pulse">
                        Processing: {currentProcessingFile}
                      </p>
                    )}
                  </div>
                )}

                <div className="mt-4 flex space-x-2">
                  {!isProcessing && !isAnalyzing ? (
                    <button
                      onClick={handleExtractInnovations}
                      disabled={files.length === 0}
                      className="w-full bg-slate-900 hover:bg-slate-800 text-white font-medium py-3 rounded-lg shadow-md transition-all disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
                    >
                      <Play className="w-4 h-4 mr-2 fill-current" /> Start Extraction
                    </button>
                  ) : (
                    <button
                      onClick={handleStop}
                      className="w-full bg-red-600 hover:bg-red-700 text-white font-medium py-3 rounded-lg shadow-md transition-all flex items-center justify-center animate-pulse"
                    >
                      <CircleDashed className="w-4 h-4 mr-2 animate-spin" /> Stop {isProcessing ? "Extraction" : "Analysis"}
                    </button>
                  )}
                </div>
              </div>

              {/* Pattern Analysis Card */}
              <div className="bg-white rounded-lg shadow-sm border border-slate-200 p-5">
                <h2 className="font-semibold text-slate-800 mb-4">Pattern Analysis</h2>

                <div className="space-y-4">
                  <div>
                    <label className="block text-xs font-medium text-slate-500 mb-1">Select Pattern</label>
                    <select
                      className="w-full bg-slate-50 border border-slate-200 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
                      value={selectedPatternId || ''}
                      onChange={(e) => setSelectedPatternId(Number(e.target.value))}
                    >
                      {patterns.map(p => (
                        <option key={p.pattern_id} value={p.pattern_id}>{p.pattern_name}</option>
                      ))}
                    </select>
                  </div>

                  <div>
                    <label className="block text-xs font-medium text-slate-500 mb-1">Upload .txt File (Optional)</label>
                    <input
                      type="file"
                      accept=".txt"
                      onChange={handleFileUpload}
                      className="w-full text-xs text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-xs file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
                    />
                    {/* Upload status is now handled in the main list */}
                  </div>

                  {!isAnalyzing && !isProcessing ? (
                    <button
                      onClick={handleAnalyze}
                      disabled={innovations.length === 0}
                      className="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 rounded-lg shadow-sm transition-all disabled:opacity-50 flex items-center justify-center text-sm"
                    >
                      <Play className="w-4 h-4 mr-2 fill-current" /> Analyse
                    </button>
                  ) : isAnalyzing ? (
                    <button
                      onClick={handleStop}
                      className="w-full bg-red-600 hover:bg-red-700 text-white font-medium py-2 rounded-lg shadow-sm transition-all flex items-center justify-center text-sm animate-pulse"
                    >
                      <CircleDashed className="w-4 h-4 mr-2 animate-spin" /> Stop Analysis
                    </button>
                  ) : (
                    <button disabled className="w-full bg-slate-300 text-white font-medium py-2 rounded-lg shadow-sm cursor-not-allowed flex items-center justify-center text-sm">
                      Processing...
                    </button>
                  )}
                </div>
              </div>
            </div>

            {/* Right Column: Results */}
            <div className="lg:col-span-8">
              <div className="flex items-center justify-between mb-4">
                <h2 className="text-xl font-bold text-slate-800">Files content refined</h2>
                {innovations.length > 0 && (
                  <span className="text-sm text-slate-500">
                    Showing {pendingInnovations.length} potential items
                  </span>
                )}
              </div>

              {innovations.length === 0 ? (
                <div className="bg-white rounded-xl border border-dashed border-slate-300 p-12 text-center">
                  <div className="mx-auto bg-slate-50 w-16 h-16 rounded-full flex items-center justify-center mb-4">
                    <Settings className="w-8 h-8 text-slate-400" />
                  </div>
                  <h3 className="text-lg font-medium text-slate-900">Ready to Process</h3>
                  <p className="text-slate-500 max-w-sm mx-auto mt-2">
                    Load documents and start the extraction engine. The Data will be mocked and stored in your local SQLite database.
                  </p>
                </div>
              ) : (
                <div className="space-y-4">
                  {pendingInnovations.map(inv => (
                    <div key={inv.id}>
                      <FileContentCard
                        innovation={inv}
                        onClassify={handleClassify}
                      />
                      {inv.analysis_result && (
                        <div className="ml-8 mt-2">
                          <InnovationCard
                            innovation={{
                              id: inv.result_id || 0,
                              file_name: inv.file_name,
                              content: inv.analysis_result || "",
                              classification: inv.classification,
                              methodology: inv.methodology || "N/A",
                              context: inv.context || "N/A",
                              problem: inv.problem || "N/A",
                            }}
                            onClassify={handleClassify}
                          />
                        </div>
                      )}
                    </div>
                  ))}
                  {pendingInnovations.length === 0 && innovations.length > 0 && (
                    <div className="text-center py-10 text-slate-500">
                      All items have been deleted. Check the Analytics tab for stats.
                    </div>
                  )}
                </div>
              )}
            </div>
          </div>
        </div>


        {/* View: Analytics Dashboard */}
        <div className={currentView === 'dashboard' ? 'animate-fade-in' : 'hidden'}>
          <div className="flex items-center justify-between mb-6">
            <h2 className="text-2xl font-bold text-slate-900">Classification Analytics</h2>
          </div>

          <StatsDashboard innovations={[]} isVisible={currentView === 'dashboard'} />

        </div>

      </main>
    </div>
  );
};

export default App;