/**
 * AtlasManagement
 * Handles atlas content browsing plus import and export of user-contributed
 * images and drawings attached to atlas trait options.
 */
import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
    getFormSchema,
    addImageToAtlas,
    importUserUpdates
} from '../../api/generated/index';
import {
    ImagePlus, Package, PackageOpen,
    Loader2, ChevronDown, ChevronUp, Check, X, Trash2, ShieldCheck, Pencil
} from 'lucide-react';
import { Button } from '../ui/button';
import { useLanguage } from '../../context/LanguageContext';
import { useMessageDialog } from '../../hooks/useMessageDialog';
import { buildApiUrl, toAbsoluteApiUrl } from '../../utils/api';

export default function AtlasManagement({ atlases, onRefresh }) {
    const { t, lang } = useLanguage();
    const { alert: showAlert, confirm } = useMessageDialog();
    const [selectedAtlasForEdit, setSelectedAtlasForEdit] = useState(null);
    const [schema, setSchema] = useState([]);
    const [isExporting, setIsExporting] = useState(false);
    const [isImporting, setIsImporting] = useState(false);
    const [expandedTrait, setExpandedTrait] = useState(null);
    const [uploadingFor, setUploadingFor] = useState(null);
    const [uploadIsDrawing, setUploadIsDrawing] = useState(false);

    const fileInputRef = useRef(null);
    const importInputRef = useRef(null);

    const fetchSchema = useCallback(async () => {
        if (!selectedAtlasForEdit) {
            setSchema([]);
            return;
        }

        try {
            const res = await getFormSchema({ query: { atlasId: selectedAtlasForEdit.id } });
            setSchema(res.data || []);
        } catch (err) {
            console.error('Failed to load atlas schema:', err);
        }
    }, [selectedAtlasForEdit]);

    useEffect(() => {
        fetchSchema();
    }, [fetchSchema]);

    const getFullUrl = (path) => {
        return toAbsoluteApiUrl(path) || "";
    };

    const handleExport = async () => {
        setIsExporting(true);
        try {
            const response = await fetch(buildApiUrl('/api/updates/export'));

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error || 'Export failed');
            }

            const blob = await response.blob();
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `atlas_updates_${new Date().toISOString().slice(0, 10)}.zip`;
            document.body.appendChild(a);
            a.click();
            a.remove();
        } catch (err) {
            await showAlert({
                title: t('dialogErrorTitle'),
                message: t('exportFailed'),
                details: err.message,
                tone: 'error',
            });
        } finally {
            setIsExporting(false);
        }
    }

    const handleImport = async (e) => {
        const file = e.target.files[0];
        if (!file) return;
        setIsImporting(true);
        try {
            const response = await importUserUpdates({ body: { updateZip: file } });
            const payload = response?.data || response || {};
            await showAlert({
                title: t('dialogNoticeTitle'),
                message: t('importSuccess'),
                detailsItems: [
                    { label: t('importImagesAddedLabel'), value: payload.addedCount ?? 0 },
                    ...(payload.duplicateCount > 0 ? [{ label: t('importImagesDuplicateLabel'), value: payload.duplicateCount }] : []),
                ],
                tone: 'info',
            });
            if (onRefresh) onRefresh();
            if (selectedAtlasForEdit) fetchSchema();
        } catch (err) {
            console.error('Atlas update import failed:', err);
            await showAlert({
                title: t('dialogErrorTitle'),
                message: t('importError'),
                tone: 'error',
            });
        } finally {
            setIsImporting(false);
            e.target.value = "";
        }
    };

    const triggerUpload = (traitId, optionLabel, isDrawing) => {
        setUploadingFor({ traitId, optionLabel });
        setUploadIsDrawing(isDrawing);
        fileInputRef.current.click();
    };

    const handleAddImage = async (e) => {
        const file = e.target.files[0];
        if (!file || !uploadingFor) return;

        try {
            const response = await addImageToAtlas({
                body: {
                    traitId: uploadingFor.traitId,
                    optionLabelCs: uploadingFor.optionLabel,
                    isDrawing: uploadIsDrawing,
                    image: file
                }
            });
            const payload = response?.data || response || {};
            if (payload.skippedDuplicate) {
                await showAlert({
                    title: t('dialogNoticeTitle'),
                    message: t('duplicateAtlasImageSkipped'),
                    tone: 'info',
                });
            }
            fetchSchema();
        } catch (err) {
            console.error('Atlas image upload failed:', err);
            await showAlert({
                title: t('dialogErrorTitle'),
                message: t('uploadError'),
                tone: 'error',
            });
        } finally {
            setUploadingFor(null);
            e.target.value = "";
        }
    };

    const handleDeleteUserImage = async (imageId) => {
        if (!imageId || imageId === 'undefined') {
            console.error('Missing image ID.');
            return;
        }

        const shouldDeleteImage = await confirm({
            title: t('dialogConfirmTitle'),
            message: t('deleteConfirmGeneral'),
            tone: 'danger',
            confirmLabel: t('dialogDeleteAction'),
        });
        if (!shouldDeleteImage) return;

        try {
            console.log(`Deleting user image: ${imageId}`);

            const response = await fetch(buildApiUrl(`/api/atlases/user-image/${imageId}`), {
                method: 'DELETE',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                }
            });

            if (response.ok) {
                fetchSchema();
            } else {
                const errorData = await response.json().catch(() => ({}));
                await showAlert({
                    title: t('dialogErrorTitle'),
                    message: t('errorDeleteFailed'),
                    details: errorData.error || response.statusText,
                    tone: 'error',
                });
            }
        } catch (err) {
            console.error('Network error while deleting image:', err);
            await showAlert({
                title: t('dialogErrorTitle'),
                message: t('errorDeleteFailed'),
                tone: 'error',
            });
        }
    };

    const renderOptionGallery = (opt, trait) => {
        const total = (opt.factoryImages?.length || 0) +
            (opt.factoryDrawings?.length || 0) +
            (opt.userImages?.length || 0) +
            (opt.userDrawings?.length || 0);

        return (
            <div key={opt.id || opt.label_cs} className="bg-white p-5 rounded-3xl shadow-sm border border-slate-100/50">
                <div className="flex items-center justify-between mb-4">
                    <div>
                        <p className="text-sm font-bold text-slate-700">
                            {lang === 'cs' ? opt.label_cs : opt.label_en}
                        </p>
                        <p className="text-[10px] text-slate-400 font-bold uppercase">{total} {t('photos')}</p>
                    </div>
                    <div className="flex items-center gap-2">
                        <Button
                            size="sm"
                            variant="ghost"
                            className="rounded-xl text-blue-600 hover:bg-blue-50 text-[11px] h-8"
                            onClick={() => triggerUpload(trait.id, opt.label_cs, false)}
                        >
                            <ImagePlus size={14} className="mr-1.5" /> {t('addPhoto')}
                        </Button>
                        <Button
                            size="sm"
                            variant="ghost"
                            className="rounded-xl text-amber-600 hover:bg-amber-50 text-[11px] h-8"
                            onClick={() => triggerUpload(trait.id, opt.label_cs, true)}
                        >
                            <Pencil size={14} className="mr-1.5" /> {t('addDrawing')}
                        </Button>
                    </div>
                </div>

                <div className="flex flex-wrap gap-3">
                    {opt.factoryDrawings?.map((url, idx) => (
                        <div key={`fd-${idx}`} className="relative w-20 h-20 rounded-2xl overflow-hidden border border-amber-100/50 bg-amber-50/30">
                            <img src={getFullUrl(url)} alt="" className="w-full h-full object-contain p-2 opacity-80" />
                            <div className="absolute top-1 left-1 bg-amber-100 text-amber-600 p-1 rounded-lg"><Pencil size={10} /></div>
                        </div>
                    ))}
                    {opt.userDrawings?.map((img) => (
                        <div key={`ud-${img.id}`} className="relative w-20 h-20 rounded-2xl overflow-hidden border border-amber-200 bg-white group">
                            <img src={getFullUrl(img.path)} alt="" className="w-full h-full object-contain p-2" />
                            <button onClick={() => handleDeleteUserImage(img.id)} className="absolute top-1 right-1 p-1 bg-rose-500 text-white rounded-lg opacity-0 group-hover:opacity-100 transition-all shadow-lg">
                                <X size={12} strokeWidth={3} />
                            </button>
                            <div className="absolute bottom-1 left-1 bg-amber-500 text-[8px] text-white px-1 rounded font-bold uppercase tracking-tighter">{t('newLabel')}</div>
                        </div>
                    ))}

                    {opt.factoryImages?.map((url, idx) => (
                        <div key={`fi-${idx}`} className="relative w-20 h-20 rounded-2xl overflow-hidden border border-slate-100 bg-slate-50">
                            <img src={getFullUrl(url)} alt="" className="w-full h-full object-cover grayscale opacity-60" />
                            <div className="absolute top-1 left-1 bg-white/80 p-1 rounded-lg"><ShieldCheck size={10} className="text-slate-400" /></div>
                        </div>
                    ))}
                    {opt.userImages?.map((img) => (
                        <div key={`ui-${img.id}`} className="relative w-20 h-20 rounded-2xl overflow-hidden border-2 border-blue-100 shadow-md group">
                            <img src={getFullUrl(img.path)} alt="" className="w-full h-full object-cover" />
                            <button onClick={() => handleDeleteUserImage(img.id)} className="absolute top-1 right-1 p-1 bg-rose-500 text-white rounded-lg opacity-0 group-hover:opacity-100 transition-all shadow-lg">
                                <Trash2 size={12} />
                            </button>
                        </div>
                    ))}
                </div>
            </div>
        );
    };

    return (
        <div className="p-8 max-w-6xl mx-auto space-y-10 animate-in fade-in duration-500 pb-24">
            <input type="file" ref={fileInputRef} className="hidden" accept="image/*" onChange={handleAddImage} />
            <input type="file" ref={importInputRef} className="hidden" accept=".zip" onChange={handleImport} />

            <header className="flex flex-col md:flex-row justify-between items-start md:items-end gap-6">
                <div className="space-y-1">
                    <h1 className="text-4xl font-black text-slate-900 tracking-tighter">{t('contentManagement')}</h1>
                    <p className="text-slate-500">{t('contentManagementSub')}</p>
                </div>
                <div className="flex gap-3">
                    <Button onClick={handleExport} disabled={isExporting} variant="outline" className="rounded-2xl border-blue-200 text-blue-600 bg-blue-50/50 hover:bg-blue-100 py-6">
                        {isExporting ? <Loader2 className="animate-spin mr-2" size={18} /> : <Package size={18} className="mr-2" />}
                        {t('exportMyChanges')}
                    </Button>
                    <Button onClick={() => importInputRef.current.click()} disabled={isImporting} className="bg-blue-600 hover:bg-blue-700 text-white rounded-2xl py-6 shadow-lg shadow-blue-200">
                        {isImporting ? <Loader2 className="animate-spin mr-2" size={18} /> : <PackageOpen size={18} className="mr-2" />}
                        {t('importChanges')}
                    </Button>
                </div>
            </header>

            <div className="grid grid-cols-1 lg:grid-cols-3 gap-10">
                <div className="lg:col-span-1 space-y-4">
                    <h2 className="font-bold text-slate-400 uppercase text-[10px] tracking-[0.2em] px-2">{t('availableAtlases')}</h2>
                    <div className="space-y-2">
                        {atlases.map(atlas => (
                            <div
                                key={atlas.id}
                                onClick={() => setSelectedAtlasForEdit(atlas)}
                                className={`p-5 rounded-[24px] border-2 cursor-pointer transition-all flex items-center justify-between group ${selectedAtlasForEdit?.id === atlas.id ? 'border-blue-500 bg-white shadow-xl shadow-blue-100 scale-[1.02]' : 'border-transparent bg-white hover:border-slate-200 shadow-sm'
                                    }`}
                            >
                                <span className={`font-bold ${selectedAtlasForEdit?.id === atlas.id ? 'text-blue-600' : 'text-slate-600'}`}>
                                    {lang === 'cs' ? atlas.nazev_cs : atlas.nazev_en}
                                </span>
                                {selectedAtlasForEdit?.id === atlas.id && <Check size={18} className="text-blue-500" />}
                            </div>
                        ))}
                    </div>
                </div>

                <div className="lg:col-span-2 bg-white rounded-[40px] border border-slate-100 p-2 shadow-sm min-h-[500px]">
                    {selectedAtlasForEdit ? (
                        <div className="p-6 space-y-8">
                            {schema.map(category => (
                                <div key={category.id} className="space-y-4">
                                    <div className="flex items-center gap-4 px-2">
                                        <div className="h-[1px] flex-1 bg-slate-100"></div>
                                        <h3 className="text-[10px] font-black text-slate-400 uppercase tracking-widest">
                                            {lang === 'cs' ? category.nazev_cs : category.nazev_en}
                                        </h3>
                                        <div className="h-[1px] flex-1 bg-slate-100"></div>
                                    </div>

                                    <div className="grid grid-cols-1 gap-3">
                                        {category.znaky.map(trait => (
                                            <div key={trait.id} className={`rounded-3xl transition-all border ${expandedTrait === trait.id ? 'border-blue-100 bg-blue-50/20' : 'border-slate-50 bg-slate-50/30'}`}>
                                                <button onClick={() => setExpandedTrait(expandedTrait === trait.id ? null : trait.id)} className="w-full flex items-center justify-between p-5">
                                                    <div className="text-left">
                                                        <p className="font-bold text-slate-800 leading-none mb-1">
                                                            {lang === 'cs' ? trait.label_cs : trait.label_en}
                                                        </p>
                                                    </div>
                                                    <div className={`w-8 h-8 rounded-full flex items-center justify-center transition-colors ${expandedTrait === trait.id ? 'bg-blue-100 text-blue-600' : 'bg-white text-slate-400'}`}>
                                                        {expandedTrait === trait.id ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
                                                    </div>
                                                </button>

                                                {expandedTrait === trait.id && (
                                                    <div className="px-5 pb-5 pt-2 space-y-4 animate-in slide-in-from-top-2 duration-300">
                                                        {trait.options.map(opt => renderOptionGallery(opt, trait))}
                                                    </div>
                                                )}
                                            </div>
                                        ))}
                                    </div>
                                </div>
                            ))}
                        </div>
                    ) : (
                        <div className="h-full flex flex-col items-center justify-center text-slate-300 py-32 space-y-4">
                            <Package size={64} className="opacity-10" />
                            <p className="text-sm font-medium">{t('selectAtlasToStart')}</p>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}