import React, { useEffect, useRef, useState, useCallback } from 'react';
import { saveAs } from 'file-saver';
// We load PDF-LIB via CDN and access it globally as window.PDFLib

// Firebase Imports
import { initializeApp } from 'firebase/app';
import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged } from 'firebase/auth';
import { getFirestore, doc, getDoc, setDoc, getDocs, collection, query, where } from 'firebase/firestore';

// Gemini API Configuration
const API_KEY = ""; // If you want to use models other than gemini-2.5-flash-preview-09-2025 or imagen-3.0-generate-002, provide an API key here. Otherwise, leave this as-is.
const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-09-2025:generateContent?key=${API_KEY}`;


// Helper function to convert canvas to Blob
function toBlobAsync(canvas, type = 'image/png', quality = 0.92) {
    return new Promise(res => canvas.toBlob(b => res(b), type, quality));
}

// --- Age Calculation Logic ---
function calculateAgeAndMeta(dob, tob) {
    if (!dob) return null;
    const dobDate = new Date(dob + (tob ? 'T' + tob : 'T00:00'));
    const now = new Date();
    
    if (isNaN(dobDate) || dobDate > now) {
        console.error('Invalid or future date provided.');
        return null;
    }

    let y = now.getFullYear() - dobDate.getFullYear();
    let m = now.getMonth() - dobDate.getMonth();
    let d = now.getDate() - dobDate.getDate();
    if (d < 0) { m--; const prev = new Date(now.getFullYear(), now.getMonth(), 0); d += prev.getDate(); }
    if (m < 0) { y--; m += 12; }
    const totalDays = Math.floor((now - dobDate) / (24 * 60 * 60 * 1000));

    const weekday = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][dobDate.getDay()];
    const zodiac = (d) => {
        const day = d.getDate(); const month = d.getMonth() + 1;
        if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) return 'Aquarius';
        if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) return 'Pisces';
        if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) return 'Aries';
        if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) return 'Taurus';
        if ((month == 5 && day >= 21) || (month == 6 && day <= 20)) return 'Gemini';
        if ((month == 6 && day >= 21) || (month == 7 && day <= 22)) return 'Cancer';
        if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) return 'Leo';
        if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) return 'Virgo';
        if ((month == 9 && day >= 23) || (month == 10 && day <= 22)) return 'Libra';
        if ((month == 10 && day >= 23) || (month == 11 && day <= 21)) return 'Scorpio';
        if ((month == 11 && day >= 22) || (month == 12 && day <= 21)) return 'Sagittarius';
        return 'Capricorn';
    };

    return {
        summary: `${y} yrs, ${m} mo, ${d} days (${totalDays} total days)`,
        meta: `Born on ${weekday}, Zodiac: ${zodiac(dobDate)}`,
        dobDate,
    };
}


export default function App() {
    const [tab, setTab] = useState('pdf-resizer'); // Default to PDF Resizer

    // --- Firebase/Auth State ---
    const [db, setDb] = useState(null);
    const [auth, setAuth] = useState(null);
    const [userId, setUserId] = useState(null);
    const [isAuthReady, setIsAuthReady] = useState(false);
    
    // --- State for PDF Library Loading (tracks both pdf.js and pdf-lib) ---
    const [isPdfLibsLoaded, setIsPdfLibsLoaded] = useState(false);

    // --- State for Age Calculator ---
    const [dob, setDob] = useState('');
    const [tob, setTob] = useState('');
    const [ageSummary, setAgeSummary] = useState('—');
    const [birthMeta, setBirthMeta] = useState('—');
    const [countdown, setCountdown] = useState('—');
    const progressRef = useRef(null);
    const countdownTimerRef = useRef(null);
    
    // --- State for Age Calculator LLM Feature (NEW) ---
    const [birthdayInsight, setBirthdayInsight] = useState('');
    const [isInsightLoading, setIsInsightLoading] = useState(false);

    // --- State for Text Refiner LLM Feature (NEW) ---
    const [refinerText, setRefinerText] = useState('');
    const [refinerAction, setRefinerAction] = useState('Summarize');
    const [refinedOutput, setRefinedOutput] = useState('');
    const [isRefining, setIsRefining] = useState(false);

    // --- State/Refs for Image Resizer ---
    const [selectedImageFile, setSelectedImageFile] = useState(null);
    const canvasRef = useRef(null);
    const originalDimensionsRef = useRef({ width: 0, height: 0 }); 
    const [imgParams, setImgParams] = useState({ width: '', height: '', percent: 100, kb: '' });
    const [targetKb, setTargetKb] = useState(''); // State for Image KB reduction

    // --- State for PDF Reader/Converter ---
    const [pdfData, setPdfData] = useState(null);
    const [pdfFileName, setPdfFileName] = useState('');
    const pdfCanvasRef = useRef(null);
    const [loadingPdf, setLoadingPdf] = useState(false);
    const [pdfError, setPdfError] = useState(null);

    // --- State for PDF Converter ---
    const [converterFile, setConverterFile] = useState(null);
    const [conversionType, setConversionType] = useState('PDF to JPG (Working)');
    const [isConverting, setIsConverting] = useState(false);

    // --- State for PDF Resizer/Optimizer ---
    const [resizerFile, setResizerFile] = useState(null);
    const [isResizing, setIsResizing] = useState(false);
    const [resizerMessage, setResizerMessage] = useState('');
    const [originalResizerSize, setOriginalResizerSize] = useState(null);
    const [newResizerSize, setNewResizerSize] = useState(null);
    const [targetPdfKb, setTargetPdfKb] = useState(''); // NEW: State for PDF Target KB
    
    // --- Utility for robust API calls with exponential backoff ---
    const exponentialBackoffFetch = async (url, options, maxRetries = 3) => {
        let delay = 1000;
        for (let i = 0; i < maxRetries; i++) {
            try {
                const response = await fetch(url, options);
                if (response.ok) {
                    return response;
                }
                console.warn(`Attempt ${i + 1}: Received status ${response.status}. Retrying...`);
            } catch (error) {
                console.error(`Attempt ${i + 1} failed with network error: ${error.message}. Retrying...`);
            }
            if (i < maxRetries - 1) {
                await new Promise(resolve => setTimeout(resolve, delay));
                delay *= 2; // Exponential backoff
            }
        }
        throw new Error("Failed to fetch from API after multiple retries.");
    };


    // --- Firebase Initialization and Auth ---
    useEffect(() => {
        try {
            const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
            const firebaseConfig = typeof __firebase_config !== 'undefined' ? JSON.parse(__firebase_config) : {};
            const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null;

            if (Object.keys(firebaseConfig).length === 0) {
                console.error("Firebase config is missing. Cannot initialize Firebase.");
                setIsAuthReady(true); 
                return;
            }

            const app = initializeApp(firebaseConfig);
            const firestoreDb = getFirestore(app);
            const firebaseAuth = getAuth(app);
            
            setDb(firestoreDb);
            setAuth(firebaseAuth);

            onAuthStateChanged(firebaseAuth, async (user) => {
                if (user) {
                    setUserId(user.uid);
                    setIsAuthReady(true);
                } else {
                    if (initialAuthToken) {
                        try {
                            await signInWithCustomToken(firebaseAuth, initialAuthToken);
                        } catch (e) {
                            console.error("Error signing in with custom token:", e);
                            await signInAnonymously(firebaseAuth);
                            setUserId(firebaseAuth.currentUser?.uid || crypto.randomUUID());
                            setIsAuthReady(true);
                        }
                    } else {
                        await signInAnonymously(firebaseAuth);
                        setUserId(firebaseAuth.currentUser?.uid || crypto.randomUUID());
                        setIsAuthReady(true);
                    }
                }
            });

        } catch (error) {
            console.error("Firebase setup failed:", error);
            setIsAuthReady(true); 
        }
        
        return () => clearInterval(countdownTimerRef.current);
    }, []); 
    
    // --- PDF.js and PDF-LIB Dynamic Loading (Fix for import error) ---
    useEffect(() => {
        const loadScript = (src, onLoadCallback) => {
            if (document.querySelector(`script[src="${src}"]`)) {
                return true; // Already exists
            }
            const script = document.createElement('script');
            script.src = src;
            script.async = true;
            script.onload = onLoadCallback;
            document.head.appendChild(script);
            return false;
        };

        const checkReadiness = () => {
            // Check if both global objects are present
            const isPdfJsReady = typeof window.pdfjsLib !== 'undefined';
            const isPdfLibReady = typeof window.PDFLib !== 'undefined'; 
            
            if (isPdfJsReady) {
                // Set the worker source for pdf.js
                window.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.14.305/pdf.worker.min.js';
            }
            
            // Set the state true only if BOTH are loaded
            setIsPdfLibsLoaded(isPdfJsReady && isPdfLibReady);
        };

        // 1. Load PDF.js (needed for Reader/Converter)
        loadScript('https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.14.305/pdf.js', checkReadiness);

        // 2. Load PDF-LIB (needed for Resizer/Optimizer)
        loadScript('https://unpkg.com/pdf-lib/dist/pdf-lib.js', checkReadiness);
        
        // Initial check if they were already loaded (or after a script loaded)
        checkReadiness();

    }, []); 

    // --- Age Calculator Functions ---

    const startCountdown = useCallback((dobDate, ref) => {
        clearInterval(countdownTimerRef.current);
        const now = new Date();
        let next = new Date(now.getFullYear(), dobDate.getMonth(), dobDate.getDate(), dobDate.getHours() || 0, dobDate.getMinutes() || 0);
        if (next <= now) next.setFullYear(next.getFullYear() + 1);

        const updateCountdown = () => {
            const current = new Date(); const diff = next - current;
            if (diff <= 0) {
                clearInterval(countdownTimerRef.current);
                setCountdown('🎂 Happy Birthday!');
                if (ref.current) ref.current.style.width = '100%';
                return;
            }
            const days = Math.floor(diff / (1000 * 60 * 60 * 24));
            const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
            const secs = Math.floor((diff % (1000 * 60)) / 1000);
            setCountdown(`${days}d ${hours}h ${mins}m ${secs}s`);

            const last = new Date(next); last.setFullYear(next.getFullYear() - 1);
            const total = next - last; 
            const passed = current - last; 
            const pct = Math.min(100, Math.round((passed / total) * 100));
            if (ref.current) ref.current.style.width = pct + '%';
        };

        updateCountdown(); 
        countdownTimerRef.current = setInterval(updateCountdown, 1000);
    }, []);

    const onComputeAge = () => {
        // Clear previous insight when recalculating
        setBirthdayInsight(''); 
        
        const result = calculateAgeAndMeta(dob, tob);
        if (result) {
            setAgeSummary(result.summary);
            setBirthMeta(result.meta);
            startCountdown(result.dobDate, progressRef);
        } else {
            setAgeSummary('—');
            setBirthMeta('—');
            setCountdown('—');
        }
    };
    
    // --- LLM Feature 1: Birthday Insight Generator ---
    const generateBirthdayInsight = async () => {
        if (!dob || !birthMeta || birthMeta === '—') {
            setBirthdayInsight('Please compute your age first.');
            return;
        }

        setIsInsightLoading(true);
        setBirthdayInsight('Generating insight...');

        // Extract weekday and zodiac from birthMeta
        const match = birthMeta.match(/Born on (\w+), Zodiac: (\w+)/);
        if (!match) {
            setBirthdayInsight('Could not parse birth details.');
            setIsInsightLoading(false);
            return;
        }
        const weekday = match[1];
        const zodiac = match[2];

        const userQuery = `Generate a fun, concise, single-paragraph personality insight based on being born on a ${weekday} under the ${zodiac} sign. Focus on positive traits and destiny.`;

        const payload = {
            contents: [{ parts: [{ text: userQuery }] }],
            systemInstruction: {
                parts: [{ text: "Act as a friendly, imaginative astrologer providing a concise, single-paragraph personality summary. Do not include any title or introductory phrase, just the paragraph." }]
            },
        };

        try {
            const response = await exponentialBackoffFetch(API_URL, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            const result = await response.json();
            const text = result.candidates?.[0]?.content?.parts?.[0]?.text || 'Failed to generate insight.';
            setBirthdayInsight(text);

        } catch (error) {
            console.error('Gemini API Insight Failed:', error);
            setBirthdayInsight('Error: Failed to fetch personality insight.');
        } finally {
            setIsInsightLoading(false);
        }
    };
    // --- End LLM Feature 1 ---


    // --- LLM Feature 2: Text Refiner ---
    const refineText = async () => {
        if (!refinerText.trim()) {
            setRefinedOutput('Please enter some text to refine.');
            return;
        }

        setIsRefining(true);
        setRefinedOutput('Refining text...');

        let systemPrompt = "You are a professional text editor. Execute the user's request precisely. Do not add any conversational text, preamble, or conclusion, just the processed text.";
        let userQuery = refinerText;

        switch (refinerAction) {
            case 'Summarize':
                userQuery = `Summarize the following text concisely:\n\n${refinerText}`;
                break;
            case 'Paraphrase':
                userQuery = `Paraphrase the following text, keeping the meaning the same but changing the sentence structure and vocabulary:\n\n${refinerText}`;
                break;
            case 'Change Tone to Formal':
                userQuery = `Rewrite the following text in a highly formal and professional tone:\n\n${refinerText}`;
                break;
            case 'Change Tone to Casual':
                userQuery = `Rewrite the following text in a casual and friendly tone:\n\n${refinerText}`;
                break;
            default:
                break;
        }

        const payload = {
            contents: [{ parts: [{ text: userQuery }] }],
            systemInstruction: { parts: [{ text: systemPrompt }] },
        };

        try {
            const response = await exponentialBackoffFetch(API_URL, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
            });

            const result = await response.json();
            const text = result.candidates?.[0]?.content?.parts?.[0]?.text || 'Failed to refine text.';
            setRefinedOutput(text);

        } catch (error) {
            console.error('Gemini API Refiner Failed:', error);
            setRefinedOutput('Error: Failed to communicate with the refinement service.');
        } finally {
            setIsRefining(false);
        }
    };
    // --- End LLM Feature 2 ---


    // --- Image Resizer Functions (Includes KB Reduction Logic) ---

    const loadImageToCanvas = useCallback(async (file) => {
        if (!file) return;
        try {
            const img = await createImageBitmap(file);
            originalDimensionsRef.current = { width: img.width, height: img.height };
            setImgParams({
                width: img.width,
                height: img.height,
                percent: 100,
                kb: (file.size / 1024).toFixed(2)
            });
            setSelectedImageFile(file);
            setTargetKb(''); // Reset KB target
        } catch (error) {
            console.error("Error loading image:", error);
            setSelectedImageFile(null); 
        }
    }, []);

    useEffect(() => {
        const drawInitialImage = async () => {
            const canvas = canvasRef.current;
            if (!selectedImageFile || !canvas || tab !== 'image-resizer') return;

            try {
                const { width, height } = originalDimensionsRef.current;
                if (!width || !height) { return; }
                
                const img = await createImageBitmap(selectedImageFile);

                canvas.width = width;
                canvas.height = height;
                
                const ctx = canvas.getContext('2d');
                ctx.clearRect(0, 0, width, height); 
                ctx.drawImage(img, 0, 0, width, height); 

            } catch (error) {
                console.error("Error drawing image to canvas:", error);
                setSelectedImageFile(null);
            }
        };

        drawInitialImage();
    }, [selectedImageFile, tab]);


    const onImageFileSelected = (e) => {
        const file = e.target.files[0];
        if (file) {
            loadImageToCanvas(file);
        }
    };

    const handleDimensionChange = (e) => {
        const { name, value } = e.target;
        const inputVal = value === '' ? '' : parseInt(value);
        let newParams = { ...imgParams, [name]: inputVal };

        const { width: originalW, height: originalH } = originalDimensionsRef.current;
        if (!originalW || !originalH || isNaN(inputVal) || inputVal <= 0) {
            setImgParams(newParams);
            setTargetKb(''); 
            return;
        }

        const aspectRatio = originalW / originalH;

        if (name === 'width') {
            const newHeight = Math.round(inputVal / aspectRatio);
            const newPercent = Math.round((inputVal / originalW) * 100);
            newParams = { ...newParams, height: newHeight, percent: newPercent };
        } else if (name === 'height') {
            const newWidth = Math.round(inputVal * aspectRatio);
            const newPercent = Math.round((inputVal / originalH) * 100);
            newParams = { ...newParams, width: newWidth, height: newHeight };
        } else if (name === 'percent') {
            const percentage = inputVal / 100;
            const newWidth = Math.round(originalW * percentage);
            const newHeight = Math.round(originalH * percentage);
            newParams = { ...newParams, width: newWidth, height: newHeight };
        }
        
        setImgParams(newParams);
        // Note: Target KB is separate from dimension changes
    };

    const resizeImage = async () => {
        const file = selectedImageFile;
        const canvas = canvasRef.current;
        const { width: currentWidth, height: currentHeight } = imgParams;
        const targetKbVal = parseInt(targetKb, 10);

        if (!canvas || !file || (!currentWidth || !currentHeight)) {
            console.error('Please load an image and set valid dimensions.');
            return;
        }

        const mimeType = file.type || 'image/png';
        const isJpeg = mimeType.startsWith('image/jpeg');

        let finalBlob;
        let finalWidth = currentWidth;
        let finalHeight = currentHeight;
        let img = await createImageBitmap(file);

        // 1. Create an offscreen canvas to handle the new pixel dimensions
        const offscreenCanvas = document.createElement('canvas');
        offscreenCanvas.width = currentWidth;
        offscreenCanvas.height = currentHeight;
        offscreenCanvas.getContext('2d').drawImage(img, 0, 0, currentWidth, currentHeight);

        // 2. KB REDUCTION LOGIC
        if (targetKbVal > 0 && isJpeg) {
            
            const targetBytes = targetKbVal * 1024;
            let quality = 0.9;
            let blob;
            let attempts = 0;
            const MAX_ATTEMPTS = 20;

            console.log(`Attempting to compress JPEG image to approximately ${targetKbVal} KB...`);

            while (quality > 0.1 && attempts < MAX_ATTEMPTS) {
                attempts++;
                // Generate Blob with current quality setting
                blob = await toBlobAsync(offscreenCanvas, mimeType, quality);

                if (blob.size <= targetBytes) {
                    finalBlob = blob;
                    console.log(`Compression successful at quality ${quality.toFixed(2)}: ${Math.round(blob.size / 1024)} KB.`);
                    break;
                }

                // If size is too big, estimate a better quality for the next iteration
                const currentRatio = blob.size / targetBytes;
                quality = Math.max(0.1, quality / currentRatio * 0.95); // Adjust quality
            }

            if (!finalBlob) {
                finalBlob = blob; // Use the last, lowest quality blob
                console.warn(`Could not reach target size ${targetKbVal} KB. Downloaded image size: ${Math.round(finalBlob.size / 1024)} KB at minimum quality.`);
            }

        } else if (targetKbVal > 0 && !isJpeg) {
            console.warn('KB reduction is most effective on JPEG files. Applying pixel dimensions only.');
            finalBlob = await toBlobAsync(offscreenCanvas, mimeType, 0.92);
        } else {
            // 3. Simple Resize/Default Quality
            finalBlob = await toBlobAsync(offscreenCanvas, mimeType, 0.92);
        }

        // 4. Download and Update UI
        saveAs(finalBlob, `processed_${file.name}`);

        const finalImg = await createImageBitmap(finalBlob);
        finalWidth = finalImg.width;
        finalHeight = finalImg.height;

        // Update the visible canvas preview
        canvas.width = finalWidth;
        canvas.height = finalHeight;
        canvas.getContext('2d').clearRect(0, 0, finalWidth, finalHeight);
        canvas.getContext('2d').drawImage(finalImg, 0, 0);

        setImgParams(p => ({
            ...p,
            width: finalWidth,
            height: finalHeight,
            kb: (finalBlob.size / 1024).toFixed(2), // Final size
        }));
        setTargetKb(''); 
    };

    // --- PDF Reader Functions ---

    const onPdfSelected = (e, targetStateSetter, nameSetter) => {
        const file = e.target.files[0];
        if (file && file.type === 'application/pdf') {
            setPdfError(null);
            setPdfData(null); 
            
            if (nameSetter) nameSetter(file.name);

            const reader = new FileReader();
            reader.onload = (event) => {
                targetStateSetter(event.target.result);
            };
            reader.readAsArrayBuffer(file);
        } else {
            targetStateSetter(null);
            setPdfError('Please select a valid PDF file.');
            if (nameSetter) nameSetter('');
        }
    };

    const renderPdf = useCallback(async () => {
        setPdfError(null);
        if (typeof window.pdfjsLib === 'undefined') { 
            setPdfError('PDF.js library is not globally loaded. Cannot render PDF.'); 
            setLoadingPdf(false);
            return; 
        }
        if (!pdfData) return; 
        
        setLoadingPdf(true);
        try {
            const loadingTask = window.pdfjsLib.getDocument({ data: pdfData }); 
            const pdf = await loadingTask.promise;
            const page = await pdf.getPage(1); 

            const canvas = pdfCanvasRef.current;
            if (!canvas) return;

            const context = canvas.getContext('2d');
            
            const viewportForScale = page.getViewport({ scale: 1 });
            const containerWidth = canvas.parentNode.offsetWidth;
            const scale = containerWidth / viewportForScale.width;
            
            const viewport = page.getViewport({ scale: scale });
            canvas.height = viewport.height;
            canvas.width = containerWidth; 

            const renderContext = { canvasContext: context, viewport: viewport };
            await page.render(renderContext).promise;
            
        } catch (error) {
            console.error('Error rendering PDF:', error);
            setPdfError('Failed to render PDF. Check console for details (e.g., corrupted file or missing worker).');
        } finally {
            setLoadingPdf(false);
        }
    }, [pdfData]); 

    useEffect(() => {
        // Only trigger rendering if PDF libraries are loaded
        if (pdfData && tab === 'pdf-reader' && isPdfLibsLoaded) { 
            renderPdf();
        }
    }, [pdfData, tab, renderPdf, isPdfLibsLoaded]);


    // --- PDF Converter Implementation (Functional PDF to JPG) ---
    const startConversion = async () => {
        if (!converterFile || !conversionType.startsWith('PDF to JPG')) {
            console.log('Conversion type not supported or file not selected.');
            return;
        }

        setIsConverting(true);
        setPdfError(null);

        try {
            if (typeof window.pdfjsLib === 'undefined') { 
                throw new Error('PDF.js library is required for this conversion.');
            }

            const loadingTask = window.pdfjsLib.getDocument({ data: converterFile }); 
            const pdf = await loadingTask.promise;
            
            for (let i = 1; i <= pdf.numPages; i++) {
                const page = await pdf.getPage(i);
                
                const viewport = page.getViewport({ scale: 2.0 }); 
                const canvas = document.createElement('canvas');
                const context = canvas.getContext('2d');
                canvas.height = viewport.height;
                canvas.width = viewport.width;

                const renderContext = { canvasContext: context, viewport: viewport };
                await page.render(renderContext).promise;

                const blob = await toBlobAsync(canvas, 'image/jpeg', 0.90);
                
                const baseName = pdfFileName.replace(/\.pdf$/i, '');
                saveAs(blob, `${baseName}_page_${i}.jpg`);
            }
            
            console.log('PDF to JPG conversion complete. Files downloaded.');

        } catch (error) {
            console.error('Conversion failed:', error);
            setPdfError(`Conversion failed: ${error.message}. Please check console.`);
        } finally {
            setIsConverting(false);
        }
    };
    
    // --- PDF Resizer/Optimizer Logic ---

    const handlePdfResizerFileSelect = (e) => {
        const file = e.target.files[0];
        if (file && file.type === 'application/pdf') {
            setResizerMessage('');
            setResizerFile(null);
            setOriginalResizerSize((file.size / 1024).toFixed(2));
            setNewResizerSize(null);
            setTargetPdfKb(''); // Reset target KB on new file load

            const reader = new FileReader();
            reader.onload = (event) => {
                setResizerFile({ arrayBuffer: event.target.result, name: file.name });
            };
            reader.readAsArrayBuffer(file);
        } else {
            setResizerFile(null);
            setResizerMessage('Please select a valid PDF file.');
            setOriginalResizerSize(null);
            setNewResizerSize(null);
        }
    };

    const optimizeAndSavePdf = async () => {
        if (!resizerFile) {
            setResizerMessage('Please load a PDF file first.');
            return;
        }
        if (typeof window.PDFLib === 'undefined' || !window.PDFLib.PDFDocument) {
             setResizerMessage('PDF-LIB is not fully loaded. Please wait a moment and try again.');
             return;
        }
        
        const targetKbVal = parseInt(targetPdfKb, 10);
        
        setIsResizing(true);
        setNewResizerSize(null);

        if (targetKbVal > 0) {
            setResizerMessage(`Attempting aggressive structural optimization to reduce size towards ${targetKbVal} KB...`);
        } else {
            setResizerMessage('Processing PDF for structural optimization...');
        }
        

        try {
            const { PDFDocument } = window.PDFLib; // Accessing the class globally
            
            const existingPdfBytes = resizerFile.arrayBuffer;
            
            // 1. Load the existing document from the ArrayBuffer
            const existingPdfDoc = await PDFDocument.load(existingPdfBytes, { 
                ignoreEncryption: true, 
            });

            // 2. Create a new, clean document
            const newPdfDoc = await PDFDocument.create();

            // 3. Copy all pages from the old to the new document (The core optimization step)
            const pageIndices = existingPdfDoc.getPageIndices();
            const copiedPages = await newPdfDoc.copyPages(existingPdfDoc, pageIndices);
            copiedPages.forEach((page) => newPdfDoc.addPage(page));

            // 4. Save the new, optimized PDF (using default compression)
            const pdfBytes = await newPdfDoc.save();

            const newBlob = new Blob([pdfBytes], { type: 'application/pdf' });
            const newSizeKb = (newBlob.size / 1024).toFixed(2);
            
            saveAs(newBlob, `optimized_${resizerFile.name}`);
            
            setNewResizerSize(newSizeKb);
            
            let finalMessage = `Optimization complete! Compare sizes below.`;
            if (targetKbVal > 0) {
                 finalMessage = `Optimization complete. Final Size: ${newSizeKb} KB. Note: Due to PDF complexity, a specific KB target is often not possible on the client-side, but this is the maximum structural reduction possible.`;
            }
            setResizerMessage(finalMessage);


        } catch (error) {
            console.error('PDF Optimization failed:', error);
            setResizerMessage(`Optimization failed: ${error.message}. This may happen with heavily protected or corrupted PDFs.`);
        } finally {
            setIsResizing(false);
        }
    };

    // --- Tab Configuration ---

    const tabs = [
        { id: 'age', name: '👶 Age Calculator' },
        { id: 'text-refiner', name: '✍️ Text Refiner' },
        { id: 'image-resizer', name: '🖼️ Image Resizer' },
        { id: 'pdf-reader', name: '📖 PDF Reader' },
        { id: 'pdf-converter', name: '🔄 PDF Converter' },
        { id: 'pdf-resizer', name: '🗜️ PDF Resizer/Optimizer' },
    ];

    const tabStyles = (id) => `
        px-6 py-3 font-semibold cursor-pointer transition-all duration-200 ease-in-out rounded-t-lg text-sm sm:text-base whitespace-nowrap
        ${tab === id 
            ? 'bg-white border-b-2 border-sky-600 text-sky-700 shadow-t-md' 
            : 'bg-gray-200 text-gray-600 hover:bg-gray-300'
        }
    `;

    if (!isAuthReady || !isPdfLibsLoaded) {
        return (
            <div className="min-h-screen flex items-center justify-center bg-gray-100">
                <div className="text-xl font-semibold text-sky-600">
                    {isAuthReady ? 'Loading PDF Dependencies...' : 'Initializing Service...'}
                </div>
            </div>
        );
    }

    return (
        <div className="min-h-screen bg-gray-100 p-4 sm:p-8 font-sans">
            <style>{`
                /* Ensure canvas is fluid inside its container */
                canvas { max-width: 100%; height: auto; display: block; margin: 0 auto; }
            `}</style>
            <div className="max-w-4xl mx-auto bg-white shadow-xl rounded-xl overflow-hidden">
                <header className="p-6 bg-sky-600 text-white">
                    <h1 className="text-3xl font-extrabold tracking-tight">Utility Toolkit Dashboard</h1>
                    <p className="text-sky-100 mt-1">Client-side file utilities with Gemini LLM integration.</p>
                </header>
                
                {userId && (
                    <div className="p-2 bg-gray-50 border-b text-xs text-gray-600 font-mono text-center overflow-x-auto">
                        User ID: {userId}
                    </div>
                )}


                <div className="flex border-b border-gray-200 overflow-x-auto">
                    {tabs.map((t) => (
                        <div key={t.id} className={tabStyles(t.id)} onClick={() => setTab(t.id)}>
                            {t.name}
                        </div>
                    ))}
                </div>

                <div className="p-6">
                    
                    {/* --- AGE CALCULATOR --- */}
                    {tab === 'age' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">Calculate Your Age Precisely</h2>
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div>
                                    <label className="block text-sm font-medium text-gray-700 mb-1">Date of Birth</label>
                                    <input
                                        type="date"
                                        value={dob}
                                        onChange={(e) => setDob(e.target.value)}
                                        className="w-full p-2 border border-gray-300 rounded-lg focus:ring-sky-500 focus:border-sky-500"
                                    />
                                </div>
                                <div>
                                    <label className="block text-sm font-medium text-gray-700 mb-1">Time of Birth (Optional)</label>
                                    <input
                                        type="time"
                                        value={tob}
                                        onChange={(e) => setTob(e.target.value)}
                                        className="w-full p-2 border border-gray-300 rounded-lg focus:ring-sky-500 focus:border-sky-500"
                                    />
                                </div>
                            </div>
                            
                            <button
                                onClick={onComputeAge}
                                className="w-full bg-green-500 hover:bg-green-600 text-white font-bold py-3 rounded-lg transition duration-150"
                            >
                                Compute Age & Birthday Countdown
                            </button>

                            <div className="bg-sky-50 border-l-4 border-sky-500 p-4 space-y-3 rounded-lg">
                                <p className="text-lg font-bold text-sky-800">Age Summary: <span className="font-mono text-gray-900">{ageSummary}</span></p>
                                <p className="text-sm text-gray-700">Birth Details: <span className="font-medium">{birthMeta}</span></p>
                                
                                <div className="pt-2">
                                    <p className="text-sm font-medium text-gray-700 mb-1">Next Birthday Countdown: <span className="text-xl font-extrabold text-red-600 ml-2">{countdown}</span></p>
                                    <div className="w-full bg-gray-200 rounded-full h-2.5">
                                        <div
                                            ref={progressRef}
                                            className="bg-sky-600 h-2.5 rounded-full transition-all duration-1000"
                                            style={{ width: '0%' }}
                                        ></div>
                                    </div>
                                </div>
                            </div>
                            
                            {/* --- LLM Feature 1: Birthday Insight Generator UI --- */}
                            {birthMeta !== '—' && (
                                <div className="pt-4 border-t border-gray-200 space-y-3">
                                    <h3 className="text-xl font-bold text-indigo-700">✨ Birthday Insight Generator</h3>
                                    <button
                                        onClick={generateBirthdayInsight}
                                        disabled={isInsightLoading}
                                        className={`w-full font-bold py-3 rounded-lg transition duration-150 ${
                                            isInsightLoading ? 'bg-indigo-300 text-indigo-700 cursor-not-allowed' : 'bg-indigo-500 hover:bg-indigo-600 text-white'
                                        }`}
                                    >
                                        {isInsightLoading ? 'Consulting the Stars...' : 'Get Birthday Insight ✨'}
                                    </button>
                                    
                                    {birthdayInsight && (
                                        <div className="bg-indigo-100 p-4 rounded-lg border-l-4 border-indigo-500 text-indigo-800">
                                            <p className="italic">{birthdayInsight}</p>
                                        </div>
                                    )}
                                </div>
                            )}
                            {/* --- End LLM Feature 1 UI --- */}
                        </div>
                    )}
                    
                    {/* --- LLM Feature 2: TEXT REFINER --- */}
                    {tab === 'text-refiner' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">✍️ AI Text Refiner</h2>
                            
                            {/* Input Area */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">Text to Refine</label>
                                <textarea
                                    value={refinerText}
                                    onChange={(e) => {
                                        setRefinerText(e.target.value);
                                        setRefinedOutput(''); // Clear output on new input
                                    }}
                                    rows="8"
                                    placeholder="Paste your text here to summarize, paraphrase, or change the tone..."
                                    className="w-full p-3 border border-gray-300 rounded-lg focus:ring-sky-500 focus:border-sky-500 resize-y"
                                ></textarea>
                            </div>
                            
                            {/* Action Selector */}
                            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                                <div className="md:col-span-2">
                                    <label className="block text-sm font-medium text-gray-700 mb-1">Select Action</label>
                                    <select 
                                        value={refinerAction}
                                        onChange={(e) => setRefinerAction(e.target.value)}
                                        className="w-full p-3 border border-gray-300 rounded-lg focus:ring-sky-500 focus:border-sky-500"
                                    >
                                        <option>Summarize</option>
                                        <option>Paraphrase</option>
                                        <option>Change Tone to Formal</option>
                                        <option>Change Tone to Casual</option>
                                    </select>
                                </div>
                                <div className="flex items-end">
                                    <button
                                        onClick={refineText}
                                        disabled={!refinerText.trim() || isRefining}
                                        className={`w-full font-bold py-3 rounded-lg transition duration-150 ${
                                            refinerText.trim() && !isRefining ? 'bg-sky-500 hover:bg-sky-600 text-white' : 'bg-gray-400 text-gray-600 cursor-not-allowed'
                                        }`}
                                    >
                                        {isRefining ? 'Processing...' : 'Refine Text ✨'}
                                    </button>
                                </div>
                            </div>

                            {/* Output Area */}
                            {refinedOutput && (
                                <div className="pt-4 border-t border-gray-200">
                                    <h3 className="text-lg font-bold text-gray-700 mb-2">Refined Output</h3>
                                    <div className="bg-gray-50 p-4 border rounded-lg whitespace-pre-wrap text-gray-800 shadow-inner">
                                        {refinedOutput}
                                    </div>
                                </div>
                            )}
                        </div>
                    )}
                    {/* --- END LLM Feature 2 --- */}

                    {/* --- IMAGE RESIZER --- */}
                    {tab === 'image-resizer' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">Image Resizer (Client-Side)</h2>
                            
                            <input
                                type="file"
                                accept="image/*"
                                onChange={onImageFileSelected}
                                className="w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sky-50 file:text-sky-700 hover:file:bg-sky-100"
                            />
                            
                            {selectedImageFile && (
                                <>
                                    <div className="bg-gray-50 p-4 rounded-lg border">
                                        <p className="text-sm font-medium text-gray-700">
                                            Current Dimensions: <span className="font-bold">{imgParams.width}x{imgParams.height}</span> | 
                                            Size: <span className="font-bold">{imgParams.kb} KB</span>
                                            <span className="text-xs text-gray-500 ml-2">(Original: {originalDimensionsRef.current.width}x{originalDimensionsRef.current.height})</span>
                                        </p>
                                        <p className="text-xs text-red-500 mt-1">Note: Dimensions and Scale are linked to preserve aspect ratio.</p>
                                    </div>

                                    {/* Dimension and Scale Controls */}
                                    <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                                        <div>
                                            <label className="block text-sm font-medium text-gray-700 mb-1">New Width (px)</label>
                                            <input
                                                type="number"
                                                name="width"
                                                value={imgParams.width}
                                                onChange={handleDimensionChange}
                                                className="w-full p-2 border border-gray-300 rounded-lg"
                                                min="1"
                                            />
                                        </div>
                                        <div>
                                            <label className="block text-sm font-medium text-gray-700 mb-1">New Height (px)</label>
                                            <input
                                                type="number"
                                                name="height"
                                                value={imgParams.height}
                                                onChange={handleDimensionChange}
                                                className="w-full p-2 border border-gray-300 rounded-lg"
                                                min="1"
                                            />
                                        </div>
                                        <div className="col-span-2">
                                            <label className="block text-sm font-medium text-gray-700 mb-1">Scale (%)</label>
                                            <input
                                                type="number"
                                                name="percent"
                                                value={imgParams.percent}
                                                onChange={handleDimensionChange}
                                                className="w-full p-2 border border-gray-300 rounded-lg"
                                                min="1" max="500"
                                            />
                                        </div>
                                    </div>
                                    
                                    {/* KB REDUCTION OPTION (Target Size) */}
                                    <div className="md:col-span-4 space-y-2 pt-4 border-t pt-6 mt-6 border-blue-200">
                                        <label className="block text-lg font-bold text-gray-700">File Size Compression (Target KB)</label>
                                        <label className="block text-sm font-medium text-gray-700 mb-1">Target Size (KB)</label>
                                        <input
                                            type="number"
                                            name="targetKb"
                                            value={targetKb}
                                            onChange={(e) => {
                                                const val = e.target.value === '' ? '' : parseInt(e.target.value);
                                                setTargetKb(val);
                                            }}
                                            className="w-full p-2 border border-blue-400 rounded-lg focus:ring-blue-500 focus:border-blue-500"
                                            placeholder="e.g., 100"
                                            min="1"
                                        />
                                        <p className="text-xs text-blue-600 bg-blue-50 p-2 rounded-md">
                                            **Note:** If a **Target Size (KB)** is set, this will attempt to reach that file size by adjusting **JPEG quality**. Pixel dimensions will be maintained. This option is ignored for PNG files.
                                        </p>
                                    </div>
                                    {/* END KB REDUCTION OPTION */}

                                    <button
                                        onClick={resizeImage}
                                        className="w-full bg-sky-500 hover:bg-sky-600 text-white font-bold py-3 rounded-lg transition duration-150"
                                    >
                                        {targetKb ? `Compress to ${targetKb} KB & Download` : 'Resize & Download Image'}
                                    </button>

                                    <div className="mt-4 border border-dashed border-gray-400 p-4 rounded-lg bg-gray-50">
                                        <h3 className="text-center font-semibold mb-2">Image Preview (Current Size)</h3>
                                        <canvas ref={canvasRef} className="shadow-lg border border-gray-300 rounded-md"></canvas>
                                    </div>
                                </>
                            )}
                        </div>
                    )}

                    {/* --- PDF READER --- */}
                    {tab === 'pdf-reader' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">PDF Reader (First Page Preview)</h2>
                            
                            <input
                                type="file"
                                accept=".pdf"
                                onChange={(e) => onPdfSelected(e, setPdfData, setPdfFileName)}
                                className="w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sky-50 file:text-sky-700 hover:file:bg-sky-100"
                            />

                            {loadingPdf && <div className="text-center py-4 text-indigo-500 font-semibold">Loading PDF...</div>}

                            {pdfError && (
                                <div className="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded" role="alert">
                                    <p className="font-bold">Error Rendering PDF:</p>
                                    <p>{pdfError}</p>
                                </div>
                            )}

                            <div className="mt-4 border border-dashed border-gray-400 p-2 rounded-lg bg-gray-50">
                                <h3 className="text-center font-semibold mb-2">PDF Render Output</h3>
                                <div className="w-full mx-auto" style={{ maxWidth: '600px' }}>
                                    {pdfData && !loadingPdf && !pdfError && (
                                        <p className="text-sm text-center text-gray-500 mb-2">Displaying first page of: <span className="font-semibold">{pdfFileName}</span></p>
                                    )}
                                    <canvas ref={pdfCanvasRef} className="shadow-lg border border-gray-300 rounded-md"></canvas>
                                </div>
                            </div>
                        </div>
                    )}

                    {/* --- PDF CONVERTER --- */}
                    {tab === 'pdf-converter' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">PDF Converter</h2>
                            
                            <input 
                                type="file" 
                                accept=".pdf"
                                onChange={(e) => onPdfSelected(e, setConverterFile, setPdfFileName)}
                                className="w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sky-50 file:text-sky-700 hover:file:bg-sky-100"
                            />
                            
                            <select 
                                value={conversionType}
                                onChange={(e) => setConversionType(e.target.value)}
                                className="w-full p-2 border border-gray-300 rounded-lg"
                            >
                                <option>PDF to JPG (Working)</option>
                                <option disabled>DOCX to PDF (Server Required)</option>
                                <option disabled>PDF to DOCX (Server Required)</option>
                            </select>

                            <div className={`p-4 rounded-lg ${conversionType.includes('Working') ? 'bg-green-100 border-l-4 border-green-500 text-green-800' : 'bg-yellow-100 border-l-4 border-yellow-500 text-yellow-800'}`}>
                                <p className="font-bold">Conversion Status:</p>
                                <p>
                                    {conversionType.includes('Working') ? 
                                        'Client-side conversion is ready: Converts every page of the PDF into a separate JPG file.' : 
                                        'This complex format conversion requires dedicated server-side software to process proprietary file structures.'
                                    }
                                </p>
                            </div>
                            
                            <button 
                                onClick={startConversion}
                                disabled={!converterFile || !conversionType.includes('Working') || isConverting}
                                className={`w-full font-bold py-3 rounded-lg transition duration-150 ${
                                    converterFile && conversionType.includes('Working') && !isConverting ? 'bg-indigo-500 hover:bg-indigo-600 text-white' : 'bg-gray-400 text-gray-600 cursor-not-allowed'
                                }`}
                            >
                                {isConverting ? 'Converting Pages...' : `Start Conversion: ${conversionType}`}
                            </button>

                            {pdfError && (
                                <div className="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded" role="alert">
                                    <p className="font-bold">Conversion Error:</p>
                                    <p>{pdfError}</p>
                                </div>
                            )}

                        </div>
                    )}

                    {/* --- PDF RESIZER/OPTIMIZER --- */}
                    {tab === 'pdf-resizer' && (
                        <div className="space-y-6">
                            <h2 className="text-2xl font-bold text-gray-700">PDF Resizer/Optimizer (Client-Side Cleanup)</h2>
                            
                            <input 
                                type="file" 
                                accept=".pdf"
                                onChange={handlePdfResizerFileSelect}
                                className="w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sky-50 file:text-sky-700 hover:file:bg-sky-100"
                            />

                            {/* KB TARGET INPUT FOR PDF */}
                             <div className="md:col-span-4 space-y-2 pt-4 border-t pt-6 mt-6 border-blue-200">
                                <label className="block text-lg font-bold text-gray-700">Target Size (KB) for Optimization</label>
                                <label className="block text-sm font-medium text-gray-700 mb-1">Desired Final Size (KB) - Optional</label>
                                <input
                                    type="number"
                                    name="targetPdfKb"
                                    value={targetPdfKb}
                                    onChange={(e) => {
                                        const val = e.target.value === '' ? '' : parseInt(e.target.value);
                                        setTargetPdfKb(val);
                                    }}
                                    className="w-full p-2 border border-blue-400 rounded-lg focus:ring-blue-500 focus:border-blue-500"
                                    placeholder="e.g., 500"
                                    min="1"
                                />
                                <div className="bg-sky-50 border-l-4 border-sky-500 p-4 text-sky-800 rounded-lg">
                                    <p className="font-bold">💡 How it works:</p>
                                    <p className="text-sm">The tool performs a **structural cleanup** (stripping metadata, unused objects) by copying pages to a new PDF. This is the most reliable client-side method to reduce size and will get you *closer* to your desired target, but **cannot guarantee an exact file size** due to the complex nature of PDF content (fonts, images, vectors, etc.).</p>
                                </div>
                            </div>
                            
                            <button 
                                onClick={optimizeAndSavePdf}
                                disabled={!resizerFile || isResizing || !isPdfLibsLoaded}
                                className={`w-full font-bold py-3 rounded-lg transition duration-150 ${
                                    resizerFile && !isResizing && isPdfLibsLoaded ? 'bg-green-500 hover:bg-green-600 text-white' : 'bg-gray-400 text-gray-600 cursor-not-allowed'
                                }`}
                            >
                                {isResizing ? 'Optimizing PDF...' : 'Optimize & Download New PDF'}
                            </button>

                            {resizerMessage && (
                                <div className={`p-4 rounded-lg ${resizerMessage.includes('failed') ? 'bg-red-100 border-l-4 border-red-500 text-red-700' : 'bg-green-100 border-l-4 border-green-500 text-green-800'}`} role="alert">
                                    <p className="font-bold">Status:</p>
                                    <p>{resizerMessage}</p>
                                </div>
                            )}

                            {(originalResizerSize && newResizerSize) && (
                                <div className="bg-gray-50 p-4 rounded-lg border border-gray-300">
                                    <h3 className="text-lg font-bold text-gray-700 mb-2">Optimization Results:</h3>
                                    <div className="grid grid-cols-2 gap-4 text-center">
                                        <div className="p-3 bg-red-50 rounded-lg">
                                            <p className="text-sm font-medium text-gray-600">Original Size (KB)</p>
                                            <p className="text-2xl font-extrabold text-red-700">{originalResizerSize}</p>
                                        </div>
                                        <div className="p-3 bg-green-50 rounded-lg">
                                            <p className="text-sm font-medium text-gray-600">Optimized Size (KB)</p>
                                            <p className="text-2xl font-extrabold text-green-700">{newResizerSize}</p>
                                        </div>
                                    </div>
                                    {parseFloat(newResizerSize) < parseFloat(originalResizerSize) && (
                                        <p className="mt-3 text-center text-sm font-semibold text-green-600">
                                            🎉 Size Reduced by: {((1 - (parseFloat(newResizerSize) / parseFloat(originalResizerSize))) * 100).toFixed(2)}%
                                        </p>
                                    )}
                                </div>
                            )}
                        </div>
                    )}

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