import React, { useState, useEffect, useCallback, ChangeEvent, useRef } from 'react';
import { Building, UploadCloud, FileText, Download, Eye, LoaderCircle, CheckCircle, XCircle, Wand2, History, FileCode } from 'lucide-react';
import { 
  fetchTemplates, 
  fetchTemplateContent, 
  convertResume, 
  fetchConversionHistory,
  type ConvertedFile 
} from './services/resumeService';

// --- Type Definitions ---
interface ConvertedFileWithContent extends ConvertedFile {
  template?: string;
  htmlContent?: string;
  pdfBlob?: Blob;
}

const formatDate = (date: Date): string => new Intl.DateTimeFormat('en-US', { dateStyle: 'medium', timeStyle: 'short' }).format(date);

// --- Main App Component ---
const App: React.FC = () => {
  // State
  const [templates, setTemplates] = useState<string[]>([]);
  const [selectedTemplate, setSelectedTemplate] = useState<string>('');
  const [resumeFile, setResumeFile] = useState<File | null>(null);
  const [generatedHtml, setGeneratedHtml] = useState<string | null>(null);
  const [processingState, setProcessingState] = useState<'idle' | 'parsing' | 'generating' | 'done' | 'error'>('idle');
  const [errorMessage, setErrorMessage] = useState<string>('');
  const [isLoadingTemplates, setIsLoadingTemplates] = useState<boolean>(true);
  const [isLoadingHistory, setIsLoadingHistory] = useState<boolean>(true);
  const [convertedFiles, setConvertedFiles] = useState<ConvertedFileWithContent[]>([]);
  const previewRef = useRef<HTMLIFrameElement>(null);
  
  // Effects
  useEffect(() => {
    // Fetch templates from R2
    setIsLoadingTemplates(true);
    fetchTemplates().then(data => {
      setTemplates(data);
      if (data.length > 0) setSelectedTemplate(data[0]);
    }).catch(error => {
      console.error('Error loading templates:', error);
      setErrorMessage('Failed to load templates from R2');
    }).finally(() => setIsLoadingTemplates(false));
    
    // Fetch conversion history from R2
    setIsLoadingHistory(true);
    fetchConversionHistory().then(data => {
        setConvertedFiles(data as ConvertedFileWithContent[]);
    }).catch(error => {
      console.error('Error loading history:', error);
    }).finally(() => setIsLoadingHistory(false));
  }, []);

  // Handlers
  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files[0]) handleFileSelect(e.target.files[0]);
  };

  const handleFileSelect = (file: File) => {
    const allowedTypes = ['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
    if (allowedTypes.includes(file.type)) {
      setResumeFile(file);
      setGeneratedHtml(null);
      setProcessingState('idle');
    } else {
      alert('Invalid file type. Please upload a PDF or DOCX file.');
    }
  };

  const handleGenerate = async () => {
    if (!resumeFile || !selectedTemplate) {
      setErrorMessage('Please select a template and upload a resume file.');
      setProcessingState('error');
      return;
    }
    setProcessingState('parsing');
    setErrorMessage('');
    setGeneratedHtml(null);

    try {
      // Call backend API to convert resume
      const result = await convertResume(
        resumeFile, 
        selectedTemplate,
        (message) => {
          // Update UI with progress messages
          if (message.includes('Uploading')) setProcessingState('parsing');
          else if (message.includes('Processing')) setProcessingState('generating');
        }
      );
      
      setGeneratedHtml(result.html_content);
      
      // Add to converted files list
      const newFile: ConvertedFileWithContent = {
        id: `${new Date().getTime()}-${resumeFile.name}`,
        name: resumeFile.name,
        url: result.html_url,
        size: new Blob([result.html_content]).size,
        lastModified: new Date().toISOString(),
        timestamp: new Date(),
        template: selectedTemplate,
        htmlContent: result.html_content,
      };
      setConvertedFiles(prev => [newFile, ...prev]);
      setProcessingState('done');
    } catch (e) {
      console.error(e);
      setErrorMessage(e instanceof Error ? e.message : 'An unknown error occurred during resume conversion.');
      setProcessingState('error');
    }
  };
  
  const handleDownload = async (file: ConvertedFileWithContent, format: 'html' | 'pdf') => {
      const baseName = file.name.replace(/\.[^/.]+$/, "");
      const templateName = file.template || 'resume';
      const fileName = `${baseName}_${templateName}.${format}`;
      
      const link = document.createElement('a');
      link.download = fileName;

      // For HTML files
      if (format === 'html') {
          if (file.htmlContent) {
              // Download from in-memory content
              const blob = new Blob([file.htmlContent], { type: 'text/html' });
              link.href = URL.createObjectURL(blob);
          } else if (file.url) {
              // Download from R2 URL
              link.href = file.url;
          } else {
              console.error("No HTML content or URL to download.");
              return;
          }
      } else {
          // PDF format - not supported yet in backend
          alert('PDF download will be available soon. For now, you can print the HTML preview to PDF.');
          return;
      }

      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      if (file.htmlContent) {
        URL.revokeObjectURL(link.href);
      }
  };

  const handlePreviewHistoryItem = async (file: ConvertedFileWithContent) => {
    if (file.htmlContent) {
        // Preview from in-memory content
        setGeneratedHtml(file.htmlContent);
    } else if (file.url) {
        // Fetch HTML content from R2 URL
        try {
            const response = await fetch(file.url);
            if (!response.ok) throw new Error('Failed to fetch file');
            const htmlContent = await response.text();
            setGeneratedHtml(htmlContent);
        } catch (e) {
            const message = e instanceof Error ? e.message : 'Unknown error';
            setGeneratedHtml(`<p>Error loading preview: ${message}</p>`);
        }
    } else {
        setGeneratedHtml(`<p>Preview not available for this file.</p>`);
    }
  };
  
  // UI Components
  const Card: React.FC<{ title: string; icon: React.ReactNode; children: React.ReactNode; className?: string }> = ({ title, icon, children, className }) => (
    <div className={`bg-white dark:bg-slate-800 rounded-lg shadow-md border border-slate-200 dark:border-slate-700 flex flex-col ${className}`}>
      <div className="flex items-center gap-3 p-4 border-b border-slate-200 dark:border-slate-700">
        {icon}
        <h2 className="text-lg font-bold text-slate-800 dark:text-slate-200">{title}</h2>
      </div>
      <div className="p-6 flex-grow">{children}</div>
    </div>
  );

  const dropzoneProps = {
    onDragOver: (e: React.DragEvent) => e.preventDefault(),
    onDrop: (e: React.DragEvent) => {
      e.preventDefault();
      if (e.dataTransfer.files && e.dataTransfer.files[0]) {
        handleFileSelect(e.dataTransfer.files[0]);
      }
    },
  };
  
  const getStatusIndicator = () => {
    switch (processingState) {
        case 'parsing': return <><LoaderCircle className="w-4 h-4 animate-spin" /> Extracting resume text with AI...</>;
        case 'generating': return <><LoaderCircle className="w-4 h-4 animate-spin" /> Generating HTML & PDF with AI...</>;
        case 'done': return <><CheckCircle className="w-4 h-4 text-green-500" /> Generation complete!</>;
        case 'error': return <><XCircle className="w-4 h-4 text-red-500" /> {errorMessage}</>;
        default: return null;
    }
  };
  
  const currentFile = convertedFiles.find(f => f.htmlContent === generatedHtml);

  return (
    <div className="min-h-screen bg-slate-50 dark:bg-slate-950 text-slate-800 dark:text-slate-200 p-4 sm:p-6 lg:p-8 font-sans">
      <header className="max-w-7xl mx-auto mb-10 text-center">
        <h1 className="text-4xl sm:text-5xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-primary to-sky-400 dark:to-sky-300 pb-2">
          Smart Resume Formatter
        </h1>
        <p className="text-slate-500 dark:text-slate-400 mt-1 text-lg">Generate professional resumes with AI-powered template merging.</p>
      </header>

      <main className="max-w-7xl mx-auto">
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
            <div className="space-y-8">
              <Card title="1. Select Template" icon={<Building className="w-6 h-6 text-primary" />}>
                {isLoadingTemplates ? <LoaderCircle className="w-6 h-6 animate-spin text-primary mx-auto" /> : (
                  <select
                    value={selectedTemplate}
                    onChange={(e) => setSelectedTemplate(e.target.value)}
                    className="w-full pl-3 pr-10 py-2 border border-slate-300 dark:border-slate-600 rounded-md bg-slate-50 dark:bg-slate-700 focus:ring-2 focus:ring-primary focus:border-primary outline-none"
                  >
                    {templates.map(t => <option key={t} value={t}>{t}</option>)}
                  </select>
                )}
              </Card>

              <Card title="2. Upload Resume" icon={<UploadCloud className="w-6 h-6 text-primary" />}>
                <div className="flex flex-col items-center justify-center w-full gap-4" {...dropzoneProps}>
                  <label htmlFor="file-upload" className="flex flex-col items-center justify-center w-full h-32 border-2 border-slate-300 dark:border-slate-600 border-dashed rounded-lg cursor-pointer bg-slate-50 dark:bg-slate-700/50 hover:bg-slate-100 dark:hover:bg-slate-700 transition">
                    <div className="flex flex-col items-center justify-center pt-5 pb-6">
                      {resumeFile ? (
                          <>
                            <FileText className="w-8 h-8 mb-2 text-green-500"/>
                            <p className="font-semibold text-green-600 dark:text-green-400 truncate max-w-xs px-2" title={resumeFile.name}>{resumeFile.name}</p>
                          </>
                      ) : (
                          <>
                            <UploadCloud className="w-8 h-8 mb-2 text-slate-500 dark:text-slate-400" />
                            <p className="text-sm text-slate-500 dark:text-slate-400"><span className="font-semibold">Click to upload</span> or drag & drop</p>
                            <p className="text-xs text-slate-500 dark:text-slate-400">PDF or DOCX</p>
                          </>
                      )}
                    </div>
                    <input id="file-upload" type="file" className="hidden" accept=".pdf,.docx" onChange={handleFileChange} />
                  </label>
                  <button
                    onClick={handleGenerate}
                    disabled={!resumeFile || !selectedTemplate || ['parsing', 'generating'].includes(processingState)}
                    className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-primary text-white font-semibold rounded-md hover:bg-blue-600 transition-colors disabled:bg-slate-400 disabled:cursor-not-allowed"
                  >
                    <Wand2 className="w-5 h-5" />
                    Convert & Generate
                  </button>
                  <div className={`h-6 text-sm flex items-center gap-2 ${processingState === 'error' ? 'text-red-500' : 'text-slate-500 dark:text-slate-400'}`}>
                    {getStatusIndicator()}
                  </div>
                </div>
              </Card>
            </div>

            <Card title="3. Preview & Download" icon={<Eye className="w-6 h-6 text-primary" />} className="lg:row-span-2">
                <div className="w-full h-[500px] bg-slate-100 dark:bg-slate-900 rounded-md border border-slate-300 dark:border-slate-700 overflow-hidden">
                     {generatedHtml ? (
                        <iframe
                            ref={previewRef}
                            srcDoc={generatedHtml}
                            title="Resume Preview"
                            className="w-full h-full border-0"
                            sandbox="allow-scripts"
                        />
                    ) : (
                        <div className="w-full h-full flex flex-col items-center justify-center text-slate-500 dark:text-slate-400 p-4 text-center">
                            <FileText className="w-12 h-12 mb-4 text-slate-400" />
                            <p className="font-medium">Preview will appear here</p>
                            <p className="text-sm">Generate a resume to see the result.</p>
                        </div>
                    )}
                </div>
                {generatedHtml && currentFile && (
                    <div className="grid grid-cols-2 gap-4 mt-6">
                        <button onClick={() => handleDownload(currentFile, 'html')} className="flex items-center justify-center gap-2 px-4 py-2 bg-slate-600 text-white font-semibold rounded-md hover:bg-slate-700 transition-colors">
                            <Download className="w-5 h-5" /> Download HTML
                        </button>
                        <button onClick={() => handleDownload(currentFile, 'pdf')} className="flex items-center justify-center gap-2 px-4 py-2 bg-red-600 text-white font-semibold rounded-md hover:bg-red-700 transition-colors">
                            <Download className="w-5 h-5" /> Download PDF
                        </button>
                    </div>
                )}
            </Card>
        </div>
        
        <div className="mt-12">
            <Card title="Conversion History" icon={<History className="w-6 h-6 text-primary" />}>
              {isLoadingHistory ? (
                <div className="flex justify-center items-center py-4">
                  <LoaderCircle className="w-6 h-6 animate-spin text-primary" />
                  <span className="ml-3 text-slate-500 dark:text-slate-400">Loading history from R2...</span>
                </div>
              ) : convertedFiles.length > 0 ? (
                <div className="space-y-2">
                  {convertedFiles.map((file) => (
                    <div key={file.id} className="grid grid-cols-[1fr,auto] gap-4 items-center p-3 rounded-md hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
                      <div className="truncate">
                        <p className="font-semibold text-slate-700 dark:text-slate-300 truncate" title={file.name}>{file.name}</p>
                        <p className="text-sm text-slate-500 dark:text-slate-400">
                          Template: <span className="font-medium">{file.template}</span> &bull; {formatDate(file.timestamp)}
                        </p>
                      </div>
                      <div className="flex items-center gap-2 flex-shrink-0">
                        <button onClick={() => handlePreviewHistoryItem(file)} title="Preview" className="p-2 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-600 rounded-md transition-colors"><Eye className="w-5 h-5" /></button>
                        <button onClick={() => handleDownload(file, 'html')} title="Download HTML" className="p-2 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-600 rounded-md transition-colors"><FileCode className="w-5 h-5" /></button>
                        <button onClick={() => handleDownload(file, 'pdf')} title="Download PDF" className="p-2 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-600 rounded-md transition-colors"><FileText className="w-5 h-5" /></button>
                      </div>
                    </div>
                  ))}
                </div>
              ) : (
                <p className="text-center text-slate-500 dark:text-slate-400 py-4">No converted resumes found in your bucket.</p>
              )}
            </Card>
        </div>
      </main>
    </div>
  );
};

export default App;
