import React, { useState } from 'react';
import mammoth from 'mammoth';

const UploadModal = ({ isOpen, onClose, onCVParse }) => {
  const [file, setFile] = useState(null);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState('');
  const [dragActive, setDragActive] = useState(false);
  const [parsingProgress, setParsingProgress] = useState('');

  const handleDrag = (e) => {
    e.preventDefault();
    e.stopPropagation();
    if (e.type === "dragenter" || e.type === "dragover") {
      setDragActive(true);
    } else if (e.type === "dragleave") {
      setDragActive(false);
    }
  };

  const handleDrop = (e) => {
    e.preventDefault();
    e.stopPropagation();
    setDragActive(false);
    
    const droppedFile = e.dataTransfer.files[0];
    if (droppedFile && (droppedFile.type === 'application/pdf' || 
        droppedFile.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
        droppedFile.type === 'text/plain')) {
      setFile(droppedFile);
      setError('');
    } else {
      setError('Please upload PDF, DOCX, or TXT file');
    }
  };

  const handleFileSelect = (e) => {
    const selectedFile = e.target.files[0];
    if (selectedFile) {
      setFile(selectedFile);
      setError('');
    }
  };

  // Function to extract text from DOCX files using mammoth
  const extractTextFromDOCX = async (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      
      reader.onload = async (e) => {
        try {
          const arrayBuffer = e.target.result;
          const result = await mammoth.extractRawText({ arrayBuffer: arrayBuffer });
          resolve(result.value);
        } catch (error) {
          console.error('DOCX parsing error:', error);
          reject(new Error('Failed to parse DOCX file. Please ensure it\'s a valid Word document.'));
        }
      };
      
      reader.onerror = () => {
        reject(new Error('Failed to read the DOCX file'));
      };
      
      reader.readAsArrayBuffer(file);
    });
  };

  // Function to extract text from PDF files
  const extractTextFromPDF = async (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      
      reader.onload = async (e) => {
        try {
          // Simple PDF text extraction - looks for text between operators
          const content = e.target.result;
          const text = extractTextFromPDFContent(content);
          resolve(text);
        } catch (error) {
          console.error('PDF parsing error:', error);
          reject(new Error('Failed to parse PDF file. Try converting to TXT format for better results.'));
        }
      };
      
      reader.onerror = () => {
        reject(new Error('Failed to read the PDF file'));
      };
      
      reader.readAsBinaryString(file);
    });
  };

  // Helper function to extract text from PDF binary content
  const extractTextFromPDFContent = (content) => {
    // Look for text between BT (Begin Text) and ET (End Text) operators
    const textMatches = [];
    const btPositions = [];
    let pos = 0;
    
    // Find all BT positions
    while (true) {
      const btPos = content.indexOf('BT', pos);
      if (btPos === -1) break;
      btPositions.push(btPos);
      pos = btPos + 2;
    }
    
    // Extract text between BT and ET
    for (const btPos of btPositions) {
      const etPos = content.indexOf('ET', btPos);
      if (etPos !== -1) {
        const textBlock = content.substring(btPos, etPos);
        // Extract text within parentheses
        const parenMatches = textBlock.match(/\(([^)]+)\)/g);
        if (parenMatches) {
          parenMatches.forEach(match => {
            const cleanText = match.substring(1, match.length - 1);
            if (cleanText.trim().length > 0 && !cleanText.match(/^[\d\s\.]+$/)) {
              textMatches.push(cleanText);
            }
          });
        }
      }
    }
    
    let extractedText = textMatches.join(' ');
    
    // If no text found with BT/ET, try alternative method
    if (extractedText.length < 50) {
      const allParenMatches = content.match(/\(([^)]+)\)/g);
      if (allParenMatches) {
        const texts = [];
        allParenMatches.forEach(match => {
          const cleanText = match.substring(1, match.length - 1);
          if (cleanText.length > 10 && !cleanText.match(/^[\d\s\.]+$/)) {
            texts.push(cleanText);
          }
        });
        extractedText = texts.join(' ');
      }
    }
    
    return extractedText || "Could not extract text from PDF. Please convert to TXT format.";
  };

  // Function to extract text from TXT files
  const extractTextFromTXT = async (file) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      
      reader.onload = (e) => {
        resolve(e.target.result);
      };
      
      reader.onerror = () => {
        reject(new Error('Failed to read the text file'));
      };
      
      reader.readAsText(file);
    });
  };

  // Main function to extract text based on file type
  const extractTextFromFile = async (file) => {
    const fileType = file.type;
    const fileName = file.name;
    const extension = fileName.split('.').pop().toLowerCase();
    
    setParsingProgress('Reading file...');
    
    try {
      if (fileType === 'text/plain' || extension === 'txt') {
        return await extractTextFromTXT(file);
      } 
      else if (fileType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || extension === 'docx') {
        return await extractTextFromDOCX(file);
      }
      else if (fileType === 'application/pdf' || extension === 'pdf') {
        return await extractTextFromPDF(file);
      }
      else {
        throw new Error('Unsupported file format. Please upload TXT, DOCX, or PDF files.');
      }
    } catch (error) {
      console.error('Extraction error:', error);
      throw error;
    }
  };

  // Function to parse CV text and extract information
  const parseCVText = (text) => {
    setParsingProgress('Extracting information...');
    
    console.log('Raw extracted text:', text.substring(0, 500)); // Debug log
    
    // Extract email
    const emailMatch = text.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/);
    const email = emailMatch ? emailMatch[0] : '';
    
    // Extract phone numbers (various formats)
    const phonePatterns = [
      /(\+\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/,
      /\d{3}[-.\s]\d{3}[-.\s]\d{4}/,
      /\(\d{3}\)\s?\d{3}-\d{4}/
    ];
    
    let phone = '';
    for (const pattern of phonePatterns) {
      const match = text.match(pattern);
      if (match) {
        phone = match[0];
        break;
      }
    }
    
    // Extract name (look for common patterns)
    const lines = text.split(/\r?\n/).filter(l => l.trim().length > 0);
    let name = '';
    
    // Name is often in the first 3 lines, not containing special characters
    for (let i = 0; i < Math.min(5, lines.length); i++) {
      const line = lines[i].trim();
      // Name should be 2-4 words, no email, no special chars except spaces and dots
      if (line.length > 3 && line.length < 50 && 
          !line.includes('@') && 
          !line.match(/http|www|\.com|\.org|\.net/i) &&
          line.split(' ').length >= 2 &&
          line.split(' ').length <= 5) {
        name = line;
        break;
      }
    }
    
    // Extract title (professional titles)
    const titlePatterns = [
      /(Senior|Lead|Principal|Head|Director|Manager|Consultant|Specialist|Architect)\s+(?:Full[\s-]?Stack|Software|Frontend|Backend|DevOps|Data|Product|Project|UX|UI|Graphic)?\s*(?:Developer|Engineer|Designer|Analyst|Consultant|Manager)/i,
      /(?:Full[\s-]?Stack|Software|Frontend|Backend|DevOps|Data|Product|Project|UX|UI|Graphic)\s+(?:Developer|Engineer|Designer|Analyst|Consultant|Manager)/i,
      /(?:Developer|Engineer|Designer|Analyst|Consultant|Manager|Director|Head|Lead)/i
    ];
    
    let title = '';
    for (const pattern of titlePatterns) {
      const match = text.match(pattern);
      if (match) {
        title = match[0];
        break;
      }
    }
    
    // Extract location (city, state, country patterns)
    const locationPatterns = [
      /[A-Z][a-z]+,\s*[A-Z]{2}/,
      /[A-Z][a-z]+\s+[A-Z][a-z]+,\s*[A-Z]{2}/,
      /(?:New York|Los Angeles|Chicago|Houston|Phoenix|Philadelphia|San Antonio|San Diego|Dallas|Austin|San Francisco|Seattle|Denver|Boston|Atlanta|Miami|Portland|Detroit|Memphis|Nashville|Baltimore|Charlotte|Fort Worth|Milwaukee|El Paso|Washington|Las Vegas)/i
    ];
    
    let location = '';
    for (const pattern of locationPatterns) {
      const match = text.match(pattern);
      if (match) {
        location = match[0];
        break;
      }
    }
    
    // Extract summary (first substantial paragraph after name/title)
    let summary = '';
    const paragraphs = text.split(/\n\s*\n/);
    let foundPersonalInfo = false;
    
    for (let para of paragraphs) {
      const cleanPara = para.trim();
      // Skip very short paragraphs or those with only contact info
      if (cleanPara.length > 80 && cleanPara.length < 600) {
        // Check if it contains contact info
        if (!cleanPara.match(/@|phone|cell|mobile|tel/i) || cleanPara.length > 100) {
          if (!summary && !cleanPara.match(/experience|education|skills|employment/i)) {
            summary = cleanPara.substring(0, 400);
            break;
          }
        }
      }
    }
    
    // Extract skills (comprehensive list)
    const skillKeywords = [
      'React', 'React.js', 'ReactJS', 'Angular', 'AngularJS', 'Vue', 'Vue.js', 'VueJS',
      'JavaScript', 'ES6', 'TypeScript', 'Node.js', 'NodeJS', 'Express.js', 'Express',
      'Python', 'Django', 'Flask', 'Java', 'Spring', 'Spring Boot', 'C#', '.NET', 'ASP.NET',
      'PHP', 'Laravel', 'Symfony', 'Ruby', 'Ruby on Rails', 'Rails', 'Go', 'Golang', 'Rust',
      'HTML', 'HTML5', 'CSS', 'CSS3', 'SASS', 'SCSS', 'LESS', 'Tailwind', 'Bootstrap',
      'jQuery', 'AJAX', 'JSON', 'XML', 'REST API', 'GraphQL', 'Apollo',
      'SQL', 'MySQL', 'PostgreSQL', 'MongoDB', 'Mongoose', 'Firebase', 'Redis', 'Cassandra',
      'Docker', 'Kubernetes', 'K8s', 'Jenkins', 'Git', 'GitHub', 'GitLab', 'Bitbucket',
      'AWS', 'Amazon Web Services', 'Azure', 'Google Cloud', 'GCP', 'Heroku', 'Netlify', 'Vercel',
      'Figma', 'Adobe XD', 'Photoshop', 'Illustrator', 'Sketch', 'InVision',
      'Agile', 'Scrum', 'Kanban', 'JIRA', 'Trello', 'Asana', 'Slack',
      'Machine Learning', 'AI', 'Data Science', 'TensorFlow', 'PyTorch', 'Pandas', 'NumPy',
      'Tableau', 'Power BI', 'Excel', 'Word', 'PowerPoint',
      'Leadership', 'Communication', 'Problem Solving', 'Team Management', 'Project Management'
    ];
    
    const foundSkills = [];
    const textLower = text.toLowerCase();
    
    skillKeywords.forEach(skill => {
      const skillLower = skill.toLowerCase();
      // Use word boundary for better matching
      const regex = new RegExp(`\\b${skillLower.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i');
      if (regex.test(textLower) || textLower.includes(skillLower)) {
        if (!foundSkills.includes(skill)) {
          foundSkills.push(skill);
        }
      }
    });
    
    // Extract experience entries
    const experience = [];
    const datePattern = /(19|20)\d{2}[\s\-–]+(?:19|20)\d{2}|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*[\s\-–]+(?:19|20)\d{2}[\s\-–]+(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*[\s\-–]+(?:19|20)\d{2}|(?:19|20)\d{2}[\s\-–]+Present|(?:19|20)\d{2}[\s\-–]+Current/gi;
    
    // Split into sections
    const sections = text.split(/\n\s*\n/);
    let experienceSection = false;
    let currentJob = null;
    
    for (let i = 0; i < sections.length; i++) {
      const section = sections[i];
      const sectionLower = section.toLowerCase();
      
      // Check for experience section header
      if (sectionLower.match(/experience|work history|employment|professional experience|work experience|career history/)) {
        experienceSection = true;
        continue;
      }
      
      // Stop at next major section
      if (experienceSection && sectionLower.match(/education|skills|references|certifications|languages|projects/)) {
        experienceSection = false;
        if (currentJob && (currentJob.company || currentJob.position)) {
          experience.push(currentJob);
          currentJob = null;
        }
        continue;
      }
      
      // Parse job entries
      if (experienceSection && section.length > 30) {
        // Check if this looks like a job entry
        const hasDate = section.match(datePattern);
        const hasCompany = section.match(/at\s+([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)/i) || 
                          section.match(/([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\s+\(/);
        
        if (hasDate || hasCompany || section.split('\n').length <= 6) {
          // Save previous job
          if (currentJob && (currentJob.company || currentJob.position)) {
            experience.push(currentJob);
          }
          
          // Create new job entry
          currentJob = {
            id: Date.now() + experience.length + Math.random(),
            company: '',
            position: '',
            start_date: '',
            end_date: '',
            description: section.substring(0, 300).trim()
          };
          
          // Extract company name
          const companyMatch = section.match(/at\s+([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)/i) ||
                              section.match(/([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*(?:Inc|Corp|LLC|Ltd|Company|Technologies|Tech|Solutions|Group))/i);
          if (companyMatch) {
            currentJob.company = companyMatch[1] || companyMatch[0];
            currentJob.company = currentJob.company.replace(/^at\s+/i, '').trim();
          }
          
          // Extract position title
          const positionMatch = section.match(/(Senior|Lead|Principal|Head|Director|Manager|Consultant|Specialist|Architect|Junior|Associate)?\s*(Full[\s-]?Stack|Software|Frontend|Backend|DevOps|Data|Product|Project|UX|UI|Graphic)?\s*(Developer|Engineer|Designer|Analyst|Consultant|Manager)/i);
          if (positionMatch) {
            currentJob.position = positionMatch[0].trim();
          }
          
          // Extract dates
          const dates = section.match(datePattern);
          if (dates && dates.length > 0) {
            const dateStr = dates[0];
            const dateParts = dateStr.split(/[\s\-–]+/);
            if (dateParts.length >= 2) {
              currentJob.start_date = dateParts[0];
              currentJob.end_date = dateParts[dateParts.length - 1];
            }
          }
        } else if (currentJob) {
          // Append to current job description
          currentJob.description += ' ' + section.substring(0, 200);
        }
      }
    }
    
    // Add last job if exists
    if (currentJob && (currentJob.company || currentJob.position)) {
      experience.push(currentJob);
    }
    
    // Extract education
    const education = [];
    let educationSection = false;
    const educationKeywords = ['Bachelor', 'Master', 'PhD', 'B.Sc', 'M.Sc', 'B.A', 'M.A', 'BBA', 'MBA', 
                               'Degree', 'University', 'College', 'Institute', 'School', 'Diploma',
                               'Associate', 'Certificate', 'Certification'];
    
    for (let i = 0; i < sections.length; i++) {
      const section = sections[i];
      const sectionLower = section.toLowerCase();
      
      if (sectionLower.match(/education|academic background|qualifications/)) {
        educationSection = true;
        continue;
      }
      
      if (educationSection && sectionLower.match(/experience|skills|references|projects/)) {
        educationSection = false;
        continue;
      }
      
      if (educationSection && section.length > 20) {
        let hasEducation = false;
        let degree = '';
        let school = '';
        let year = '';
        
        // Check for education keywords
        for (let keyword of educationKeywords) {
          if (section.match(new RegExp(keyword, 'i'))) {
            hasEducation = true;
            break;
          }
        }
        
        if (hasEducation) {
          // Extract degree
          const degreeMatch = section.match(/(Bachelor|Master|PhD|B\.?Sc|M\.?Sc|B\.?A|M\.?A|BBA|MBA|Associate|Diploma)[^\n]{0,50}/i);
          if (degreeMatch) degree = degreeMatch[0].trim();
          
          // Extract school
          const schoolMatch = section.match(/(?:University|College|Institute|School)\s+of\s+[A-Z][a-z]+|[A-Z][a-z]+\s+(?:University|College)/i);
          if (schoolMatch) school = schoolMatch[0];
          
          // Extract year
          const yearMatch = section.match(/(19|20)\d{2}/);
          if (yearMatch) year = yearMatch[0];
          
          education.push({
            id: Date.now() + education.length + Math.random(),
            degree: degree || section.substring(0, 100).trim(),
            school: school || '',
            year: year || ''
          });
        }
      }
    }
    
    setParsingProgress('Complete!');
    
    const result = {
      personal: {
        name: name,
        title: title,
        email: email,
        phone: phone,
        location: location
      },
      summary: summary,
      skills: [...new Set(foundSkills)].slice(0, 20), // Remove duplicates, limit to 20
      experience: experience.slice(0, 5),
      education: education.slice(0, 3)
    };
    
    console.log('Parsed result:', result);
    return result;
  };

  const handleUpload = async () => {
    if (!file) {
      setError('Please select a file');
      return;
    }

    setUploading(true);
    setError('');
    setParsingProgress('Starting...');
    
    try {
      // Extract text from the uploaded file
      const extractedText = await extractTextFromFile(file);
      
      console.log('Extracted text length:', extractedText.length);
      console.log('First 500 chars:', extractedText.substring(0, 500));
      
      if (!extractedText || extractedText.length < 50) {
        throw new Error('Could not extract enough text from the file. Please ensure the file contains readable text.');
      }
      
      setParsingProgress('Analyzing content...');
      
      // Parse the extracted text
      const parsedData = parseCVText(extractedText);
      
      // Check if we found any data
      const hasData = parsedData.personal.name || 
                      parsedData.personal.email || 
                      parsedData.skills.length > 0 || 
                      parsedData.experience.length > 0;
      
      if (!hasData) {
        throw new Error('No CV data could be extracted. Please try a different file format or ensure the file contains clear text.');
      }
      
      // Send to parent component
      onCVParse(parsedData);
      onClose();
      setFile(null);
      setParsingProgress('');
      
    } catch (err) {
      console.error('Upload error:', err);
      setError(err.message || 'Failed to parse CV. Please try a plain text (.txt) file for best results.');
    } finally {
      setUploading(false);
      setParsingProgress('');
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
      <div className="bg-white rounded-lg max-w-md w-full mx-4 p-6">
        <div className="flex justify-between items-center mb-4">
          <h2 className="text-2xl font-bold text-gray-800">Upload Your CV</h2>
          <button onClick={onClose} className="text-gray-500 hover:text-gray-700">
            <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        <div 
          className={`border-2 border-dashed rounded-lg p-8 text-center transition-colors ${
            dragActive ? 'border-blue-500 bg-blue-50' : 'border-gray-300'
          }`}
          onDragEnter={handleDrag}
          onDragLeave={handleDrag}
          onDragOver={handleDrag}
          onDrop={handleDrop}
        >
          <svg className="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
          </svg>
          
          <div className="mt-4">
            <label htmlFor="file-upload" className="cursor-pointer">
              <span className="mt-2 text-sm text-gray-600">
                Drag and drop your CV here, or
              </span>
              <span className="text-blue-500 hover:text-blue-600 ml-1">browse</span>
              <input
                id="file-upload"
                type="file"
                className="hidden"
                accept=".pdf,.docx,.txt"
                onChange={handleFileSelect}
              />
            </label>
          </div>
          
          <p className="text-xs text-gray-500 mt-2">
            Supports PDF, DOCX, TXT (Max 5MB)
          </p>
          <p className="text-xs text-green-600 mt-1">
            ✓ DOCX files now fully supported with text extraction
          </p>
        </div>

        {file && (
          <div className="mt-4 p-3 bg-gray-50 rounded-lg">
            <div className="flex items-center">
              <svg className="w-5 h-5 text-gray-500 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
              </svg>
              <span className="text-sm text-gray-700 flex-1 truncate">{file.name}</span>
              <span className="text-xs text-gray-400 ml-2">
                {(file.size / 1024).toFixed(1)} KB
              </span>
              <button onClick={() => setFile(null)} className="text-red-500 hover:text-red-600 ml-2">
                Remove
              </button>
            </div>
            <div className="text-xs text-gray-400 mt-1">
              Type: {file.type || file.name.split('.').pop().toUpperCase()}
            </div>
          </div>
        )}

        {parsingProgress && (
          <div className="mt-4 p-3 bg-blue-50 text-blue-600 rounded-lg text-sm flex items-center">
            <svg className="animate-spin h-4 w-4 mr-2" viewBox="0 0 24 24">
              <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
              <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
            </svg>
            {parsingProgress}
          </div>
        )}

        {error && (
          <div className="mt-4 p-3 bg-red-50 text-red-600 rounded-lg text-sm">
            {error}
          </div>
        )}

        <div className="mt-6 flex gap-3">
          <button
            onClick={onClose}
            className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition"
          >
            Cancel
          </button>
          <button
            onClick={handleUpload}
            disabled={!file || uploading}
            className="flex-1 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition disabled:bg-gray-300 disabled:cursor-not-allowed"
          >
            {uploading ? (
              <span className="flex items-center justify-center">
                <svg className="animate-spin h-5 w-5 mr-2" viewBox="0 0 24 24">
                  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" fill="none" />
                  <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
                </svg>
                Processing...
              </span>
            ) : (
              'Parse & Fill Form'
            )}
          </button>
        </div>

        <div className="mt-4 text-center text-xs text-gray-500">
          <p>📄 Your uploaded file will be processed to extract:</p>
          <p className="mt-1">Name • Contact • Skills • Experience • Education</p>
          <p className="mt-2 text-green-600">✓ DOCX files now fully supported</p>
        </div>
      </div>
    </div>
  );
};

export default UploadModal;