/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
*/
import React, { useState, useEffect, useCallback } from 'react';
import ControlPanel from './components/ControlPanel';
import ResumePreview from './components/ResumePreview';
import JobMatchDashboard from './components/JobMatchDashboard';
import LoadingSpinner from './components/LoadingSpinner';
import type { InitialInput, ResumeDocument, ResumeSectionType, ScoreResponse, ActiveEditor } from './lib/types';

// Custom hook for debouncing
const useDebounce = (callback: (...args: any[]) => void, delay: number) => {
  const [timeoutId, setTimeoutId] = useState<NodeJS.Timeout | null>(null);

  return useCallback((...args: any[]) => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }
    const newTimeoutId = setTimeout(() => {
      callback(...args);
    }, delay);
    setTimeoutId(newTimeoutId);
  }, [callback, delay, timeoutId]);
};

export default function App() {
  const [jobDescription, setJobDescription] = useState<string>('');
  const [resumeDocument, setResumeDocument] = useState<ResumeDocument>([]);
  const [activeEditor, setActiveEditor] = useState<ActiveEditor | null>(null);
  const [scoreData, setScoreData] = useState<ScoreResponse>({ score: 0, suggestions: [] });
  
  const [isGenerating, setIsGenerating] = useState(false); // For initial generation
  const [isScoring, setIsScoring] = useState(false);       // For real-time scoring
  const [isRefining, setIsRefining] = useState(false);     // For co-pilot actions
  const [error, setError] = useState<string | null>(null);
  
  const parseFullResumeText = (fullText: string): ResumeDocument => {
    const sections: ResumeDocument = [];
    const sectionTitles: ResumeSectionType[] = ["Professional Summary", "Skills Section", "Experience", "Education"];
    const sectionRegex = new RegExp(`##\\s*(${sectionTitles.join('|')})\\s*([\\s\\S]*?)(?=\\n##\\s*(?:${sectionTitles.join('|')})|$)`, 'g');
    
    let match;
    while ((match = sectionRegex.exec(fullText)) !== null) {
      const title = match[1].trim() as ResumeSectionType;
      const content = match[2].trim();
      sections.push({ id: title, title, content });
    }
    return sections;
  };

  const handleInitialGenerate = async (input: InitialInput) => {
    setIsGenerating(true);
    setError(null);
    setJobDescription(input.jobDescription || '');
    setResumeDocument([]);
    setScoreData({ score: 0, suggestions: [] });

    try {
      const response = await fetch('http://127.0.0.1:5000/api/generate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(input),
      });

      if (!response.ok) throw new Error((await response.json()).error || 'Server error');
      const data = await response.json();
      const parsedSections = parseFullResumeText(data.resume);
      setResumeDocument(parsedSections);
    } catch (err) {
      handleFetchError(err, "Could not generate resume.");
    } finally {
      setIsGenerating(false);
    }
  };

  const debouncedScoreRequest = useDebounce(async (doc: ResumeDocument, jd: string) => {
    if (!jd || doc.length === 0) return;
    setIsScoring(true);
    try {
      const fullText = doc.map(s => `## ${s.title}\n${s.content}`).join('\n\n');
      const response = await fetch('http://127.0.0.1:5000/api/score', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ resume: fullText, job_description: jd }),
      });
      if (!response.ok) return; // Fail silently on scoring
      const data: ScoreResponse = await response.json();
      setScoreData(data);
    } catch (err) {
      // Don't show scoring errors to user to avoid being noisy
      console.error("Scoring error:", err);
    } finally {
      setIsScoring(false);
    }
  }, 1500); // 1.5-second debounce delay

  useEffect(() => {
    if (resumeDocument.length > 0 && jobDescription) {
      debouncedScoreRequest(resumeDocument, jobDescription);
    }
  }, [resumeDocument, jobDescription, debouncedScoreRequest]);

  const handleContentUpdate = (sectionId: ResumeSectionType, newContent: string) => {
    setResumeDocument(prevDoc =>
      prevDoc.map(section =>
        section.id === sectionId ? { ...section, content: newContent } : section
      )
    );
  };
  
  const handleRefineSection = async (instruction: string) => {
      if (!activeEditor) return;
      setIsRefining(true);
      setError(null);
      try {
          const response = await fetch('http://127.0.0.1:5000/api/refine_section', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                  text_to_refine: activeEditor.content,
                  instruction: instruction
              }),
          });
          if (!response.ok) throw new Error((await response.json()).error || 'Server error during refinement.');
          const data = await response.json();
          handleContentUpdate(activeEditor.sectionId, data.refined_text);
      } catch (err) {
          handleFetchError(err, "Could not refine section.");
      } finally {
          setIsRefining(false);
      }
  };

  const handleFetchError = (err: any, context: string) => {
    let message = err instanceof Error ? err.message : "An unknown error occurred.";
    if (message.includes('Failed to fetch')) {
      message = "Could not connect to the backend server. Is it running? Please start the Python server and try again.";
    }
    setError(`${context} ${message}`);
  };

  const clearAll = () => {
    setJobDescription('');
    setResumeDocument([]);
    setActiveEditor(null);
    setScoreData({ score: 0, suggestions: [] });
    setError(null);
  };

  return (
    <div className="app-container">
      <header className="app-header">
        <h1>AI Resume Studio</h1>
        <p>Your intelligent co-pilot for crafting the perfect resume.</p>
      </header>

      {isGenerating && <div className="global-loading-overlay"><LoadingSpinner /></div>}
      
      {error && <div className="error-message global-error">{error}</div>}

      <div className="app-content-grid">
        <aside className="control-column">
          <ControlPanel
            onGenerate={handleInitialGenerate}
            onClear={clearAll}
            activeEditor={activeEditor}
            onRefine={handleRefineSection}
            isGenerating={isGenerating}
            isRefining={isRefining}
          />
        </aside>
        
        <main className="resume-column">
          {resumeDocument.length > 0 ? (
            <ResumePreview 
              document={resumeDocument}
              onContentChange={handleContentUpdate}
              activeSectionId={activeEditor?.sectionId}
              onSectionFocus={setActiveEditor}
            />
          ) : (
             <div className="placeholder-text">
                <p>Your AI-crafted resume will appear here. Fill in the "Initial Setup" form and click "Generate" to begin!</p>
            </div>
          )}
        </main>
        
        <aside className="dashboard-column">
          <JobMatchDashboard
            score={scoreData.score}
            suggestions={scoreData.suggestions}
            isLoading={isScoring}
            hasContent={resumeDocument.length > 0 && jobDescription.length > 0}
          />
        </aside>
      </div>
    </div>
  );
}
