
import React, { useState, useCallback } from 'react';
import { UploadedImage, AppStep, GenerationResult } from './types';
import { expandPrompt, generateImage, refineImage } from './services/geminiService';
import ImageUploader from './components/ImageUploader';
import ImageSegmenter from './components/ImageSegmenter';
import PromptCustomizer from './components/PromptCustomizer';
import ImageResult from './components/ImageResult';
import StepIndicator from './components/StepIndicator';
import { SparklesIcon } from './components/icons/SparklesIcon';
import { applyMask } from './utils/canvasUtils';
import { LoggingProvider, useLogger } from './contexts/LoggingContext';
import DebugConsole from './components/DebugConsole';

const AppContent: React.FC = () => {
  const [step, setStep] = useState<AppStep>(AppStep.Upload);
  const [uploadedImages, setUploadedImages] = useState<UploadedImage[]>([]);
  const [masterPrompt, setMasterPrompt] = useState<string>('');
  const [generationResult, setGenerationResult] = useState<GenerationResult | null>(null);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [loadingMessage, setLoadingMessage] = useState<string>('');
  const [error, setError] = useState<string | null>(null);
  const { log } = useLogger();

  const handleImagesUploaded = (images: UploadedImage[]) => {
    log('info', `${images.length} images uploaded. Moving to segmentation step.`);
    setUploadedImages(images);
    setStep(AppStep.Segment);
    setError(null);
  };

  const handleSegmentationComplete = (imagesWithMasks: UploadedImage[]) => {
    log('success', `Segmentation complete for all ${imagesWithMasks.length} images. Moving to prompt step.`);
    setUploadedImages(imagesWithMasks);
    setStep(AppStep.Prompt);
    setError(null);
  };

  const handlePromptExpanded = useCallback(async (scenario: string, userInstruction: string) => {
    setIsLoading(true);
    setLoadingMessage('Expanding your idea into a master prompt...');
    setError(null);
    log('info', `Expanding prompt with scenario: "${scenario}"`);
    try {
      const prompt = await expandPrompt(scenario, userInstruction, uploadedImages);
      setMasterPrompt(prompt);
      log('success', 'Master prompt created successfully.');
    } catch (e) {
      const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during prompt expansion.';
      log('error', `Prompt expansion failed: ${errorMessage}`);
      setError(errorMessage);
    } finally {
      setIsLoading(false);
      setLoadingMessage('');
    }
  }, [uploadedImages, log]);

  const handleFinalGeneration = useCallback(async (finalPrompt: string) => {
    setIsLoading(true);
    setLoadingMessage('Generating your K-Pop thumbnail...');
    setError(null);
    log('info', 'Starting final image generation.');
    try {
        log('info', 'Applying masks to create segmented images...');
        const segmentedImages = await Promise.all(
            uploadedImages.map(async (image) => {
                if (!image.maskDataUrl) {
                    throw new Error(`Mask is missing for image: ${image.file.name}`);
                }
                const segmentedData = await applyMask(image.previewUrl, image.maskDataUrl);
                return { ...image, segmentedDataUrl: `data:image/png;base64,${segmentedData}` };
            })
        );
        log('success', 'Masks applied successfully.');
        
      const result = await generateImage(finalPrompt, segmentedImages);
      setGenerationResult({
        baseImage: result,
        currentImage: result,
        history: [result],
      });
      setStep(AppStep.Result);
      log('success', 'Thumbnail generated successfully.');
    } catch (e) {
      const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during image generation.';
      log('error', `Final image generation failed: ${errorMessage}`);
      setError(errorMessage);
      setStep(AppStep.Prompt); 
    } finally {
      setIsLoading(false);
      setLoadingMessage('');
    }
  }, [uploadedImages, log]);

  const handleImageRefinement = useCallback(async (refinementPrompt: string) => {
    if (!generationResult) return;
    setIsLoading(true);
    setLoadingMessage('Applying your refinements...');
    setError(null);
    log('info', `Refining image with prompt: "${refinementPrompt}"`);
    try {
      const newImage = await refineImage(refinementPrompt, generationResult.currentImage);
      setGenerationResult(prev => {
        if (!prev) return null;
        const newHistory = [...prev.history, newImage];
        return {
          baseImage: prev.baseImage,
          currentImage: newImage,
          history: newHistory,
        };
      });
      log('success', 'Image refined successfully.');
    } catch (e) {
      const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during image refinement.';
      log('error', `Image refinement failed: ${errorMessage}`);
      setError(errorMessage);
    } finally {
      setIsLoading(false);
      setLoadingMessage('');
    }
  }, [generationResult, log]);

  const handleBack = () => {
    setError(null);
    if (step === AppStep.Result) {
      log('info', 'Navigating back from Result to Prompt step.');
      setMasterPrompt('');
      setStep(AppStep.Prompt);
    } else if (step === AppStep.Prompt) {
        log('info', 'Navigating back from Prompt to Segment step.');
        setMasterPrompt('');
        setStep(AppStep.Segment);
    } else if (step === AppStep.Segment) {
        log('info', 'Navigating back from Segment to Upload step.');
        setStep(AppStep.Upload);
    }
  };
  
  const handleStartOver = () => {
      log('info', 'Starting over. Resetting application state.');
      setStep(AppStep.Upload);
      setUploadedImages([]);
      setMasterPrompt('');
      setGenerationResult(null);
      setIsLoading(false);
      setLoadingMessage('');
      setError(null);
  }

  const renderStep = () => {
    switch (step) {
      case AppStep.Upload:
        return <ImageUploader onImagesUploaded={handleImagesUploaded} />;
      case AppStep.Segment:
        return <ImageSegmenter
                  images={uploadedImages}
                  onComplete={handleSegmentationComplete}
                  onBack={handleBack}
                />;
      case AppStep.Prompt:
        return <PromptCustomizer 
                  onPromptExpanded={handlePromptExpanded}
                  onFinalSubmit={handleFinalGeneration}
                  isLoading={isLoading} 
                  loadingMessage={loadingMessage}
                  uploadedImages={uploadedImages} 
                  onBack={handleBack}
                  masterPrompt={masterPrompt}
                  setMasterPrompt={setMasterPrompt}
                />;
      case AppStep.Result:
        return <ImageResult 
                  result={generationResult}
                  onRefine={handleImageRefinement}
                  masterPrompt={masterPrompt}
                  isLoading={isLoading}
                  loadingMessage={loadingMessage}
                  onStartOver={handleStartOver}
                />;
      default:
        return <ImageUploader onImagesUploaded={handleImagesUploaded} />;
    }
  };

  return (
    <div className="min-h-screen bg-gray-900 text-gray-100 flex flex-col items-center p-4 sm:p-6 lg:p-8 pb-32">
      <header className="w-full max-w-6xl text-center mb-6">
         <div className="flex items-center justify-center gap-3">
          <SparklesIcon className="w-10 h-10 text-purple-400" />
          <h1 className="text-4xl sm:text-5xl md:text-6xl font-teko tracking-wider uppercase bg-gradient-to-r from-purple-400 to-pink-500 text-transparent bg-clip-text">
            K-Pop Thumbnail Genie
          </h1>
        </div>
        <p className="text-gray-400 mt-2 text-sm sm:text-base">Create stunning, emotional YouTube thumbnails with the magic of AI</p>
      </header>
      
      <main className="w-full max-w-6xl flex-grow">
        <StepIndicator currentStep={step} />
        <div className="mt-8 bg-gray-800/50 p-6 sm:p-8 rounded-2xl shadow-2xl shadow-purple-900/10 border border-gray-700">
           {error && (
            <div className="bg-red-900/50 border border-red-700 text-red-300 px-4 py-3 rounded-lg mb-6 text-center">
              <p><span className="font-bold">Error:</span> {error}</p>
            </div>
          )}
          {renderStep()}
        </div>
      </main>
      <footer className="w-full max-w-6xl text-center mt-8 text-gray-500 text-xs">
          <p>Powered by Google Gemini. Designed for K-Pop content creators.</p>
      </footer>
      <DebugConsole />
    </div>
  );
};


const App: React.FC = () => (
    <LoggingProvider>
        <AppContent />
    </LoggingProvider>
);

export default App;
