// Version: 2.02.00
// --- GLOBAL EDITOR COMPONENT  ---
const { useState, useEffect, useRef, useMemo } = React;

// Import helpers from window scope
const { urlToBase64, cleanNum, formatPrice, calcFinal, cleanNumberInput } = window;
// Import Icons from window scope
const { 
    Layout, Plus, Search, ExternalLink, ChevronUp, Copy, ArrowDown, ChevronDown, 
    Trash2, ImageIcon, Clipboard, Ruler, Disk, UploadIcon, Cloud, Loader, FileText, 
    Download 
} = window;

window.HeaderRow = ({ hasGlobalDiscount, debugClass, gridContainerClass }) => (
    <div className={`${gridContainerClass} border-b-2 border-[#2d3440] pb-2 mb-4 mt-2 px-2 header-row hidden md:grid break-inside-avoid`}>
        <div className={`text-[10px] font-bold text-gray-500 uppercase ${debugClass}`}>Фото</div>
        <div className={`text-[10px] font-bold text-gray-500 uppercase pl-2 ${debugClass}`}>Описание</div>
        <div className={`text-[10px] font-bold text-gray-500 uppercase text-center ${debugClass}`}>Ссылка</div>
        <div className={`text-[10px] font-bold text-gray-500 uppercase text-right ${debugClass}`}>Кол</div>
        <div className={`text-[10px] font-bold text-gray-500 uppercase text-right ${debugClass}`}>Цена</div>
        <div className={`text-[10px] font-bold text-gray-500 uppercase text-right ${debugClass}`}>Сумма</div>
        {hasGlobalDiscount && <div className={`text-[10px] font-bold text-blue-600 uppercase text-right print-text-black ${debugClass}`}>Итого</div>}
    </div>
);

window.Editor = ({ user, initialProject, useAquaPlaza, onBack }) => {
    // ... [Logic remains same as v5.147, just Version bump]
    const getAutoNumber = () => {
        const today = new Date();
        const dd = String(today.getDate()).padStart(2, '0');
        const mm = String(today.getMonth() + 1).padStart(2, '0');
        return `КП-${dd}/${mm}-`;
    };
    // ... [Rest of the code]
    
    // NOTE: Copy the FULL logic from previous version 5.147 here, 
    // I am ensuring the structure is modular. 
    // Since I cannot output 1000 lines every time, I assume you have the content.
    // If not, I can output the full file again.
    
    // For this response, I will output the FULL file to be safe.
    
    const defaults = { docInfo: { number: getAutoNumber(), date: new Date().toISOString().split('T')[0], recipient: '' }, items: [{ id: Date.now(), type: 'item', title: '', price: 0, quantity: 1, finalPrice: 0 }] };
    const initData = initialProject?.data || defaults;
    const [docInfo, setDocInfo] = useState(initData.docInfo);
    const [items, setItems] = useState(initData.items);
    const [currentProjectId, setCurrentProjectId] = useState(initialProject?.id || null);
    const [isPdf, setIsPdf] = useState(false);
    const [saving, setSaving] = useState(false);
    const [loadingItems, setLoadingItems] = useState({});
    const [fileColumns, setFileColumns] = useState([]);
    const [showMappingModal, setShowMappingModal] = useState(false);
    const [mapping, setMapping] = useState({ article: '', title: '', price: '', link: '' });
    const [globalDiscount, setGlobalDiscount] = useState(initData.globalDiscount || 0);
    const [showGlobalDiscountInput, setShowGlobalDiscountInput] = useState(initData.globalDiscount > 0);
    const [showDebugGrid, setShowDebugGrid] = useState(false);
    const [showPasteModal, setShowPasteModal] = useState(false);
    const [pasteText, setPasteText] = useState("");
    const [previewItems, setPreviewItems] = useState([]);
    const [statusMessage, setStatusMessage] = useState(null);

    const debugClass = showDebugGrid ? "border-r border-dashed border-red-400 bg-red-50/30" : "";
    const textareaRefs = useRef({});
    
    useEffect(() => { Object.values(textareaRefs.current).forEach(t => t && adjustHeight(t)); }, [items]);
    const adjustHeight = (el) => { if (!el) return; el.style.height = 'auto'; el.style.height = el.scrollHeight + 'px'; };
    const handleDateChange = (e) => { setDocInfo({ ...docInfo, date: e.target.value }); };
    const getFormattedDateForPrint = () => { if (!docInfo.date) return ''; const parts = docInfo.date.split('-'); if (parts.length === 3) return `${parts[2]}.${parts[1]}.${parts[0]}`; return docInfo.date; };

    const handleGlobalDiscountChange = (val) => { setGlobalDiscount(val); const numVal = parseFloat(val); setItems(prev => prev.map(item => { if (item.type === 'item') { const isDiscounted = numVal > 0; const final = calcFinal(item.price, item.quantity, isDiscounted, 'percent', val); return { ...item, isDiscounted, discountType: 'percent', discountValue: val, finalPrice: final }; } return item; })); };
    const toggleGlobalDiscount = () => { if (showGlobalDiscountInput) { setShowGlobalDiscountInput(false); handleGlobalDiscountChange(0); } else { setShowGlobalDiscountInput(true); } };

    const fetchProductByArticle = async (id, article) => {
        if (!article) return;
        setLoadingItems(prev => ({ ...prev, [id]: true }));
        try {
            let data = { found: false };
            if (useAquaPlaza) {
                const res = await fetch(`/api/proxy/search?article=${encodeURIComponent(article)}`);
                const apiData = await res.json();
                if (apiData.found) {
                    data = apiData;
                    if (data.link) { const sep = data.link.includes('?') ? '&' : '?'; data.link = `${data.link}${sep}utm_source=kp-gen`; }
                }
            }
            if (!data.found) {
                const res = await fetch(`/api/search?article=${encodeURIComponent(article)}`);
                const localData = await res.json();
                if (localData.found) data = localData;
            }
            if (data.found) {
                const imgUrl = data.image ? (data.image.startsWith('http') ? data.image : 'https://' + data.image) : null;
                const base64Img = imgUrl ? await urlToBase64(imgUrl) : null;
                setItems(prev => prev.map(item => { if (item.id === id) { const updated = { ...item, title: data.title, price: data.price, link: data.link || item.link, image: base64Img || imgUrl }; updated.finalPrice = calcFinal(parseFloat(updated.price) || 0, parseFloat(updated.quantity) || 0, updated.isDiscounted, updated.discountType, updated.discountValue); return updated; } return item; }));
            } else { alert('Товар не найден (ни в прайсе, ни на сайте)'); }
        } catch (error) { alert("Ошибка поиска"); } finally { setLoadingItems(prev => ({ ...prev, [id]: false })); }
    };

    const enrichItemWithImage = async (id, article) => {
        if (!article) return;
        try {
            const res = await fetch(`/api/proxy/search?article=${encodeURIComponent(article)}`);
            const data = await res.json();
            if (data.found) {
                let link = data.link;
                if (link) { const sep = link.includes('?') ? '&' : '?'; link = `${link}${sep}utm_source=kp-gen`; }
                const imgUrl = data.image ? (data.image.startsWith('http') ? data.image : 'https://' + data.image) : null;
                const base64Img = imgUrl ? await urlToBase64(imgUrl) : null;
                setItems(prev => prev.map(it => { if (it.id === id) { return { ...it, image: base64Img || imgUrl, link: link || it.link }; } return it; }));
            }
        } catch (e) { }
    };

    const smartParse = (rawHTML, rawText) => {
        const newItems = [];
        if (rawHTML) {
            const parser = new DOMParser();
            const doc = parser.parseFromString(rawHTML, 'text/html');
            const rows = doc.querySelectorAll('tr');
            let colMap = { art: -1, title: -1, qty: -1, price: -1, sum: -1, unit: -1 };
            let headerFound = false;
            rows.forEach((row, rIndex) => {
                const cells = Array.from(row.cells).map(c => c.textContent.trim());
                if (cells.length < 3) return;
                if (!headerFound) {
                    const txt = cells.join(' ').toLowerCase();
                    if (txt.includes('артикул') || txt.includes('код') || txt.includes('товар') || txt.includes('наименование')) {
                        let priceIndices = [], sumIndices = [];
                        cells.forEach((c, idx) => {
                            const t = c.toLowerCase();
                            if (t.includes('артикул') || t.includes('код')) colMap.art = idx;
                            else if (t.includes('товар') || t.includes('наименование') || t.includes('работы')) colMap.title = idx;
                            else if (t.includes('кол') && !t.includes('цена')) colMap.qty = idx;
                            else if (t.includes('ед')) colMap.unit = idx;
                            else if (t.includes('цена')) priceIndices.push(idx);
                            else if (t.includes('сумма') && !t.includes('без')) sumIndices.push(idx);
                        });
                        if (priceIndices.length > 0) colMap.price = priceIndices[0];
                        if (sumIndices.length > 0) colMap.sum = sumIndices[sumIndices.length - 1];
                        if (colMap.title !== -1) { headerFound = true; return; }
                    }
                }
                if (!headerFound && rIndex > 5) { colMap = { art: 2, title: 3, qty: 4, unit: 5, price: 6, sum: 7 }; headerFound = true; }
                if (!headerFound) return;
                let shift = 0;
                if (colMap.unit === -1 && colMap.qty !== -1) {
                    const possibleUnit = (cells[colMap.qty + 1] || '').toLowerCase();
                    if (['шт', 'компл', 'упак', 'м2', 'пог.м', 'л'].some(u => possibleUnit.includes(u))) shift = 1;
                }
                const getVal = (colType) => {
                    let idx = colMap[colType];
                    if (idx === -1) return '';
                    if (shift > 0 && colMap.qty !== -1 && idx > colMap.qty) return cells[idx + shift] || '';
                    return cells[idx] || '';
                };
                const title = getVal('title');
                if (!title || title.toLowerCase().includes('итого')) return;
                let qty = cleanNum(getVal('qty'));
                let basePrice = cleanNum(getVal('price'));
                let finalSum = cleanNum(getVal('sum'));
                if (qty === 0) qty = 1;
                if (basePrice === 0 && finalSum > 0) basePrice = finalSum / qty;
                if (finalSum === 0 && basePrice > 0) finalSum = basePrice * qty;
                let isDiscounted = false, discountValue = '';
                let finalPrice = finalSum > 0 ? finalSum : (basePrice * qty);
                const calculatedBaseSum = basePrice * qty;
                if (calculatedBaseSum > (finalSum + 2)) { isDiscounted = true; const diff = calculatedBaseSum - finalSum; const percent = (diff / calculatedBaseSum) * 100; discountValue = Math.round(percent); }
                if (basePrice > 0 || finalSum > 0) {
                    newItems.push({ id: Date.now() + Math.random(), type: 'item', article: getVal('art'), title: title, price: basePrice, quantity: qty, unit: (colMap.unit !== -1 ? getVal('unit') : (shift ? cells[colMap.qty + 1] : 'шт')), finalPrice: finalPrice, isDiscounted: isDiscounted, discountType: 'percent', discountValue: isDiscounted ? discountValue : '', image: null, link: '' });
                }
            });
        }
        if (newItems.length === 0 && rawText) {
            const lines = rawText.trim().split('\n');
            lines.forEach(line => {
                const row = line.split('\t');
                if (row.length < 5) return;
                const cleanNum = (s) => parseFloat(s?.replace(/[\s\u00A0]/g, '').replace(',', '.') || '0');
                const title = row[3]?.trim();
                if (!title) return;
                const qty = cleanNum(row[4]);
                const basePrice = cleanNum(row[6]);
                const finalSum = cleanNum(row[row.length - 1]);
                const q = qty || 1;
                if (basePrice > 0 || finalSum > 0) {
                    const fSum = finalSum > 0 ? finalSum : basePrice * q;
                    const bPrice = basePrice > 0 ? basePrice : fSum / q;
                    let isDisc = (bPrice * q) > (fSum + 1);
                    let discVal = '';
                    if (isDisc) discVal = Math.round(((bPrice * q - fSum) / (bPrice * q)) * 100);
                    newItems.push({ id: Date.now() + Math.random(), type: 'item', article: row[2]?.trim(), title: title, price: bPrice, quantity: q, unit: row[5]?.trim() || 'шт', finalPrice: fSum, isDiscounted: isDisc, discountType: 'percent', discountValue: discVal, image: null, link: '' });
                }
            });
        }
        return newItems;
    };

    const handlePasteBox = (e) => {
        const html = e.clipboardData.getData('text/html');
        const text = e.clipboardData.getData('text/plain');
        const parsed = smartParse(html, text);
        if (parsed.length > 0) { setPreviewItems(parsed); e.preventDefault(); }
    };

    const confirmPaste = async () => {
        if (previewItems.length === 0) return;
        setItems(prev => [...prev.filter(x => x.title || x.price), ...previewItems]);
        setShowPasteModal(false);
        const itemsToProcess = [...previewItems];
        setPreviewItems([]);
        setStatusMessage(`Загрузка фото: 0 из ${itemsToProcess.length}...`);
        for (let i = 0; i < itemsToProcess.length; i++) {
            const it = itemsToProcess[i];
            if (it.article) {
                setStatusMessage(`Загрузка фото: ${i + 1} из ${itemsToProcess.length}...`);
                await enrichItemWithImage(it.id, it.article);
                await new Promise(r => setTimeout(r, 1200));
            }
        }
        setStatusMessage(null);
        alert(`Готово! Добавлено ${itemsToProcess.length} товаров.`);
    };

    const addSection = () => setItems([...items, { id: Date.now(), type: 'section', title: 'НОВЫЙ РАЗДЕЛ' }]);
    const addItem = () => setItems([...items, { id: Date.now(), type: 'item', title: '', price: 0, quantity: 1, finalPrice: 0, article: '', isDiscounted: false, discountType: 'fixed', discountValue: '' }]);

    const handleLocalSave = () => { const data = JSON.stringify({ docInfo, items, globalDiscount }, null, 2); const blob = new Blob([data], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `KP-${docInfo.number}.json`; a.click(); URL.revokeObjectURL(url); };
    const handleLocalLoad = (e) => { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (ev) => { try { const data = JSON.parse(ev.target.result); if (data.docInfo) setDocInfo(data.docInfo); if (data.items) setItems(data.items); if (data.globalDiscount !== undefined) { setGlobalDiscount(data.globalDiscount); setShowGlobalDiscountInput(data.globalDiscount > 0); } alert("Проект загружен!"); } catch (err) { alert("Ошибка"); } }; reader.readAsText(file); e.target.value = null; };

    const handleCloudSave = async () => {
        if (!user || !user.id) { alert("Войдите в систему"); return; }
        setSaving(true);
        const pName = docInfo.recipient ? `${docInfo.number} Для ${docInfo.recipient}` : docInfo.number;
        let projectIdToSave = currentProjectId;
        try {
            const checkRes = await fetch(`/api/projects/${user.id}?t=${Date.now()}`);
            const checkData = await checkRes.json();
            if (Array.isArray(checkData)) {
                const existingProject = checkData.find(p => p.name === pName);
                if (existingProject) {
                    if (!projectIdToSave || projectIdToSave !== existingProject.id) {
                        const confirmOverwrite = confirm(`Файл "${pName}" уже существует. Перезаписать его?`);
                        if (confirmOverwrite) { projectIdToSave = existingProject.id; } else { setSaving(false); return; }
                    }
                }
            }
        } catch (e) { }

        const projectData = { user_id: user.id, id: projectIdToSave || 0, name: pName, data: JSON.stringify({ docInfo, items, globalDiscount }) };
        try {
            const res = await fetch('/api/projects', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(projectData) });
            const data = await res.json();
            if (data.status === 'created' || data.status === 'updated') {
                setCurrentProjectId(data.id);
                alert("☁️ Сохранено!");
            } else if (res.status === 402) {
                alert("⛔ " + data.message);
            } else {
                alert("Ошибка сохранения: " + data.detail);
            }
        } catch (e) { alert("Ошибка"); } finally { setSaving(false); }
    };

    const handleUploadPrice = async (e) => { const file = e.target.files[0]; if (!file) return; const formData = new FormData(); formData.append('file', file); e.target.value = null; try { const res = await fetch('/api/upload', { method: 'POST', body: formData }); const data = await res.json(); if (data.status === 'success') { setFileColumns(data.columns); const guess = { article: '', title: '', price: '', link: '' }; data.columns.forEach(col => { const c = col.toLowerCase(); if (c.includes('арт') || c.includes('code')) guess.article = col; else if (c.includes('назв') || c.includes('name')) guess.title = col; else if (c.includes('цен') || c.includes('price')) guess.price = col; else if (c.includes('ссыл') || c.includes('link')) guess.link = col; }); setMapping(guess); setShowMappingModal(true); } else { alert("Ошибка: " + data.detail); } } catch (err) { alert('Ошибка загрузки.'); } };
    const saveColumnMapping = async () => { if (!mapping.article || !mapping.price) { alert("Выберите Артикул и Цену."); return; } try { const res = await fetch('/api/mapping', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(mapping) }); const data = await res.json(); if (data.status === 'ok') { setShowMappingModal(false); alert("✅ Настройки сохранены!"); } } catch (err) { alert("Ошибка сохранения"); } };
    const handleItemChange = (id, f, v) => setItems(prev => prev.map(i => { if (i.id === id) { const u = { ...i, [f]: v }; if (i.type === 'item') { const p = parseFloat(u.price) || 0; const q = parseFloat(u.quantity) || 0; u.finalPrice = calcFinal(p, q, u.isDiscounted, u.discountType, u.discountValue); } return u; } return i; }));
    const handleArticleBlur = (id, artValue, currentTitle) => { if (artValue && !currentTitle) { handleItemChange(id, 'title', artValue); } };
    const deleteItem = (id) => setItems(items.filter(i => i.id !== id));
    const duplicateItem = (id) => { const idx = items.findIndex(i => i.id === id); if (idx === -1) return; const cp = { ...items[idx], id: Date.now() }; const ni = [...items]; ni.splice(idx + 1, 0, cp); setItems(ni); };
    const duplicateItemToBottom = (id) => { const idx = items.findIndex(i => i.id === id); if (idx === -1) return; const cp = { ...items[idx], id: Date.now() }; setItems([...items, cp]); };
    const moveItem = (idx, dir) => { const ni = [...items]; if (dir === -1 && idx > 0) { [ni[idx], ni[idx - 1]] = [ni[idx - 1], ni[idx]]; } else if (dir === 1 && idx < ni.length - 1) { [ni[idx], ni[idx + 1]] = [ni[idx + 1], ni[idx]]; } setItems(ni); };

    const formatPrice = (p) => new Intl.NumberFormat('ru-RU').format(Math.round(p || 0));
    const totals = useMemo(() => { const baseTotal = items.reduce((acc, i) => i.type === 'item' ? acc + (i.price * i.quantity) : acc, 0); const finalTotal = items.reduce((acc, i) => i.type === 'item' ? acc + i.finalPrice : acc, 0); const disc = baseTotal - finalTotal; return { t: baseTotal, disc: disc, f: finalTotal }; }, [items]);
    const hasGlobalDiscount = items.some(i => i.isDiscounted);

    const handlePdf = async () => {
        setIsPdf(true); await new Promise(r => setTimeout(r, 100)); const el = document.getElementById('print-area'); const imgs = el.querySelectorAll('.pdf-no-border'); imgs.forEach(i => i.style.border = 'none');
        for (const item of items) { if (item.image && item.image.startsWith('http')) { const b64 = await urlToBase64(item.image); if (b64) { const imgEls = el.querySelectorAll(`img[src="${item.image}"]`); imgEls.forEach(img => img.src = b64); } } }
        window.html2pdf().set({ margin: 0, filename: `${docInfo.number}.pdf`, image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, useCORS: true, scrollY: 0, backgroundColor: '#ffffff' }, jsPDF: { format: 'a4', orientation: 'portrait', unit: 'mm' } }).from(el).save().then(() => { setIsPdf(false); imgs.forEach(i => i.style.border = ''); });
    };

    const handleImageUpload = (id, e) => { const f = e.target.files[0]; if (f) { const r = new FileReader(); r.onload = (ev) => handleItemChange(id, 'image', ev.target.result); r.readAsDataURL(f); } };
    const handleImageDrop = (e, id) => { e.preventDefault(); e.stopPropagation(); const file = e.dataTransfer.files[0]; if (file && file.type.startsWith('image/')) { const reader = new FileReader(); reader.onload = (ev) => handleItemChange(id, 'image', ev.target.result); reader.readAsDataURL(file); } };
    const handleImagePaste = (e, id) => { const items = e.clipboardData.items; for (let i = 0; i < items.length; i++) { if (items[i].type.indexOf('image') !== -1) { e.preventDefault(); const file = items[i].getAsFile(); const reader = new FileReader(); reader.onload = (ev) => handleItemChange(id, 'image', ev.target.result); reader.readAsDataURL(file); if (e.target.tagName === 'INPUT') e.target.value = ''; break; } } };
    const handleDescDrop = (e, id) => { e.preventDefault(); e.stopPropagation(); const text = e.dataTransfer.getData('text'); if (text) handleItemChange(id, 'title', text); };
    const handlePriceDrop = (e, id) => { e.preventDefault(); e.stopPropagation(); const text = e.dataTransfer.getData('text'); if (!text) return; let clean = text.replace(/[^\d.,]/g, '').replace(',', '.'); const val = parseFloat(clean); if (!isNaN(val)) { handleItemChange(id, 'price', val); } };

    const handleCopyTo1C = () => {
        const canExport = user && (user.is_vip || user.premium || user.role === 'admin');
        if (!canExport) { alert("Экспорт в 1С доступен в PRO версии"); return; }
        const lines = items.filter(i => i.type === 'item').map(i => {
            let p = parseFloat(i.price); if (isNaN(p)) p = 0;
            let q = parseFloat(i.quantity); if (isNaN(q)) q = 0;
            if (i.isDiscounted && q > 0) { let fp = parseFloat(i.finalPrice); if (isNaN(fp)) fp = 0; p = fp / q; }
            const fmt = (n) => n.toFixed(2).replace('.', ',');
            const cleanArt = (i.article || '').replace(/\t/g, ' ');
            const cleanTitle = (i.title || '').replace(/\t/g, ' ');
            return `\t\t${cleanArt}\t${cleanTitle}\t${fmt(q)}\t${fmt(p)}`;
        });
        if (lines.length === 0) { alert("Нет товаров для экспорта"); return; }
        navigator.clipboard.writeText(lines.join('\n')).then(() => alert("📋 Скопировано! Вставьте в 1С (Ctrl+V)")).catch(() => alert("Ошибка доступа к буферу обмена"));
    };

    const isPro = user?.premium || user?.is_vip || user?.role === 'admin';
    const isFree = user?.tier === 'free' && !user?.is_vip;
    const can1C = user?.tier === 'speed' || user?.is_vip || user?.tier === 'vip' || user?.role === 'admin';
    const hasWatermark = user?.tier === 'free' && !user?.is_vip;
    const gridContainerClass = `kp-grid-container ${!hasGlobalDiscount ? 'no-discount' : ''}`;

    return (
        <div className="bg-gray-100 min-h-screen pb-20">
            {statusMessage && <div className="fixed top-16 left-1/2 transform -translate-x-1/2 bg-blue-600 text-white px-6 py-2 rounded-full shadow-lg z-50 animate-bounce font-bold">{statusMessage}</div>}
            
            {showMappingModal && (
                <div className="modal-overlay">
                    <div className="modal-content">
                        <h2 className="text-xl font-bold mb-4">Настройка колонок Excel</h2>
                        <div className="space-y-4">
                            <div><label className="block text-xs font-bold uppercase mb-1">Артикул</label><select value={mapping.article} onChange={e => setMapping({ ...mapping, article: e.target.value })} className="w-full p-2 border rounded"><option value="">--</option>{fileColumns.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
                            <div><label className="block text-xs font-bold uppercase mb-1">Название</label><select value={mapping.title} onChange={e => setMapping({ ...mapping, title: e.target.value })} className="w-full p-2 border rounded"><option value="">--</option>{fileColumns.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
                            <div><label className="block text-xs font-bold uppercase mb-1">Цена</label><select value={mapping.price} onChange={e => setMapping({ ...mapping, price: e.target.value })} className="w-full p-2 border rounded"><option value="">--</option>{fileColumns.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
                            <div><label className="block text-xs font-bold uppercase mb-1">Ссылка</label><select value={mapping.link} onChange={e => setMapping({ ...mapping, link: e.target.value })} className="w-full p-2 border rounded"><option value="">--</option>{fileColumns.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
                        </div>
                        <div className="mt-6 flex justify-end"><button onClick={saveColumnMapping} className="bg-blue-600 text-white px-6 py-2 rounded hover:bg-blue-700">Сохранить</button></div>
                    </div>
                </div>
            )}

            {showPasteModal && (
                <div className="modal-overlay">
                    <div className="modal-content !max-w-4xl !h-[90vh] flex flex-col">
                        <div className="flex justify-between items-start mb-4 flex-shrink-0"><div><h2 className="text-xl font-bold mb-1">Импорт из 1С</h2><p className="text-sm text-gray-500">Нажмите на область ниже и нажмите <b>Ctrl+V</b>.</p></div><button onClick={confirmPaste} disabled={previewItems.length === 0} className="bg-blue-600 hover:bg-blue-700 disabled:opacity-50 disabled:bg-gray-300 text-white px-6 py-2 rounded-lg font-bold shadow-md transition-transform active:scale-95">Добавить {previewItems.length > 0 ? previewItems.length : ''}</button></div>
                        <div className="paste-area h-32 flex items-center justify-center bg-gray-50 border-2 border-dashed border-blue-300 rounded-lg mb-4 hover:bg-blue-50 focus-within:ring-2 ring-blue-500 transition-colors flex-shrink-0" contentEditable="true" onPaste={handlePasteBox}><span className="pointer-events-none font-bold text-lg text-blue-400">Вставьте таблицу сюда (Ctrl+V)</span></div>
                        <div className="flex-1 overflow-auto border border-gray-200 rounded-lg bg-white mb-4">
                            {previewItems.length > 0 ? (
                                <table className="w-full text-left text-xs">
                                    <thead className="bg-gray-100 sticky top-0"><tr><th className="p-2">Артикул</th><th className="p-2">Название</th><th className="p-2 text-right">Кол-во</th><th className="p-2 text-right">Базовая Цена</th><th className="p-2 text-right">Скидка</th><th className="p-2 text-right">Сумма</th></tr></thead>
                                    <tbody className="divide-y">{previewItems.map((it, idx) => (<tr key={idx}><td className="p-2 font-mono text-gray-500">{it.article}</td><td className="p-2 font-bold">{it.title}</td><td className="p-2 text-right">{it.quantity}</td><td className="p-2 text-right">{formatPrice(it.price)}</td><td className="p-2 text-right text-red-500">{it.isDiscounted ? `-${it.discountValue}%` : '-'}</td><td className="p-2 text-right font-bold">{formatPrice(it.finalPrice)}</td></tr>))}</tbody>
                                </table>
                            ) : (<div className="h-full flex items-center justify-center text-gray-400">Нет данных для просмотра</div>)}
                        </div>
                        <div className="flex justify-end gap-2 pt-4 border-t flex-shrink-0"><button onClick={() => { setShowPasteModal(false); setPreviewItems([]); }} className="px-6 py-2 text-gray-500 hover:bg-gray-100 rounded-lg font-bold">Отмена</button><button onClick={confirmPaste} disabled={previewItems.length === 0} className="bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white px-8 py-2 rounded-lg font-bold shadow-lg transition-transform active:scale-95">Добавить {previewItems.length} товаров</button></div>
                    </div>
                </div>
            )}

            {!isPdf && (
                <div className="bg-white border-b px-6 py-3 flex justify-between items-center sticky top-0 z-50 shadow-sm">
                    <button onClick={onBack} className="flex items-center gap-2 text-gray-500 hover:text-gray-800 font-medium"><ArrowLeft size={20} /> Назад</button>
                    <div className="flex gap-3">
                        <button onClick={() => setShowDebugGrid(!showDebugGrid)} className={`hidden md:flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-lg transition-colors ${showDebugGrid ? 'bg-red-100 text-red-600' : 'text-gray-600 bg-gray-100 hover:bg-gray-200'}`}><Ruler size={16} /> Сетка</button>
                        
                        {/* Only show Local Save/Load if NOT Free tier */}
                        {!isFree && (
                            <>
                                <button onClick={handleLocalSave} className="flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 font-bold transition"><Disk size={16} /> Файл</button>
                                <label className="flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 font-bold transition cursor-pointer"><UploadIcon size={16} /> Загрузить<input type="file" onChange={handleLocalLoad} accept=".json" className="hidden" /></label>
                            </>
                        )}
                        
                        <button onClick={handleCloudSave} disabled={saving} className="flex items-center gap-2 px-4 py-2 bg-blue-100 text-blue-700 rounded-lg hover:bg-blue-200 font-bold transition">{saving ? <Loader size={16} /> : <Cloud size={16} />} {saving ? "..." : "Облако"}</button>
                        
                        {/* 1C Features */}
                        {can1C && (
                             <>
                                {/* "Загрузка из 1С" file button hidden as requested for everyone */}
                                {/* <label className="flex items-center gap-2 px-4 py-2 text-sm font-bold text-green-700 bg-green-100 rounded-lg hover:bg-green-200 cursor-pointer"><FileText size={16} /> Загрузка из 1С<input type="file" onChange={handleUploadPrice} accept=".xlsx, .xls" className="hidden" /></label> */}
                                
                                <button onClick={handleCopyTo1C} className="flex items-center gap-2 px-4 py-2 bg-orange-100 text-orange-700 rounded-lg hover:bg-orange-200 font-bold transition" title="Копировать для 1С"><Copy size={16} /> в 1С</button>
                                <button type="button" onClick={() => { setShowPasteModal(true); setPreviewItems([]) }} className="flex items-center gap-2 px-4 py-2 bg-purple-100 text-purple-700 rounded-lg hover:bg-purple-200 font-bold transition cursor-pointer active:scale-95" title="Вставить из 1С"><Clipboard size={16} /> из 1С</button>
                             </>
                        )}

                        <button onClick={handlePdf} className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-bold shadow-md active:scale-95"><Download size={16} /> PDF</button>
                    </div>
                </div>
            )}
            
            {/* --- FLOATING BUTTONS --- */}
            {!isPdf && (
                <div className="fixed bottom-6 right-6 flex flex-col gap-3 z-40 print:hidden">
                    <button onClick={addSection} className="w-12 h-12 bg-white text-gray-600 rounded-full shadow-lg border border-gray-200 flex items-center justify-center hover:bg-gray-50 transition" title="Добавить Раздел"><Layout size={20} /></button>
                    <button onClick={addItem} className="w-14 h-14 bg-blue-600 text-white rounded-full shadow-lg shadow-blue-600/30 flex items-center justify-center hover:bg-blue-700 transition transform active:scale-95" title="Добавить Товар"><Plus size={28} /></button>
                </div>
            )}

            <div className="p-4 md:p-8 flex justify-center">
                <div id="print-area" className={`bg-white w-full max-w-5xl min-h-[1000px] shadow-lg p-8 md:p-12 ${isPdf ? 'pdf-mode' : ''}`}>
                    {hasWatermark && <div className="watermark-overlay"></div>}
                    <header className="flex flex-col md:flex-row justify-between items-start mb-12 flex-shrink-0 gap-8 md:gap-0 relative z-10"><div><h1 className="text-3xl font-black italic text-[#2d3440] leading-[0.95] tracking-tighter uppercase mb-8 print-text-black">Коммерческое<br />Предложение</h1><div className="flex flex-col md:flex-row gap-6 md:gap-12"><div><label className="block text-xs font-bold text-gray-400 uppercase mb-1">№ Документа</label><input value={docInfo.number} onChange={(e) => setDocInfo({ ...docInfo, number: e.target.value })} className="bg-transparent text-2xl font-bold text-[#2d3440] w-full md:w-64 outline-none border-b border-transparent focus:border-gray-400 hide-on-print" /><div className="show-on-print text-2xl font-bold text-[#2d3440] print-text-black">{docInfo.number}</div><div className="mt-2 text-[10px] text-gray-500 max-w-[250px] leading-tight print-text-gray">Цены действуют в течение 3-х дней. Далее нужно уточнять актуальность цен на момент заказа.</div></div><div><label className="block text-xs font-bold text-gray-400 uppercase mb-1">Дата</label><div className="flex items-center gap-2"><input type="date" value={docInfo.date} onChange={handleDateChange} className="text-2xl font-bold text-[#2d3440] bg-transparent outline-none p-0 cursor-pointer hide-on-print font-sans w-full" /><div className="show-on-print text-2xl font-bold text-[#2d3440] print-text-black">{getFormattedDateForPrint()}</div></div></div></div></div><div className="w-full md:w-auto text-left md:text-right md:pr-8"><label className="block text-xs font-bold text-blue-600 uppercase mb-1">Получатель</label><input value={docInfo.recipient} onChange={(e) => setDocInfo({ ...docInfo, recipient: e.target.value })} className="bg-transparent text-2xl md:text-3xl font-bold text-[#2d3440] text-left md:text-right w-full md:w-64 outline-none hide-on-print" placeholder="Кому..." /><div className="show-on-print text-3xl font-bold text-[#2d3440] text-right print-text-black">{docInfo.recipient}</div></div></header>

                    {!isPdf && (
                        <div className="flex justify-start gap-4 mb-8 no-print">
                            <button onClick={addItem} className="flex items-center gap-2 px-6 py-3 bg-blue-100 text-blue-700 rounded-lg hover:bg-blue-200 font-bold transition"><Plus size={20} /> Добавить Товар</button>
                            <button onClick={addSection} className="flex items-center gap-2 px-6 py-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 font-bold transition"><Layout size={20} /> Добавить Раздел</button>
                        </div>
                    )}

                    <div className="space-y-4 relative z-10">
                        {items.map((item, index) => {
                            const isFirstItem = index === 0;
                            const isAfterSection = index > 0 && items[index - 1].type === 'section';
                            const showHeader = item.type === 'item' && (isFirstItem || isAfterSection);

                            if (item.type === 'section') {
                                return (
                                    <div key={item.id} className="pt-8 group relative break-inside-avoid">
                                        <div className="flex items-end border-b-4 border-[#2d3440] pb-2 mb-4">
                                            {!isPdf ? (
                                                <input value={item.title} onChange={e => handleItemChange(item.id, 'title', e.target.value)} className="text-2xl md:text-4xl font-black italic text-[#2d3440] uppercase bg-transparent outline-none w-full placeholder:text-gray-300" placeholder="НАЗВАНИЕ РАЗДЕЛА" />
                                            ) : (
                                                <div className="text-4xl font-black italic text-[#2d3440] uppercase w-full print-text-black">{item.title}</div>
                                            )}
                                            
                                            {!isPdf && (
                                                <div className="absolute -right-12 bottom-2 opacity-0 group-hover:opacity-100 transition-opacity hide-on-print z-50 bg-white/50 hover:bg-white p-1 rounded-md shadow-sm border border-gray-200 flex flex-col gap-1">
                                                    <button onClick={() => moveItem(index, -1)} disabled={index === 0} title="Вверх" className="hover:text-blue-600 text-gray-400 p-1"><ChevronUp size={16} /></button>
                                                    <button onClick={() => moveItem(index, 1)} disabled={index === items.length - 1} title="Вниз" className="hover:text-blue-600 text-gray-400 p-1"><ChevronDown size={16} /></button>
                                                    <div className="w-full h-px bg-gray-200 my-0.5"></div>
                                                    <button onClick={() => deleteItem(item.id)} className="text-red-400 hover:text-red-600 p-1" title="Удалить"><Trash2 size={16} /></button>
                                                </div>
                                            )}
                                        </div>
                                    </div>
                                );
                            }
                            return (
                                <React.Fragment key={item.id}>
                                    {showHeader && <HeaderRow hasGlobalDiscount={hasGlobalDiscount} debugClass={debugClass} gridContainerClass={gridContainerClass} />}
                                    <div className="group relative break-inside-avoid">
                                        <div className={`${gridContainerClass} p-2 rounded-xl transition-colors hover:bg-gray-50`}>
                                            {/* IMAGE */}
                                            <div className={`flex flex-col items-center gap-2 ${debugClass}`}>
                                                <div className={`relative w-20 h-20 bg-gray-100 rounded-xl flex items-center justify-center overflow-hidden transition-colors hover:border-blue-300 hide-on-print`} onDragOver={e => !isPdf && e.preventDefault()} onDrop={e => !isPdf && handleImageDrop(e, item.id)}>
                                                    {item.image ? <img src={item.image} className="w-full h-full object-contain pointer-events-none" /> : !isPdf && <ImageIcon size={20} className="text-gray-400 pointer-events-none" />}
                                                    {!isPdf && <input id={`f-${item.id}`} type="file" className="hidden" onChange={e => handleImageUpload(item.id, e)} />}
                                                </div>
                                                {!isPdf && (
                                                    <div className="w-full hide-on-print">
                                                        <input type="text" placeholder="Вставить (Ctrl+V)" onPaste={(e) => handleImagePaste(e, item.id)} className="w-full text-[9px] text-center bg-gray-50 border border-gray-200 rounded outline-none focus:bg-white focus:border-blue-400 px-1" />
                                                    </div>
                                                )}
                                                <div className="show-on-print w-20 h-20 bg-white flex items-center justify-center pdf-no-border text-center">
                                                    {item.image && <img src={item.image} style={{ maxWidth: '100%', maxHeight: '100%', display: 'block', margin: 'auto' }} />}
                                                </div>
                                            </div>

                                            {/* TITLE / DESC */}
                                            <div className={`pl-2 pt-1 w-full ${debugClass}`}>
                                                {!isPdf ? (
                                                    <>
                                                        <div className="flex items-center gap-1 mb-2">
                                                            <div className="relative w-full">
                                                                <input type="text" value={item.article || ''} onChange={e => handleItemChange(item.id, 'article', e.target.value)} onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); fetchProductByArticle(item.id, e.target.value) } }} onBlur={e => handleArticleBlur(item.id, e.target.value, item.title)} placeholder="🔍 Артикул" enterKeyHint="search" className={`w-full text-xs py-1.5 px-3 border border-gray-200 rounded focus:border-blue-500 outline-none ${loadingItems[item.id] ? 'bg-gray-100 animate-pulse' : 'bg-white'}`} />
                                                            </div>
                                                            <button onClick={() => fetchProductByArticle(item.id, item.article)} className="p-2 bg-blue-600 text-white rounded hover:bg-blue-700 shadow-sm transition-colors flex-shrink-0" title="Найти"><Search size={14} /></button>
                                                        </div>
                                                        <textarea ref={el => textareaRefs.current[item.id] = el} rows={2} value={item.title} onChange={e => handleItemChange(item.id, 'title', e.target.value)} onDrop={e => handleDescDrop(e, item.id)} onDragOver={e => e.preventDefault()} className="w-full font-bold text-gray-800 text-sm bg-white border border-gray-200 rounded p-1 outline-none resize-none focus:border-blue-500" placeholder="Описание товара..." />
                                                        <div className="mt-2 flex gap-2">
                                                            <button onClick={() => handleItemChange(item.id, 'isDiscounted', !item.isDiscounted)} className={`text-[10px] font-bold px-2 py-1 rounded uppercase ${item.isDiscounted ? 'bg-blue-600 text-white' : 'bg-gray-200 text-gray-500'}`}>% Скидка</button>
                                                            {item.isDiscounted && (
                                                                <div className="flex flex-col gap-1">
                                                                    <div className="flex items-center gap-1">
                                                                        <button onClick={() => handleItemChange(item.id, 'discountType', 'percent')} className={`p-1 rounded text-xs font-bold w-20 text-left transition-colors ${item.discountType === 'percent' ? 'bg-blue-100 text-blue-700' : 'text-gray-400 hover:bg-gray-100'}`}>% Процент</button>
                                                                        {item.discountType === 'percent' && <input type="number" value={item.discountValue} onChange={e => handleItemChange(item.id, 'discountValue', e.target.value)} className="w-16 text-xs bg-white border border-gray-300 rounded px-1 py-0.5 outline-none focus:border-blue-500" />}
                                                                    </div>
                                                                    <div className="flex items-center gap-1">
                                                                        <button onClick={() => handleItemChange(item.id, 'discountType', 'fixed')} className={`p-1 rounded text-xs font-bold w-20 text-left transition-colors ${item.discountType === 'fixed' ? 'bg-blue-100 text-blue-700' : 'text-gray-400 hover:bg-gray-100'}`}>₽ Спец.цена</button>
                                                                        {item.discountType === 'fixed' && <input type="number" value={item.discountValue} onChange={e => handleItemChange(item.id, 'discountValue', e.target.value)} className="w-16 text-xs bg-white border border-gray-300 rounded px-1 py-0.5 outline-none focus:border-blue-500" />}
                                                                    </div>
                                                                </div>
                                                            )}
                                                        </div>
                                                    </>
                                                ) : (
                                                    <div className="text-sm font-bold text-black whitespace-pre-wrap">{item.title}</div>
                                                )}
                                            </div>

                                            {/* LINK */}
                                            <div className={`kp-col-link text-center pt-1 ${debugClass}`}>
                                                {!isPdf ? (
                                                    <>
                                                        <input value={item.link} onChange={e => handleItemChange(item.id, 'link', e.target.value)} placeholder="URL" className="bg-[#f0f0f0] px-2 py-1 rounded-md text-[10px] font-bold text-gray-600 w-full text-center outline-none" />
                                                        {item.link && <a href={item.link} target="_blank" className="text-[#5c5cff] block text-center mt-1"><ExternalLink size={14} className="inline" /></a>}
                                                    </>
                                                ) : (
                                                    <div className="text-center">{item.link && <a href={item.link} style={{ fontSize: '10px', color: 'blue', textDecoration: 'underline' }}>Ссылка</a>}</div>
                                                )}
                                            </div>

                                            {/* QTY */}
                                            <div className={`text-right pt-1 font-bold text-gray-800 kp-col-qty ${debugClass}`}>
                                                {!isPdf ? <input type="number" value={item.quantity} onChange={e => handleItemChange(item.id, 'quantity', e.target.value)} className="w-full text-right bg-transparent outline-none" /> : item.quantity}
                                            </div>

                                            {/* PRICE */}
                                            <div className={`text-right pt-1 font-medium text-gray-800 kp-col-price ${debugClass}`}>
                                                {!isPdf ? <input type="number" value={item.price} onChange={e => handleItemChange(item.id, 'price', e.target.value)} onFocus={e => e.target.select()} onDragOver={e => { e.preventDefault(); e.stopPropagation(); e.currentTarget.classList.add('bg-blue-100') }} onDragLeave={e => e.currentTarget.classList.remove('bg-blue-100')} onDrop={e => handlePriceDrop(e, item.id)} className="w-full text-right bg-transparent outline-none rounded transition-colors" /> : formatPrice(item.price)}
                                            </div>

                                            {/* SUM */}
                                            <div className={`text-right font-bold pt-1 ${debugClass}`}>
                                                {hasGlobalDiscount && item.isDiscounted && parseFloat(item.discountValue) > 0 ? (
                                                    <div className="inline-block relative">
                                                        <span className="text-gray-400 print-text-gray">{formatPrice(item.price * item.quantity)}</span>
                                                        <div className="strikethrough-line absolute top-1/2 left-0 w-full h-[2px] bg-gray-400 -translate-y-1/2 z-10 transform rotate-[-10deg]"></div>
                                                    </div>
                                                ) : (
                                                    <span className="text-[#2d3440] print-text-black">{formatPrice(item.price * item.quantity)}</span>
                                                )}
                                            </div>

                                            {/* FINAL TOTAL */}
                                            {hasGlobalDiscount && <div className={`text-right pt-1 font-black text-blue-600 print:text-black ${debugClass}`}>{item.isDiscounted ? formatPrice(item.finalPrice) : ''}</div>}
                                        </div>

                                        {/* ITEM ACTIONS */}
                                        {!isPdf && (
                                            <div className="absolute -right-12 top-0 opacity-0 group-hover:opacity-100 transition-opacity hide-on-print z-50 bg-white/50 hover:bg-white p-1 rounded-md shadow-sm border border-gray-200 flex flex-col gap-1">
                                                <button onClick={() => moveItem(index, -1)} disabled={index === 0} title="Вверх" className="hover:text-blue-600 text-gray-400 p-1"><ChevronUp size={16} /></button>
                                                <button onClick={() => duplicateItem(item.id)} className="text-blue-500 hover:text-blue-700 p-1" title="Копировать рядом"><Copy size={16} /></button>
                                                <button onClick={() => duplicateItemToBottom(item.id)} className="text-green-600 hover:text-green-800 p-1" title="Копировать в конец списка"><ArrowDown size={16} /></button>
                                                <button onClick={() => moveItem(index, 1)} disabled={index === items.length - 1} title="Вниз" className="hover:text-blue-600 text-gray-400 p-1"><ChevronDown size={16} /></button>
                                                <div className="w-full h-px bg-gray-200 my-0.5"></div>
                                                <button onClick={() => deleteItem(item.id)} className="text-red-400 hover:text-red-600 p-1" title="Удалить"><Trash2 size={16} /></button>
                                            </div>
                                        )}
                                    </div>
                                </React.Fragment>
                            );
                        })}
                    </div>

                    <div className="mt-12 border-t-2 border-gray-100 pt-6 flex flex-col items-end relative z-10">
                        <div className="w-64">
                            <div className="flex justify-between mb-2"><span className="text-gray-500 font-bold">Сумма:</span><span className="font-bold text-gray-800">{formatPrice(totals.t)} ₽</span></div>
                            {totals.disc > 0 && (<div className="flex justify-between mb-2 text-red-500 font-bold"><span>Скидка на заказ:</span><span>-{formatPrice(totals.disc)} ₽</span></div>)}
                            <div className="flex justify-between border-t border-gray-200 pt-4"><span className="text-xl font-black uppercase text-gray-800">Итого:</span><span className="text-3xl font-black text-gray-800">{formatPrice(totals.f)} ₽</span></div>
                            
                            {!isPdf && (
                                <div className="mt-4 flex items-center justify-end gap-2 border-t pt-4 w-full">
                                    {!showGlobalDiscountInput ? (
                                        <button onClick={toggleGlobalDiscount} className="text-xs font-bold text-blue-600 hover:text-blue-800 bg-blue-50 px-3 py-1.5 rounded transition-colors">% Скидка на проект</button>
                                    ) : (
                                        <div className="flex items-center gap-2 animate-fade-in">
                                            <label className="text-xs text-gray-500 font-bold">Скидка (%):</label>
                                            <input type="number" value={globalDiscount} onChange={e => handleGlobalDiscountChange(e.target.value)} className="w-16 border border-gray-300 rounded px-2 py-1 text-right font-bold text-red-500 outline-none focus:border-red-500" placeholder="0" autoFocus />
                                            <button onClick={toggleGlobalDiscount} className="text-gray-400 hover:text-red-500 p-1" title="Убрать скидку"><span className="text-lg leading-none">×</span></button>
                                        </div>
                                    )}
                                </div>
                            )}
                        </div>
                    </div>

                    {!isPdf && (
                        <div className="mt-12 grid grid-cols-2 gap-4">
                            <button onClick={addItem} className="border-2 border-dashed border-gray-300 py-4 rounded-lg text-gray-400 font-bold hover:border-blue-400 hover:text-blue-500 flex items-center justify-center gap-2"><Plus size={24} /> Товар</button>
                            <button onClick={addSection} className="border-2 border-dashed border-gray-300 py-4 rounded-lg text-gray-400 font-bold hover:border-blue-400 hover:text-blue-500 flex items-center justify-center gap-2"><Layout size={24} /> Раздел</button>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
};
