• Import page component for the Kenmei to AniList sync tool.

    Handles file upload, import process, error handling, and displays import summary and data table for the user.

    Returns Element

    export function ImportPage() {
    const navigate = useNavigate();
    const [importData, setImportData] = useState<KenmeiData | null>(null);
    const [error, setError] = useState<AppError | null>(null);
    const [isLoading, setIsLoading] = useState(false);
    const [importSuccess, setImportSuccess] = useState(false);
    const [previousMatchCount, setPreviousMatchCount] = useState(0);
    const [progress, setProgress] = useState(0);

    const handleFileLoaded = (data: KenmeiData) => {
    setImportData(data);
    setError(null);
    setImportSuccess(false);
    toast.success("File loaded successfully");
    };

    const handleError = (error: AppError) => {
    setError(error);
    setImportData(null);
    setImportSuccess(false);
    toast.error(error.message);
    };

    const handleImport = async () => {
    if (!importData) {
    return;
    }

    setIsLoading(true);

    // Start progress animation
    setProgress(10);
    const progressInterval = setInterval(() => {
    setProgress((prev) => {
    if (prev >= 90) {
    clearInterval(progressInterval);
    return 90;
    }
    return prev + 10;
    });
    }, 200);

    try {
    // Normalize the imported manga with proper ID assignment
    const normalizedManga = normalizeMangaItems(importData.manga);

    // Get previously imported manga to compare against
    const previousManga = getPreviousMangaData();

    // Merge manga data and get results
    const { mergedManga, results } = mergeMangaData(
    previousManga,
    normalizedManga,
    );

    console.log(
    `Import results: Previous: ${previousManga.length}, New file: ${normalizedManga.length}, Final merged: ${mergedManga.length}`,
    );
    console.log(
    `Changes: ${results.newMangaCount} new manga, ${results.updatedMangaCount} updated manga`,
    );

    // Ensure all manga have proper IDs and required fields
    const validMergedManga = validateMangaData(mergedManga);
    saveKenmeiData({ manga: validMergedManga });

    // Update existing match results with new data if any exist
    updateMatchResults(validMergedManga);

    // Clear pending manga storage after import to force recalculation
    clearPendingMangaStorage();

    // Show success state briefly before redirecting
    setImportSuccess(true);
    setProgress(100);

    // Redirect to the review page after a short delay
    setTimeout(() => {
    navigate({ to: "/review" });
    }, 1500);
    } catch (err) {
    // Handle any errors that might occur during storage
    console.error("Storage error:", err);
    handleError(
    createError(
    ErrorType.STORAGE,
    "Failed to save import data. Please try again.",
    ),
    );
    } finally {
    clearInterval(progressInterval);
    setIsLoading(false);
    }
    };

    const dismissError = () => {
    setError(null);
    };

    const resetForm = () => {
    setImportData(null);
    setError(null);
    setImportSuccess(false);
    };

    useEffect(() => {
    // Check if we have previous match results
    const savedResults = getSavedMatchResults();
    if (savedResults && Array.isArray(savedResults)) {
    const reviewedCount = savedResults.filter(
    (m) =>
    m.status === "matched" ||
    m.status === "manual" ||
    m.status === "skipped",
    ).length;

    setPreviousMatchCount(reviewedCount);
    }
    }, []);

    return (
    <motion.div
    className="container mx-auto px-4 py-8 md:px-6"
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
    transition={{ duration: 0.4 }}
    >
    <motion.div
    className="mb-8 space-y-2"
    initial={{ opacity: 0, y: -20 }}
    animate={{ opacity: 1, y: 0 }}
    transition={{ delay: 0.1, duration: 0.5 }}
    >
    <h1 className="bg-gradient-to-r from-blue-600 to-indigo-600 bg-clip-text text-4xl font-bold text-transparent">
    Import Your Manga
    </h1>
    <p className="text-muted-foreground max-w-2xl">
    Transfer your manga collection from Kenmei to AniList with a single
    file import.
    </p>
    </motion.div>

    {error && (
    <motion.div
    className="mb-6"
    initial={{ opacity: 0, scale: 0.95 }}
    animate={{ opacity: 1, scale: 1 }}
    transition={{ duration: 0.3 }}
    >
    <ErrorMessage
    message={error.message}
    type={error.type}
    dismiss={dismissError}
    retry={importData ? handleImport : undefined}
    />
    </motion.div>
    )}

    {(() => {
    if (importSuccess && importData) {
    return (
    <ImportSuccessContent importData={importData} progress={progress} />
    );
    }

    if (!importData) {
    return (
    <FileUploadContent
    onFileLoaded={handleFileLoaded}
    onError={handleError}
    />
    );
    }

    const statusCounts = getStatusCounts(importData.manga);
    return (
    <FileReadyContent
    importData={importData}
    statusCounts={statusCounts}
    previousMatchCount={previousMatchCount}
    isLoading={isLoading}
    onImport={handleImport}
    onReset={resetForm}
    />
    );
    })()}
    </motion.div>
    );
    }