import React, { useState, useEffect, useMemo, useRef, useLayoutEffect } from 'https://esm.sh/react@18.2.0';
import { createRoot } from 'https://esm.sh/react-dom@18.2.0/client';
import * as LucideIcons from 'https://esm.sh/lucide-react@0.292.0';
import SignaturePad from 'https://esm.sh/signature_pad@4.1.7';

const { User, Lock, LogIn, FileText, Plus, Search, ChevronLeft, ChevronRight, UserCircle, Trash2, Save, Loader2, LogOut, ChevronDown, ChevronUp, Eye, EyeOff, Printer, Settings, CheckSquare, X, Edit, Filter, RefreshCw, Calendar, Phone, Download, HelpCircle, Columns, Layout, ZoomIn, ZoomOut, Globe, ArrowUp, ArrowDown, Moon, Sun, Mail, UserPlus, Check, Image: ImageIcon, Upload } = LucideIcons;
const SUPP_SEPARATOR = '|||SUPP|||';

// --- TRANSLATION DICTIONARY ---
const TEXT = {
    th: {
        quotation_title: "ใบเสนอราคา", quotation_sub: "Quotation", company_name_en: "PAVARA PROSPERITY CO.,LTD.", company_name_th: "บริษัท ปาวาร่า พรอสเพอร์ริตี้ จำกัด (สำนักงานใหญ่)", address: "194 หมู่ 15 ตำบลเมืองเก่า อำเภอเมืองขอนแก่น จังหวัดขอนแก่น", tel: "โทรศัพท์ :", tax_id_label: "เลขประจำตัวผู้เสียภาษี/เลขที่ทะเบียนการค้า", attn: "เรียน", doc_no: "เลขที่", addr_label: "ที่อยู่", date: "วันที่", delivery_date: "วันจัดส่ง", delivery_text: "7-15 วัน หลังอนุมัติสั่งซื้อ<br/>60 วัน กรณีนำเข้า/สั่งผลิต", tax_id_short: "เลขผู้เสียภาษี", validity: "ยืนยันราคา", contact: "ติดต่อ", page: "หน้า:", continued: "ใบเสนอราคา (ต่อ)", no: "ลำดับ", desc: "รายละเอียดสินค้า", img: "รูป", qty: "จำนวน", unit: "หน่วย", price_unit: "ราคา/หน่วย", total_col: "รวม (บาท)", note_label: "หมายเหตุ:", total_label: "ยอดรวม", discount_label: "ส่วนลด", after_discount_label: "รวมเงิน", vat_label: "ภาษีมูลค่าเพิ่ม 7%", net_total_label: "รวมทั้งสิ้น (บาท)", closing_text: "ทางบริษัทฯ หวังเป็นอย่างยิ่งว่า จะได้รับการพิจารณาสั่งซื้อจากท่าน จึงเรียนมาเพื่อโปรดพิจารณา", approved_by: "อนุมัติสั่งซื้อ", manager_pos: "ผู้จัดการฝ่ายขาย", sales_pos: "พนักงานขาย", supp_included: "อุปกรณ์มากับเครื่อง", supp_warranty: "การรับประกัน", supp_payment: "เงื่อนไขการชำระ", baht: "บาท", satang: "สตางค์", only: "ถ้วน", dash_title: "ใบเสนอราคา", hello: "สวัสดี,", last_update: "อัปเดตล่าสุด:", search: "ค้นหา...", filter_start: "ตั้งแต่วันที่", filter_end: "ถึงวันที่", filter_issuer: "เลือกผู้ออกเอกสาร", not_found: "ไม่พบรายการ", create_title: "สร้างใบเสนอราคา", edit_title: "แก้ไขใบเสนอราคา", preview: "ดูตัวอย่าง", hide_preview: "ซ่อนตัวอย่าง", show_preview: "แสดงตัวอย่าง", cust_info: "ข้อมูลลูกค้า", doc_auto: "(สร้างอัตโนมัติ)", issuer: "ผู้ออก", issuer_phone: "เบอร์พนักงานขาย", cust_search: "ค้นหาลูกค้า...", phone_ph: "เบอร์โทร", tax_ph: "เลขประจำตัวผู้เสียภาษี (13 หลัก)", addr_ph: "ที่อยู่บรรทัดที่", prod_title: "รายการสินค้า", prod_search: "ชื่อสินค้า...", show_detail: "แสดงรายละเอียด", hide_detail: "ซ่อนรายละเอียด", detail_ph: "บรรทัดที่", img_url: "URL รูปภาพ", add_supp: "รายการเพิ่ม", edit_supp: "แก้ไขรายการเสริม", add_prod: "เพิ่มรายการสินค้า", summary_title: "สรุปยอด", vat_type: "ประเภท VAT", vat_no: "NO VAT (ไม่มีภาษี)", vat_ex: "VAT นอก (7%)", vat_in: "VAT ใน (7%)", disc_pct: "ส่วนลด (%)", disc_baht: "ส่วนลด (บาท)", note_add: "หมายเหตุเพิ่มเติม", note_line_ph: "หมายเหตุบรรทัดที่", save: "บันทึก", confirm_save: "ตรวจสอบข้อมูลครบถ้วนแล้วหรือไม่ ?", yes_save: "ใช่, บันทึกข้อมูล", no_cancel: "ไม่ใช่, กลับไปแก้ไข", warn_cust: "กรุณาระบุชื่อลูกค้า", warn_phone: "กรุณาระบุเบอร์โทรติดต่อ", warn_addr: "กรุณาระบุที่อยู่", warn_item: "ต้องมีรายการสินค้าอย่างน้อย 1 รายการ", login_welcome: "ยินดีต้อนรับ", login_sub: "ระบบจัดการใบเสนอราคา", username: "ชื่อผู้ใช้งาน", password: "รหัสผ่าน", login_btn: "เข้าสู่ระบบ", checking: "กำลังตรวจสอบ...", download: "ดาวน์โหลด", print: "พิมพ์", detail_view: "รายละเอียด:", supp_modal_title: "รายการเพิ่ม", cancel: "ยกเลิก", save_item: "บันทึกรายการ", supp_ph: "ระบุรายละเอียดข้อที่", move_up: "ย้ายขึ้น", move_down: "ย้ายลง", remove: "ลบรายการ", loading_msg: "กำลังโหลด...", downloading_msg: "กำลังดาวน์โหลด...", error_title: "เกิดข้อผิดพลาด", alert_title: "แจ้งเตือน", success_title: "สำเร็จ", load_user_fail: "ไม่สามารถโหลดรายชื่อผู้ใช้ได้", please_select_user: "กรุณาระบุชื่อผู้ใช้งาน", saved_success: "บันทึกข้อมูลเรียบร้อยแล้ว", check_title: "ตรวจสอบข้อมูล", confirm_delete_title: "ยืนยันการลบ", confirm_delete_text: "ต้องการลบเอกสารเลขที่", delete_btn: "ลบข้อมูล", deleted_title: "ลบแล้ว", item_deleted: "ลบรายการเรียบร้อยแล้ว", pdf_fail: "การสร้าง PDF ล้มเหลว", example_title: "ตัวอย่าง", example_text: "ตัวอย่าง: 0105556002882", compact_mode: "โหมดบีบหน้า (Compact)", req_fields: "กรุณากรอกข้อมูลให้ครบและถูกต้อง", manage_images: "จัดการรูปภาพ", upload_image: "อัปโหลดรูป",
        sig_settings: "ตั้งค่าลายเซ็น", sig_manage_sub: "จัดการเอกลักษณ์ดิจิทัลของคุณ", draw_live: "เซ็นสดผ่านหน้าจอ", sig_here: "เซ็นชื่อที่นี่", please_sign: "กรุณาเซ็นชื่อก่อนบันทึก", back_to_profile: "กลับไปหน้าโปรไฟล์", undo: "ย้อนกลับ", clear: "ล้างหน้าจอ", save_sig: "บันทึกชื่อ",
        version: "เวอร์ชัน", filter_by_date: "กรองตามวันที่", all_issuers: "ผู้ออกเอกสารทั้งหมด", overview_reports: "ภาพรวมและรายงาน",
        db_connected: "เชื่อมต่อฐานข้อมูลแล้ว", search_tip: "ลองปรับการค้นหาหรือช่วงวันที่ในแถบเมนูด้านข้าง", date_label: "วันที่", by_label: "โดย"
    },
    en: {
        quotation_title: "Quotation", quotation_sub: "Quotation", company_name_en: "PAVARA PROSPERITY CO.,LTD.", company_name_th: "PAVARA PROSPERITY CO.,LTD. (Head Office)", address: "194 Moo 15, Mueang Kao, Mueang Khon Kaen, Khon Kaen", tel: "Tel :", tax_id_label: "Tax ID / Commercial Registration No.", attn: "Attn", doc_no: "No.", addr_label: "Address", date: "Date", delivery_date: "Delivery", delivery_text: "7-15 Days after approval<br/>60 Days for Import/Made to order", tax_id_short: "Tax ID", validity: "Validity", contact: "Contact", page: "Page:", continued: "Quotation (Cont.)", no: "No.", desc: "Description", img: "Image", qty: "Qty", unit: "Unit", price_unit: "Unit Price", total_col: "Amount", note_label: "Note:", total_label: "Subtotal", discount_label: "Discount", after_discount_label: "Total after Discount", vat_label: "VAT (7%)", net_total_label: "Grand Total", closing_text: "We hope this quotation meets your approval and look forward to receiving your order.", approved_by: "Authorized Signature", manager_pos: "Sales Manager", sales_pos: "Sales Representative", supp_included: "Included Items", supp_warranty: "Warranty", supp_payment: "Payment Terms", baht: "Baht", satang: "Satang", only: "Only", dash_title: "Quotation System", hello: "Hello,", last_update: "Last Updated:", search: "Search...", filter_start: "From Date", filter_end: "To Date", filter_issuer: "Issuer", not_found: "No items found", create_title: "Create Quotation", edit_title: "Edit Quotation", preview: "Preview", hide_preview: "Hide Preview", show_preview: "Show Preview", cust_info: "Customer Info", doc_auto: "(Auto Generated)", issuer: "Issuer", issuer_phone: "Sales Phone", cust_search: "Search Customer...", phone_ph: "Phone Number", tax_ph: "Tax ID (13 Digits)", addr_ph: "Address Line", prod_title: "Products", prod_search: "Product Name...", show_detail: "Show Detail", hide_detail: "Hide Detail", detail_ph: "Line", img_url: "Image URL", add_supp: "Add. Items", edit_supp: "Edit Add. Items", add_prod: "Add Product", summary_title: "Summary", vat_type: "VAT Type", vat_no: "NO VAT", vat_ex: "VAT Excl. (7%)", vat_in: "VAT Incl. (7%)", disc_pct: "Discount (%)", disc_baht: "Discount (THB)", note_add: "Additional Note", note_line_ph: "Note Line", save: "Save", confirm_save: "Is all information correct?", yes_save: "Yes, Save", no_cancel: "No, Edit", warn_cust: "Please specify customer name", warn_phone: "Please specify phone number", warn_addr: "Please specify address", warn_item: "At least 1 item is required", login_welcome: "Welcome", login_sub: "Login to manage your documents", username: "Username", password: "Password", login_btn: "Login", checking: "Checking...", download: "Download", print: "Print", detail_view: "Detail:", supp_modal_title: "Additional Items", cancel: "Cancel", save_item: "Save Items", supp_ph: "Detail item", move_up: "Move Up", move_down: "Move Down", remove: "Remove", loading_msg: "Loading...", downloading_msg: "Downloading...", error_title: "Error", alert_title: "Alert", success_title: "Success", load_user_fail: "Load Users Failed", please_select_user: "Please specify username", saved_success: "Saved successfully", check_title: "Check", confirm_delete_title: "Confirm Delete", confirm_delete_text: "Delete document", delete_btn: "Delete", deleted_title: "Deleted", item_deleted: "Item deleted", pdf_fail: "PDF generation failed", example_title: "Example", example_text: "Example: 0105556002882", compact_mode: "Compact Mode", req_fields: "Please fill all fields correctly", manage_images: "Manage Images", upload_image: "Upload Image",
        sig_settings: "Signature Settings", sig_manage_sub: "Manage Your Digital Identity", draw_live: "Draw Live", sig_here: "Sign Here", please_sign: "Please sign before saving", back_to_profile: "Back to Profile", undo: "Undo", clear: "Clear", save_sig: "Save Signature",
        version: "Version", filter_by_date: "Filter by Date", all_issuers: "All Issuers", overview_reports: "Overview & Reports",
        db_connected: "Live Database Connected", search_tip: "Try refining your search or date range in the sidebar", date_label: "Date", by_label: "By"
    }
};

const LanguageToggle = ({ lang, setLang }) => (
    <div className="flex bg-gray-100 dark:bg-gray-800 p-1 rounded-full border border-gray-300 dark:border-gray-600 shadow-inner w-fit cursor-pointer transition-colors" onClick={() => setLang(lang === 'th' ? 'en' : 'th')}>
        <div className={`px-3 py-1 rounded-full text-xs font-bold transition-all duration-300 flex items-center gap-1 ${lang === 'th' ? 'bg-white dark:bg-gray-600 text-blue-600 dark:text-white shadow-sm' : 'text-gray-400 dark:text-gray-400'}`}>
            <span>TH</span>
        </div>
        <div className={`px-3 py-1 rounded-full text-xs font-bold transition-all duration-300 flex items-center gap-1 ${lang === 'en' ? 'bg-white dark:bg-gray-600 text-blue-600 dark:text-white shadow-sm' : 'text-gray-400 dark:text-gray-400'}`}>
            <span>EN</span>
        </div>
    </div>
);

const ThemeToggle = ({ theme, setTheme }) => (
    <button
        onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
        className="p-2 rounded-full bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors border border-gray-300 dark:border-gray-600 shadow-inner flex items-center justify-center"
        title="Toggle Dark Mode"
    >
        {theme === 'light' ? <Moon size={18} /> : <Sun size={18} />}
    </button>
);

const formatCurrency = (num) => new Intl.NumberFormat('th-TH', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(num || 0);
const getCurrentDate = () => new Date().toISOString().split('T')[0];

const formatDate = (dateString, lang) => {
    if (!dateString) return "";
    if (typeof dateString === 'string' && dateString.includes('\u200B')) return "";
    try {
        const date = new Date(dateString.replace('\u200B', ''));
        if (isNaN(date.getTime())) return dateString.replace('\u200B', '');

        const day = String(date.getDate()).padStart(2, '0');
        const month = String(date.getMonth() + 1).padStart(2, '0');

        if (lang === 'en') {
            const year = date.getFullYear();
            return `${day}/${month}/${year}`;
        } else {
            const year = date.getFullYear() + 543;
            return `${day}/${month}/${year}`;
        }
    } catch (e) { return typeof dateString === 'string' ? dateString.replace('\u200B', '') : dateString; }
};

const premiumAlert = {
    fire: (options) => {
        return Swal.fire({
            ...options,
            customClass: {
                popup: 'custom-swal-popup',
                title: 'custom-swal-title',
                htmlContainer: 'custom-swal-content',
                confirmButton: 'custom-swal-confirm-button',
                cancelButton: 'custom-swal-cancel-button',
                actions: 'swal2-actions'
            },
            buttonsStyling: false,
            showClass: {
                popup: 'animate__animated animate__zoomIn animate__faster'
            },
            hideClass: {
                popup: 'animate__animated animate__zoomOut animate__faster'
            }
        });
    },
    success: (title, text) => premiumAlert.fire({ icon: 'success', title, text }),
    error: (title, text) => premiumAlert.fire({ icon: 'error', title, text }),
    warn: (title, text) => premiumAlert.fire({ icon: 'warning', title, text }),
    info: (title, text) => premiumAlert.fire({ icon: 'info', title, text }),
    confirm: (title, text, confirmText, cancelText) => premiumAlert.fire({
        icon: 'question',
        title,
        text,
        showCancelButton: true,
        confirmButtonText: confirmText || 'Yes',
        cancelButtonText: cancelText || 'No'
    })
};

const convertNumberToEnglish = (amount) => {
    const units = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine'];
    const teens = ['Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
    const tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];

    const convertGroup = (n) => {
        let str = '';
        if (n >= 100) {
            str += units[Math.floor(n / 100)] + ' Hundred ';
            n %= 100;
        }
        if (n >= 20) {
            str += tens[Math.floor(n / 10)] + ' ';
            n %= 10;
        }
        if (n >= 10) {
            str += teens[n - 10] + ' ';
            n = 0;
        }
        if (n > 0) {
            str += units[n] + ' ';
        }
        return str.trim();
    };

    const numStr = parseFloat(amount).toFixed(2);
    const [intPart, decPart] = numStr.split('.');
    let integer = parseInt(intPart);
    let decimal = parseInt(decPart);

    if (integer === 0 && decimal === 0) return 'Zero Baht Only';

    let words = '';
    if (integer > 0) {
        if (integer >= 1000000) {
            words += convertGroup(Math.floor(integer / 1000000)) + ' Million ';
            integer %= 1000000;
        }
        if (integer >= 1000) {
            words += convertGroup(Math.floor(integer / 1000)) + ' Thousand ';
            integer %= 1000;
        }
        if (integer > 0) {
            words += convertGroup(integer);
        }
        words = words.trim() + ' Baht';
    }

    if (decimal > 0) {
        if (words !== '') words += ' and ';
        words += convertGroup(decimal) + ' Satang';
    } else {
        words += ' Only';
    }

    return words;
};

const ThaiNumberToText = (num, lang) => {
    if (lang === 'en') {
        return convertNumberToEnglish(num);
    }

    num = parseFloat(num).toFixed(2);
    const ThaiNumber = ["ศูนย์", "หนึ่ง", "สอง", "สาม", "สี่", "ห้า", "หก", "เจ็ด", "แปด", "เก้า"];
    const ThaiUnit = ["", "สิบ", "ร้อย", "พัน", "หมื่น", "แสน", "ล้าน"];
    let bahtText = "";
    let [integer, fraction] = num.split(".");
    if (integer.length > 7) return "จำนวนเงินมากเกินไป";
    for (let i = 0; i < integer.length; i++) {
        const digit = parseInt(integer.charAt(i));
        const unitIndex = integer.length - i - 1;
        if (digit !== 0) {
            if (unitIndex === 1 && digit === 1) bahtText += "";
            else if (unitIndex === 1 && digit === 2) bahtText += "ยี่";
            else if (unitIndex === 0 && digit === 1 && integer.length > 1) bahtText += "เอ็ด";
            else bahtText += ThaiNumber[digit];
            bahtText += ThaiUnit[unitIndex];
        }
    }
    bahtText += "บาท";
    if (parseInt(fraction) === 0) bahtText += "ถ้วน";
    else {
        for (let i = 0; i < fraction.length; i++) {
            const digit = parseInt(fraction.charAt(i));
            const unitIndex = fraction.length - i - 1;
            if (digit !== 0) {
                if (unitIndex === 1 && digit === 1) bahtText += "";
                else if (unitIndex === 1 && digit === 2) bahtText += "ยี่";
                else if (unitIndex === 0 && digit === 1 && fraction.length > 1) bahtText += "เอ็ด";
                else bahtText += ThaiNumber[digit];
                if (unitIndex === 1) bahtText += "สิบ";
            }
        }
        bahtText += "สตางค์";
    }
    return bahtText;
};

const parseDetailField = (rawDetail) => {
    if (!rawDetail) return { text: '', supp: null };
    const parts = rawDetail.split(SUPP_SEPARATOR);
    let text = parts[0] || '';

    let supp = null;
    if (parts.length > 1) {
        try { supp = JSON.parse(parts[1]); } catch (e) { console.error(e); }
    }
    return { text, supp };
};

const CompanyHeader = ({ lang }) => {
    const t = TEXT[lang];
    return (
        <>
            <div className="bg-brand-dark text-white text-center py-2 text-xl font-bold mb-1">{t.quotation_title}</div>
            <div className="flex border border-gray-400 mb-2 h-[115px] overflow-hidden bg-white">
                <div className="flex-1 px-3 flex flex-col justify-center text-[10px] text-gray-700">
                    <div className="flex flex-col gap-0.5 leading-snug">
                        <div className="font-bold text-gray-900 text-[10px]">{t.company_name_en}</div>
                        <div className="font-bold text-gray-900">{t.company_name_th}</div>
                        <div className="text-gray-900">{t.address}</div>
                        <div className="text-gray-900">{t.tel} 087-3747733</div>
                        <div className="text-gray-900">{t.tax_id_label} 0405556002882</div>
                        <div className="break-all text-gray-900">email : pavarapprt@gmail.com website : pavarapros.com line id : @pavarapros</div>
                    </div>
                </div>
                <div className="w-[240px] flex items-center justify-center border-l border-gray-400 bg-white p-0 overflow-hidden"><div className="pavara-wrapper"><div className="pavara-circle">P</div><div className="pavara-content"><div className="pavara-title stroked-text">AVARA</div><div className="pavara-line"></div><div className="pavara-subtitle stroked-text"><span>PROSPERITY</span><span className="ml-2">Co.,Ltd.</span></div></div></div></div>
            </div>
        </>
    );
};

const CustomerDetail = ({ q, lang }) => {
    const t = TEXT[lang];
    const addressLines = (q.customerAddress || "").split('\n');
    const line1 = addressLines[0] || "";
    const line2 = addressLines[1] || "";
    return (
        <div className="border border-gray-400 text-xs mb-4 text-black bg-white">
            <div className="flex border-b border-gray-400"><div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.attn}</div><div className="flex-1 p-2 border-r border-gray-400 flex items-center text-black">{q.customerName || "-"}</div><div className="w-[240px] flex"><div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.doc_no}</div><div className="flex-1 p-2 flex items-center justify-center text-black">{q.quotationID || "-"}</div></div></div>
            <div className="flex border-b border-gray-400 items-stretch">
                <div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.addr_label}</div>
                <div className="flex-1 p-2 border-r border-gray-400 flex flex-col justify-center text-[11px] leading-snug overflow-hidden min-h-[64px] text-black">
                    <div style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{line1}</div>
                    <div style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{line2}</div>
                </div>
                <div className="w-[240px] flex flex-col">
                    <div className="flex border-b border-gray-400 h-8"><div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.date}</div><div className="flex-1 p-2 flex items-center justify-center text-black">{formatDate(q.date, lang)}</div></div>
                    <div className="flex flex-1"><div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.delivery_date}</div><div className="flex-1 p-1 text-center text-[10px] leading-tight flex items-center justify-center text-black" dangerouslySetInnerHTML={{ __html: t.delivery_text }}></div></div>
                </div>
            </div>
            <div className="flex border-b border-gray-400">
                <div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.tax_id_short}</div>
                <div className="flex-1 p-2 border-r border-gray-400 flex items-center text-black">{q.customerTaxId || "-"}</div>
                <div className="w-[240px] flex">
                    <div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.validity}</div>
                    <div className="flex-1 p-2 flex items-center justify-center text-center leading-tight text-black">{q.priceValidity || "-"}</div>
                </div>
            </div>
            <div className="flex">
                <div className="w-[85px] font-bold bg-white p-2 border-r border-gray-400 flex items-center justify-center text-black">{t.contact}</div>
                <div className="flex-1 p-2 border-r border-gray-400 flex items-center text-black">{q.phone || "-"}</div>
                <div className="w-[240px] flex bg-gray-50">
                    <div className="flex-1"></div>
                </div>
            </div>
        </div>
    )
};

const SmallInfo = ({ pageNumber, lang }) => {
    const t = TEXT[lang];
    return (
        <div className="flex justify-between items-end border-b border-gray-300 pb-2 mb-4 text-xs text-gray-500 bg-white">
            <div className="font-bold text-brand-dark text-sm">{t.continued}</div>
            <div className="flex gap-4 text-black"><div><span className="font-bold text-black">{t.page}</span> {pageNumber}</div></div>
        </div>
    );
};

const TableHeader = ({ lang }) => {
    const t = TEXT[lang];
    return (
        <thead>
            <tr className="bg-brand-dark text-white text-center">
                <th className="py-2 w-[5%] text-center align-middle">{t.no}</th>
                <th className="py-2 w-[35%] align-middle">{t.desc}</th>
                <th className="py-2 w-[10%] text-center align-middle">{t.img}</th>
                <th className="py-2 w-[8%] text-center align-middle">{t.qty}</th>
                <th className="py-2 w-[8%] text-center align-middle">{t.unit}</th>
                <th className="py-2 w-[12%] text-center align-middle">{t.price_unit}</th>
                <th className="py-2 w-[12%] text-center align-middle">{t.total_col}</th>
            </tr>
        </thead>
    );
};

const SummarySection = ({ q, grandTotalText, lang }) => {
    const t = TEXT[lang];
    const noteLines = (q.note || "").split('\n');
    return (
        <div className="mt-2 flex border border-gray-400 text-xs mb-2 bg-white text-black">
            <div className="flex-1 flex flex-col justify-between border-r border-gray-400">
                <div className="p-2 flex-1 pb-3 text-black">
                    <span className="font-bold text-red-600 block mb-1">{t.note_label}</span>
                    {noteLines.length > 0 && noteLines.some(l => l.trim() !== "") ? (
                        noteLines.map((line, idx) => (
                            <div key={idx} className="leading-tight text-black">{line}</div>
                        ))
                    ) : (
                        '-'
                    )}
                </div>
                <div className="bg-brand-dark text-white text-center font-bold h-7 flex items-center justify-center">{grandTotalText}</div>
            </div>
            <div className="w-[240px] text-black"><div className="flex justify-between p-1 border-b border-gray-400 bg-gray-100 px-2 text-black"><span className="text-black">{t.total_label}</span> <span className="text-black">{formatCurrency(q.total)}</span></div><div className="flex justify-between p-1 border-b border-gray-400 px-2 text-black"><span className="text-black">{t.discount_label}</span> <span className="text-red-600 font-bold">{formatCurrency(q.discount)}</span></div><div className="flex justify-between p-1 border-b border-gray-400 bg-gray-100 px-2 text-black"><span className="text-black">{t.after_discount_label}</span> <span className="text-black">{formatCurrency(q.afterDiscount)}</span></div><div className="flex justify-between p-1 border-b border-gray-400 px-2 text-black"><span className="text-black">{t.vat_label}</span> <span className="text-black">{formatCurrency(q.vat)}</span></div><div className="flex justify-between px-2 bg-brand-dark text-white items-center h-7"><span className="font-bold text-white">{t.net_total_label}</span> <span className="font-bold text-white">{formatCurrency(q.netTotal)}</span></div></div>
        </div>
    );
};

const SignatureSection = ({ q, signatures, lang }) => {
    const t = TEXT[lang];
    const salesName = q.issuerName || "";
    const salesNameNorm = salesName.replace(/\s+/g, ' ').trim();
    const salesSig = signatures ? (signatures[salesNameNorm] || null) : null;

    return (
        <div className="mt-2 bg-white text-black">
            <div className="text-xs text-right mb-8 text-black">{t.closing_text}</div>
            <div className="grid grid-cols-3 gap-4 text-xs text-center mb-4 text-black">
                <div>
                    <div className="w-3/4 mx-auto mb-2 flex flex-col justify-end items-center h-14">
                        <div className="h-10"></div>
                        <div className="w-full border-b border-dotted border-gray-400"></div>
                    </div>
                    <div className="mb-1 text-black font-bold">(....................................................)</div>
                    <div className="text-black">{t.approved_by}</div>
                    <div className="text-black">{t.date}........./........./.........</div>
                </div>

                <div></div>

                <div>
                    <div className="w-3/4 mx-auto mb-2 flex flex-col justify-end items-center h-14 relative">
                        {salesSig ? (
                            <img
                                src={salesSig}
                                crossOrigin="anonymous"
                                className="h-16 w-auto object-contain mb-[-10px] mix-blend-multiply z-10"
                                alt="Sales Sig"
                            />
                        ) : (
                            <div className="h-10"></div>
                        )}
                        <div className="w-full border-b border-dotted border-gray-400 z-0"></div>
                    </div>
                    <div className="mb-1 text-black font-bold">{salesName}</div>
                    <div className="text-black font-medium">{t.sales_pos} {q.issuerPhone}</div>
                    <div className="text-black">{t.date} {formatDate(q.date, lang) || "........./........./........."}</div>
                </div>
            </div>
        </div>
    );
};

const SupplementaryDisplay = ({ supp, lang }) => {
    const t = TEXT[lang];
    if (!supp) return null;
    const categories = [{ id: 'included', label: t.supp_included }, { id: 'warranty', label: t.supp_warranty }, { id: 'payment', label: t.supp_payment }];
    const categoryItems = categories.filter(cat => supp[cat.id] && supp[cat.id].length > 0);
    if (categoryItems.length === 0) return null;
    return (
        <div className="pdf-supp-container bg-white text-black">
            {categoryItems.map((cat) => (
                <div key={cat.id}>
                    <div className="font-bold text-black">{cat.label}</div>
                    <div className="pl-0">
                        {supp[cat.id].map((item, idx) => (
                            <div key={idx} className="text-gray-800 leading-tight">{idx + 1}. {item}</div>
                        ))}
                    </div>
                </div>
            ))}
        </div>
    );
};

const calculatePages = (q, isCompactMode = false) => {
    const lines = [...q.products];
    const chunks = [];

    if (lines.length === 0) {
        return [{ pageNumber: 1, items: [], isFirst: true, showTable: true, showSummary: true, showSignatures: true }];
    }

    const MAX_LINES_P1 = isCompactMode ? 52 : 40;
    const MAX_LINES_P2 = isCompactMode ? 64 : 50;
    const ITEM_LIMIT = isCompactMode ? 15 : 8;

    const WEIGHT_SUMMARY = isCompactMode ? 8 : 10;
    const WEIGHT_SIG = isCompactMode ? 12 : 14;
    let currentLines = [...lines];
    let pageNum = 1;

    const estimateItemLines = (item) => {
        const { text, supp } = parseDetailField(item.detail);
        const textLines = text ? text.split('\n').length : 0;
        let weight = isCompactMode ? 1.5 : 2;
        
        // Estimate lines for product title (description)
        const descLength = (item.description || "").length;
        const descLines = Math.max(1, Math.ceil(descLength / 35));
        if (descLines > 1) {
            weight += (descLines - 1);
        }
        
        weight += textLines;
        if (supp) { Object.values(supp).forEach(arr => weight += arr.length); }
        const minImageHeight = item.imageURL ? 5 : 0;
        return Math.max(weight, minImageHeight);
    };

    while (currentLines.length > 0) {
        const isFirst = pageNum === 1;
        const maxWeight = isFirst ? MAX_LINES_P1 : MAX_LINES_P2;
        let currentWeight = 0;
        let sliceCount = 0;

        for (let i = 0; i < currentLines.length; i++) {
            if (sliceCount >= ITEM_LIMIT) break;
            const itemWeight = estimateItemLines(currentLines[i]);
            if (currentWeight + itemWeight <= maxWeight) {
                currentWeight += itemWeight;
                sliceCount++;
            } else { break; }
        }

        if (sliceCount === 0 && currentLines.length > 0) { sliceCount = 1; }

        const slice = currentLines.slice(0, sliceCount);
        currentLines = currentLines.slice(sliceCount);
        const isLastItemBatch = currentLines.length === 0;

        let showSummaryHere = false;
        let showSigHere = false;
        let needsNewPageForSig = false;
        let needsNewPageForAll = false;

        if (isLastItemBatch) {
            const remaining = maxWeight - currentWeight;
            const SAFETY_BUFFER = isCompactMode ? 4 : 5;

            if (remaining >= (WEIGHT_SUMMARY + WEIGHT_SIG + SAFETY_BUFFER)) {
                showSummaryHere = true;
                showSigHere = true;
            }
            else if (remaining >= (WEIGHT_SUMMARY + SAFETY_BUFFER)) {
                showSummaryHere = true;
                needsNewPageForSig = true;
            }
            else {
                needsNewPageForAll = true;
            }
        }

        chunks.push({ pageNumber: pageNum, items: slice, isFirst: isFirst, showTable: true, showSummary: showSummaryHere, showSignatures: showSigHere });
        pageNum++;

        if (needsNewPageForAll) {
            chunks.push({ pageNumber: pageNum, items: [], isFirst: false, showTable: false, showSummary: true, showSignatures: true });
        }
        else if (needsNewPageForSig) {
            chunks.push({ pageNumber: pageNum, items: [], isFirst: false, showTable: false, showSummary: false, showSignatures: true });
        }
    }
    return chunks;
};

const QuotationSheet = ({ q, signatures, userPhotos, lang, isCompact = false }) => {
    const pages = useMemo(() => calculatePages(q, isCompact), [q, isCompact]);
    const grandTotalText = useMemo(() => ThaiNumberToText(q.netTotal, lang), [q.netTotal, lang]);
    const t = TEXT[lang];

    return (
        <div className={`print-content-fix bg-white text-black ${isCompact ? 'compact-mode-active' : ''}`}>
            {pages.map((page, index) => (
                <div key={index} className="a4-page print:transform-none print:scale-100 print:shadow-none print:m-0 print:w-full mb-4 mx-auto scale-[0.7] origin-top lg:scale-100 bg-white">
                    {page.isFirst ? (<><CompanyHeader lang={lang} /><CustomerDetail q={q} lang={lang} /><div className="text-xs mb-2 text-black"></div></>) : (<SmallInfo pageNumber={page.pageNumber} lang={lang} />)}

                    <div className="bg-white">
                        {page.showTable && (
                            <table className="pdf-table text-xs bg-white text-black">
                                <TableHeader lang={lang} />
                                <tbody>
                                    {page.items.map((p, i) => {
                                        const { text, supp } = parseDetailField(p.detail);
                                        const hasContent = (text && text.trim().length > 0) || (supp && Object.values(supp).flat().length > 0);
                                        return (
                                            <tr key={i} className="align-middle bg-white text-black">
                                                <td className="p-2 text-center align-middle text-black border-gray-400">{p.number}</td>
                                                <td className={`p-2 text-left ${hasContent ? 'align-top' : 'align-middle'} text-black border-gray-400`}>
                                                    <div className={`pdf-product-title ${hasContent ? 'mb-1' : 'mb-0'} text-black text-left`}>{p.description}</div>
                                                    {hasContent && (
                                                        <>
                                                            <div className="pdf-desc-text text-gray-800 text-left">
                                                                {text}
                                                            </div>
                                                            <SupplementaryDisplay supp={supp} lang={lang} />
                                                        </>
                                                    )}
                                                </td>
                                                <td className="p-1 text-center align-middle border-gray-400">
                                                    <div className="flex justify-center items-center h-full">
                                                        {p.imageURL && <img src={p.imageURL} alt="p" className="w-16 h-16 object-contain mx-auto" />}
                                                    </div>
                                                </td>
                                                <td className="p-2 text-center align-middle text-black border-gray-400">{p.quantity}</td>
                                                <td className="p-2 text-center align-middle text-black border-gray-400">{p.unit}</td>
                                                <td className="p-2 text-center align-middle text-black border-gray-400">{formatCurrency(p.unitPrice)}</td>
                                                <td className="p-2 text-center align-middle text-black border-gray-400">{formatCurrency(p.amount)}</td>
                                            </tr>
                                        );
                                    })}
                                </tbody>
                            </table>
                        )}
                    </div>
                    {page.showSummary && <SummarySection q={q} grandTotalText={grandTotalText} lang={lang} />}
                    {page.showSignatures && <SignatureSection q={q} signatures={signatures} lang={lang} />}
                    <div className="absolute bottom-4 right-8 text-[8px] text-gray-400">&copy; 2025 Quotation System By IT</div>
                </div>
            ))}
        </div>
    );
}

const Loading = ({ text }) => (
    <div className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-white/90 dark:bg-gray-900/90 backdrop-blur-sm no-print">
        <Loader2 className="animate-spin text-sky-600 dark:text-sky-400 mb-3" size={48} />
        <span className="text-gray-600 dark:text-gray-300 font-medium">{text || 'Loading...'}</span>
    </div>
);

const ThaiDatePicker = ({ value, onChange, lang }) => {
    const displayDate = useMemo(() => {
        if (!value) return "";
        return formatDate(value, lang);
    }, [value, lang]);

    return (
        <div className="relative w-full h-[46px]">
            <div className="absolute inset-0 z-0">
                <input type="text" value={displayDate} readOnly className="w-full h-full bg-white dark:bg-gray-700 p-3 rounded-xl border border-gray-200 dark:border-gray-600 text-gray-700 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 font-medium pl-10 pointer-events-none transition-colors" />
                <Calendar className="absolute left-3 top-3.5 text-blue-500 dark:text-blue-400" size={18} />
            </div>
            <input type="date" value={value || ''} onChange={(e) => onChange(e.target.value)} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10" />
        </div>
    );
};

const SearchableDropdown = ({ options, value, onChange, placeholder, labelKey = 'label', className, icon }) => {
    const [isOpen, setIsOpen] = useState(false);
    const [search, setSearch] = useState('');
    const [tempValue, setTempValue] = useState('');
    useEffect(() => { setSearch(value || ''); setTempValue(value || ''); }, [value]);
    const filtered = options.filter(opt => {
        const val = typeof opt === 'object' ? opt[labelKey] : opt;
        return val && val.toLowerCase().includes(tempValue.toLowerCase());
    });
    return (
        <div className="relative">
            <div className="relative">
                {icon && <div className="absolute left-4 top-3.5 pointer-events-none text-gray-400 dark:text-gray-500">{icon}</div>}
                <input type="text" value={tempValue} onChange={(e) => { setTempValue(e.target.value); setIsOpen(true); onChange(e.target.value); }} onFocus={() => setIsOpen(true)} onBlur={() => setTimeout(() => setIsOpen(false), 200)} placeholder={placeholder} className={`${className || 'bg-sky-50 dark:bg-gray-700 border-sky-100 dark:border-gray-600 focus:ring-sky-500 text-gray-900 dark:text-white'} w-full px-4 py-3.5 rounded-xl border focus:outline-none focus:ring-2 focus:border-transparent transition-all ${icon ? 'pl-12' : ''}`} />
                <div className="absolute right-4 top-3.5 pointer-events-none text-gray-400 dark:text-gray-500"><ChevronDown size={20} className={`transition-transform ${isOpen ? 'rotate-180' : ''}`} /></div>
            </div>
            {isOpen && filtered.length > 0 && (
                <div className="absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 rounded-xl shadow-xl border border-gray-100 dark:border-gray-700 max-h-56 overflow-y-auto overflow-x-hidden">
                    {filtered.map((opt, idx) => {
                        const val = typeof opt === 'object' ? opt[labelKey] : opt;
                        return (<div key={idx} className="px-4 py-3 hover:bg-sky-50 dark:hover:bg-gray-700 cursor-pointer text-sm text-gray-700 dark:text-gray-200 border-b border-gray-50 dark:border-gray-700 last:border-0 transition-colors" onClick={() => { setTempValue(val); setSearch(val); onChange(val, opt); setIsOpen(false); }}>{val}</div>);
                    })}
                </div>
            )}
        </div>
    );
};

const SupplementaryModal = ({ isOpen, onClose, initialData, onSave, suggestions, lang }) => {
    const [data, setData] = useState({ included: [], warranty: [], payment: [] });
    const [activeField, setActiveField] = useState(null);
    const t = TEXT[lang];

    useEffect(() => {
        if (isOpen) { setData({ included: initialData?.included || Array(3).fill(''), warranty: initialData?.warranty || Array(3).fill(''), payment: initialData?.payment || Array(3).fill('') }); }
    }, [isOpen, initialData]);

    const handleChange = (catId, index, value) => {
        const newData = { ...data };
        const newArr = [...(newData[catId] || [])];
        while (newArr.length <= index) newArr.push('');
        newArr[index] = value;
        newData[catId] = newArr;
        setData(newData);
    };

    const handleSelect = (catId, index, value) => {
        handleChange(catId, index, value);
        setActiveField(null);
    };

    const handleSave = () => { onSave({ included: data.included.filter(s => s.trim()), warranty: data.warranty.filter(s => s.trim()), payment: data.payment.filter(s => s.trim()) }); onClose(); };

    if (!isOpen) return null;
    return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4">
            <div className="bg-white dark:bg-gray-800 rounded-2xl shadow-2xl w-full max-w-2xl max-h-[90vh] flex flex-col overflow-hidden transition-colors">
                <div className="px-6 py-4 border-b border-gray-100 dark:border-gray-700 flex justify-between items-center bg-gray-50 dark:bg-gray-900"><h3 className="text-lg font-bold text-gray-800 dark:text-white flex items-center gap-2"><Settings size={20} className="text-blue-600 dark:text-blue-400" /> {t.supp_modal_title}</h3><button onClick={onClose} className="text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300"><X size={24} /></button></div>
                <div className="flex-1 overflow-y-auto p-6 space-y-6">
                    {[{ id: 'included', label: t.supp_included }, { id: 'warranty', label: t.supp_warranty }, { id: 'payment', label: t.supp_payment }].map(cat => (
                        <div key={cat.id} className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4 shadow-sm transition-colors">
                            <h4 className="font-bold text-blue-700 dark:text-blue-400 mb-3 border-b border-gray-100 dark:border-gray-700 pb-2">{cat.label}</h4>
                            <div className="space-y-3">
                                {[0, 1, 2].map(idx => {
                                    const val = data[cat.id]?.[idx] || '';
                                    const isFocused = activeField?.cat === cat.id && activeField?.idx === idx;
                                    const catSuggestions = suggestions && suggestions[cat.id] ? suggestions[cat.id] : [];
                                    const filtered = catSuggestions.filter(s => s && s.toLowerCase().includes(val.toLowerCase()) && s !== val);

                                    return (
                                        <div key={idx} className="flex flex-col gap-1 relative">
                                            <div className="flex items-center gap-3">
                                                <span className="text-xs text-gray-400 dark:text-gray-500 font-mono w-4 text-right">{idx + 1}.</span>
                                                <div className="flex-1 relative">
                                                    <input
                                                        type="text"
                                                        maxLength={68}
                                                        value={val}
                                                        onFocus={() => setActiveField({ cat: cat.id, idx })}
                                                        onBlur={() => {
                                                            setTimeout(() => {
                                                                setActiveField(current => {
                                                                    if (current && current.cat === cat.id && current.idx === idx) {
                                                                        return null;
                                                                    }
                                                                    return current;
                                                                });
                                                            }, 200);
                                                        }}
                                                        onChange={(e) => handleChange(cat.id, idx, e.target.value)}
                                                        placeholder={`${t.supp_ph} ${idx + 1}...`}
                                                        className={`w-full bg-gray-50 dark:bg-gray-700 border rounded-lg px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-400 focus:bg-white dark:focus:bg-gray-600 transition-all ${val.length >= 68 ? 'border-red-300 dark:border-red-500 ring-2 ring-red-100 dark:ring-red-900' : 'border-gray-200 dark:border-gray-600'}`}
                                                    />
                                                    {isFocused && filtered.length > 0 && (
                                                        <div
                                                            className="absolute z-20 w-full left-0 mt-1 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-xl max-h-48 overflow-y-auto"
                                                            onMouseDown={(e) => { e.preventDefault(); e.stopPropagation(); }}
                                                        >
                                                            {filtered.map((opt, i) => (
                                                                <div
                                                                    key={i}
                                                                    className="px-3 py-2.5 text-sm text-gray-700 dark:text-gray-200 hover:bg-blue-50 dark:hover:bg-gray-700 cursor-pointer border-b border-gray-50 dark:border-gray-700 last:border-0 transition-colors"
                                                                    onMouseDown={(e) => {
                                                                        e.preventDefault();
                                                                        e.stopPropagation();
                                                                        handleSelect(cat.id, idx, opt);
                                                                    }}
                                                                    onClick={() => handleSelect(cat.id, idx, opt)}
                                                                >
                                                                    {opt}
                                                                </div>
                                                            ))}
                                                        </div>
                                                    )}
                                                </div>
                                            </div>
                                            <div className={`text-[10px] text-right pr-1 ${val.length >= 68 ? 'text-red-500 dark:text-red-400 font-bold' : 'text-gray-400 dark:text-gray-500'}`}>
                                                {val.length}/68 {val.length >= 68 && '(Limit)'}
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>
                        </div>
                    ))}
                </div>
                <div className="px-6 py-4 border-t border-gray-100 dark:border-gray-700 bg-gray-50 dark:bg-gray-900 flex justify-end gap-3"><button onClick={onClose} className="px-4 py-2 rounded-lg text-gray-600 dark:text-gray-300 font-medium hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">{t.cancel}</button><button onClick={handleSave} className="px-6 py-2 rounded-lg bg-blue-600 text-white font-bold shadow-md hover:bg-blue-700 active:scale-95 transition-all">{t.save_item}</button></div>
            </div>
        </div>
    );
};

const SignaturePadComponent = ({ onSave, lang }) => {
    const canvasRef = useRef(null);
    const signaturePadRef = useRef(null);
    const t = TEXT[lang];

    useEffect(() => {
        if (canvasRef.current) {
            signaturePadRef.current = new SignaturePad(canvasRef.current, {
                backgroundColor: 'rgba(255, 255, 255, 0)',
                penColor: 'rgb(20, 50, 150)'
            });

            const resizeCanvas = () => {
                const canvas = canvasRef.current;
                const ratio = Math.max(window.devicePixelRatio || 1, 1);
                canvas.width = canvas.offsetWidth * ratio;
                canvas.height = canvas.offsetHeight * ratio;
                canvas.getContext("2d").scale(ratio, ratio);
                signaturePadRef.current.clear();
            };
            window.addEventListener("resize", resizeCanvas);
            resizeCanvas();
            return () => window.removeEventListener("resize", resizeCanvas);
        }
    }, []);

    const handleClear = () => signaturePadRef.current?.clear();
    const handleUndo = () => {
        const data = signaturePadRef.current?.toData();
        if (data && data.length > 0) {
            data.pop();
            signaturePadRef.current?.fromData(data);
        }
    };
    const handleSave = () => {
        if (signaturePadRef.current?.isEmpty()) {
            return premiumAlert.warn(TEXT[lang].alert_title, t.please_sign);
        }
        const dataUrl = signaturePadRef.current.toDataURL('image/png');
        onSave(dataUrl);
    };

    return (
        <div className="space-y-4">
            <div className="signature-pad-container">
                <canvas ref={canvasRef} className="signature-pad-canvas" />
                <div className="absolute top-2 right-2 px-2 py-1 bg-gray-100/50 dark:bg-gray-800/50 rounded text-[10px] text-gray-500 font-bold pointer-events-none uppercase tracking-widest">{t.sig_here}</div>
            </div>
            <div className="flex justify-between items-center">
                <div className="flex gap-2">
                    <button onClick={handleUndo} className="px-4 py-2 text-xs font-bold text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 border border-gray-200 dark:border-gray-700 rounded-xl transition-all active:scale-95">{t.undo}</button>
                    <button onClick={handleClear} className="px-4 py-2 text-xs font-bold text-red-500 hover:text-red-700 border border-red-100 dark:border-red-900/30 rounded-xl transition-all active:scale-95">{t.clear}</button>
                </div>
                <button onClick={handleSave} className="px-8 py-2.5 bg-blue-600 text-white rounded-2xl font-black text-sm shadow-xl shadow-blue-500/20 hover:bg-blue-700 active:scale-[0.98] transition-all">{t.save_sig}</button>
            </div>
        </div>
    );
};

const UserProfileModal = ({ isOpen, onClose, user, currentSignature, currentPhoto, onUpdate, lang }) => {
    const [isDrawing, setIsDrawing] = useState(false);
    const [loading, setLoading] = useState(false);
    const t = TEXT[lang];

    if (!isOpen) return null;

    const handleDrawSave = async (dataUrl) => {
        setLoading(true);
        // Convert Base64 to Blob
        const blob = await (await fetch(dataUrl)).blob();
        const file = new File([blob], "signature.png", { type: "image/png" });

        google.script.run.withSuccessHandler(res => {
            setLoading(false);
            if (res.success) {
                onUpdate(res.url);
                setIsDrawing(false);
                premiumAlert.success(t.success_title, t.saved_success);
            } else {
                premiumAlert.error(t.error_title, res.message);
            }
        }).updateUserSignatureAPI(user.username, file);
    };

    return (
        <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/60 backdrop-blur-md p-4 animate-in fade-in duration-300">
            <div className="bg-white dark:bg-gray-900 rounded-[40px] shadow-2xl w-full max-w-lg overflow-hidden flex flex-col border border-white/10 relative">
                {loading && <Loading text={t.loading_msg} />}

                <div className="p-8 border-b border-gray-100 dark:border-gray-800 flex justify-between items-center bg-gray-50/50 dark:bg-gray-800/50">
                    <div className="flex items-center gap-4">
                        <div className="w-12 h-12 rounded-2xl bg-blue-100 dark:bg-blue-900/50 flex items-center justify-center text-blue-600 dark:text-blue-400">
                            <Settings size={24} />
                        </div>
                        <div>
                            <h3 className="text-xl font-black text-gray-900 dark:text-white leading-none">{t.sig_settings}</h3>
                            <p className="text-[10px] text-gray-400 dark:text-gray-500 font-bold uppercase tracking-widest mt-1">{t.sig_manage_sub}</p>
                        </div>
                    </div>
                    <button onClick={onClose} className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-white transition-colors"><X size={28} /></button>
                </div>

                <div className="p-8">
                    {!isDrawing ? (
                        <div className="space-y-8 animate-in zoom-in-95 duration-300">
                            <div className="flex flex-col items-center gap-6">
                                <div className="flex items-center gap-8 justify-center">
                                    {/* Profile Photo */}
                                    <div className="flex flex-col items-center gap-2">
                                        <span className="text-[10px] text-gray-400 font-bold uppercase tracking-wider">รูปโปรไฟล์ (Profile)</span>
                                        <div className="w-24 h-24 rounded-full overflow-hidden border-2 border-blue-500/20 bg-white shadow-sm flex items-center justify-center">
                                            {currentPhoto ? (
                                                <img src={currentPhoto} className="w-full h-full object-cover rounded-full" alt="Profile" />
                                            ) : (
                                                <UserCircle size={64} className="text-gray-300 dark:text-gray-600" />
                                            )}
                                        </div>
                                    </div>
                                    
                                    {/* Signature Preview */}
                                    <div className="flex flex-col items-center gap-2">
                                        <span className="text-[10px] text-gray-400 font-bold uppercase tracking-wider">ลายเซ็น (Signature)</span>
                                        <div className="signature-preview-circle flex items-center justify-center p-2 relative group w-24 h-24 rounded-full border-2 border-blue-500/20 bg-white shadow-sm">
                                            {currentSignature ? (
                                                <img src={currentSignature} className="max-w-full max-h-full object-contain mix-blend-multiply dark:invert-0" alt="Sig" />
                                            ) : (
                                                <div className="text-gray-300 dark:text-gray-600 italic text-[10px]">{t.not_found}</div>
                                            )}
                                        </div>
                                    </div>
                                </div>
                                <div className="text-center">
                                    <h4 className="font-black text-lg text-gray-900 dark:text-white mb-1">{user.name}</h4>
                                    <p className="text-xs text-gray-500 dark:text-gray-400 font-medium">{user.role} | {user.username}</p>
                                </div>
                            </div>

                            <button onClick={() => setIsDrawing(true)} className="w-full flex items-center justify-center gap-3 p-6 bg-blue-50 dark:bg-blue-900/20 rounded-3xl border border-blue-100 dark:border-blue-800 hover:bg-blue-100 dark:hover:bg-blue-900/40 transition-all group">
                                <div className="w-10 h-10 rounded-xl bg-white dark:bg-gray-700 shadow-sm flex items-center justify-center text-blue-600 group-hover:scale-110 transition-transform">
                                    <Edit size={20} />
                                </div>
                                <span className="text-sm font-black text-blue-700 dark:text-blue-300 uppercase tracking-widest">{t.draw_live}</span>
                            </button>
                        </div>
                    ) : (
                        <div className="space-y-6 animate-in slide-in-from-right duration-300">
                            <SignaturePadComponent onSave={handleDrawSave} lang={lang} />
                            <button onClick={() => setIsDrawing(false)} className="w-full text-xs font-bold text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors">{t.cancel}</button>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
};


const LoginScreen = ({ onLogin, lang, setLang, theme, setTheme }) => {
    const [userInputValue, setUserInputValue] = useState('');
    const [pass, setPass] = useState('');
    const [showPass, setShowPass] = useState(false);
    const [loading, setLoading] = useState(false);

    const t = TEXT[lang];

    const handleLoginSubmit = (e) => {
        e.preventDefault();
        if (!userInputValue.trim()) return premiumAlert.warn(t.alert_title, t.please_select_user);
        setLoading(true);
        google.script.run.withSuccessHandler(res => {
            setLoading(false);
            if (res.success) onLogin(res);
            else premiumAlert.error(t.error_title, res.message);
        }).loginUser(userInputValue.trim(), pass);
    };

    return (
        <div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-950 transition-colors relative overflow-hidden">
            {/* Background Decorations */}
            <div className="absolute top-0 -left-4 w-72 h-72 bg-blue-400 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob"></div>
            <div className="absolute top-0 -right-4 w-72 h-72 bg-indigo-400 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob animation-delay-2000"></div>
            <div className="absolute -bottom-8 left-20 w-72 h-72 bg-sky-400 rounded-full mix-blend-multiply filter blur-xl opacity-20 animate-blob animation-delay-4000"></div>

            <div className="absolute top-4 right-4 z-50 flex items-center gap-2">
                <ThemeToggle theme={theme} setTheme={setTheme} />
                <LanguageToggle lang={lang} setLang={setLang} />
            </div>

            <div className="w-full max-w-4xl flex flex-col lg:flex-row h-full lg:h-[600px] shadow-2xl rounded-3xl overflow-hidden login-glass z-10 mx-4">
                {/* Left Side: Branding */}
                <div className="w-full lg:w-1/2 bg-gradient-to-br from-blue-700 via-blue-600 to-indigo-800 p-12 text-white flex flex-col justify-between relative overflow-hidden">
                    <div className="absolute top-0 right-0 -mr-16 -mt-16 w-64 h-64 bg-white/10 rounded-full blur-3xl"></div>
                    <div className="absolute bottom-0 left-0 -ml-16 -mb-16 w-64 h-64 bg-indigo-900/50 rounded-full blur-3xl"></div>

                    <div className="relative z-10">
                        <div className="flex items-center gap-3 mb-10">
                            <div className="w-10 h-10 rounded-xl bg-white/20 backdrop-blur-md flex items-center justify-center">
                                <FileText size={24} className="text-white" />
                            </div>
                            <span className="font-black text-xl tracking-tighter">PAVARA PROS</span>
                        </div>

                        <h1 className="text-4xl lg:text-5xl font-black mb-6 leading-tight">
                            {t.quotation_title}
                        </h1>
                        <p className="text-blue-100 text-lg font-light leading-relaxed max-w-xs">
                            {t.login_sub}
                        </p>
                    </div>

                </div>

                {/* Right Side: Form */}
                <div className="w-full lg:w-1/2 bg-white/80 dark:bg-gray-900/80 backdrop-blur-md p-8 sm:p-12 flex flex-col justify-center">
                    <div className="max-w-sm mx-auto w-full">
                        <div className="mb-8">
                            <h2 className="text-3xl font-black text-gray-900 dark:text-white mb-2">{t.login_welcome}</h2>
                            <p className="text-gray-500 dark:text-gray-400 text-sm">{t.login_sub}</p>
                        </div>

                        <form onSubmit={handleLoginSubmit} className="space-y-5">
                            <div className="space-y-2">
                                <label className="text-xs font-black uppercase tracking-widest text-gray-400 dark:text-gray-500 ml-1">{t.username}</label>
                                <div className="relative group">
                                    <div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-gray-400 group-focus-within:text-blue-500 transition-colors">
                                        <User size={18} />
                                    </div>
                                    <input
                                        type="text"
                                        value={userInputValue}
                                        onChange={e => setUserInputValue(e.target.value)}
                                        className="block w-full pl-11 pr-4 py-3.5 bg-gray-50 dark:bg-gray-800/50 border border-gray-100 dark:border-gray-700 rounded-2xl focus:ring-2 focus:ring-blue-500 focus:bg-white dark:focus:bg-gray-800 transition-all text-sm font-medium text-gray-900 dark:text-white outline-none"
                                        placeholder="Username"
                                        required
                                    />
                                </div>
                            </div>

                            <div className="space-y-2">
                                <label className="text-xs font-black uppercase tracking-widest text-gray-400 dark:text-gray-500 ml-1">{t.password}</label>
                                <div className="relative group">
                                    <div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none text-gray-400 group-focus-within:text-blue-500 transition-colors">
                                        <Lock size={18} />
                                    </div>
                                    <input
                                        type={showPass ? "text" : "password"}
                                        value={pass}
                                        onChange={e => setPass(e.target.value)}
                                        className="block w-full pl-11 pr-12 py-3.5 bg-gray-50 dark:bg-gray-800/50 border border-gray-100 dark:border-gray-700 rounded-2xl focus:ring-2 focus:ring-blue-500 focus:bg-white dark:focus:bg-gray-800 transition-all text-sm font-medium text-gray-900 dark:text-white outline-none"
                                        placeholder="••••••••"
                                        required
                                    />
                                    <button type="button" onClick={() => setShowPass(!showPass)} className="absolute inset-y-0 right-0 pr-4 flex items-center text-gray-400 hover:text-blue-500 transition-colors">
                                        {showPass ? <EyeOff size={18} /> : <Eye size={18} />}
                                    </button>
                                </div>
                            </div>

                            <button
                                disabled={loading}
                                className="w-full mt-6 py-4 px-6 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white rounded-2xl font-black text-sm shadow-xl shadow-blue-500/20 transition-all active:scale-[0.98] disabled:opacity-70 disabled:cursor-not-allowed flex items-center justify-center gap-2 group"
                            >
                                {loading ? (
                                    <Loader2 className="animate-spin" size={20} />
                                ) : (
                                    <>
                                        <span>{t.login_btn}</span>
                                    </>
                                )}
                            </button>
                        </form>
                    </div>
                </div>
            </div>

            <div className="absolute bottom-6 text-[10px] text-gray-400 dark:text-gray-600 font-bold uppercase tracking-[0.3em]">
                &copy; 2024 Pavara Prosperity Co.,Ltd. All Rights Reserved.
            </div>
        </div>
    );
};

const MemoizedQuotationCard = React.memo(({ q, idx, lang, onView, onEdit, onDelete, isAdmin, user, saveContextAndNavigate }) => {
    const t = TEXT[lang];
    return (
        <div
            onClick={() => saveContextAndNavigate(onView, q)}
            className="group quotation-card relative bg-white dark:bg-gray-900 p-5 rounded-[32px] border border-gray-100 dark:border-gray-800 hover:border-blue-500 dark:hover:border-blue-500/50 flex flex-col h-full shadow-sm cursor-pointer"
            style={{ animationDelay: `${idx * 50}ms` }}
        >
            <div className="flex justify-between items-start mb-4">
                <div className="flex-1 min-w-0 pr-3">
                    <div className="flex items-center gap-2 mb-2">
                        <span className="text-[9px] font-black text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/30 px-2 py-0.5 rounded-full uppercase tracking-widest border border-blue-100 dark:border-blue-900/30">
                            {q.quotationID}
                        </span>
                    </div>
                    <h3 className="font-black text-lg text-gray-900 dark:text-white leading-tight group-hover:text-blue-600 transition-colors quotation-card-title">
                        {q.customerName || "Untitled Proposal"}
                    </h3>
                </div>
                {(isAdmin || q.createdBy === user.name) && (
                    <div className="flex gap-2" onClick={(e) => e.stopPropagation()}>
                        <button
                            onClick={() => saveContextAndNavigate(onEdit, q)}
                            className="w-9 h-9 flex items-center justify-center bg-gray-50 dark:bg-gray-800 text-gray-400 hover:bg-blue-600 hover:text-white rounded-xl transition-all active:scale-[0.9] shadow-sm"
                            title={t.edit_title}
                        >
                            <Edit size={16} />
                        </button>
                        <button
                            onClick={() => onDelete(q)}
                            className="w-9 h-9 flex items-center justify-center bg-gray-50 dark:bg-gray-800 text-gray-400 hover:bg-red-600 hover:text-white rounded-xl transition-all active:scale-[0.9] shadow-sm"
                            title={t.delete_btn || "Delete"}
                        >
                            <Trash2 size={16} />
                        </button>
                    </div>
                )}
            </div>

            <div className="space-y-2 mb-6">
                <div className="flex items-center justify-between p-2.5 bg-gray-50/50 dark:bg-gray-800/30 rounded-xl">
                    <span className="text-[8px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.date_label}</span>
                    <span className="text-[11px] font-bold text-gray-700 dark:text-gray-300 flex items-center gap-1.5"><Calendar size={11} /> {formatDate(q.date, lang)}</span>
                </div>
                <div className="flex items-center justify-between p-2.5 bg-gray-50/50 dark:bg-gray-800/30 rounded-xl">
                    <span className="text-[8px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.by_label}</span>
                    <span className="text-[11px] font-bold text-gray-700 dark:text-gray-300 truncate flex items-center gap-1.5 max-w-[120px]"><User size={11} /> {q.issuerName}</span>
                </div>
            </div>

            <div className="mt-auto pt-4 border-t border-gray-50 dark:border-gray-800/50">
                <p className="text-[8px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest mb-1">{t.net_total_label}</p>
                <div className="flex items-baseline gap-1">
                    <span className="text-sm font-black text-emerald-600 dark:text-emerald-400">฿</span>
                    <span className="text-2xl font-black text-emerald-600 dark:text-emerald-400 tracking-tight">
                        {q.netTotal.toLocaleString('th-TH', { minimumFractionDigits: 2 })}
                    </span>
                </div>
            </div>
        </div>
    );
});

const DashboardScreen = ({ quotations, onCreate, onView, onEdit, onDelete, user, onLogout, issuers, userPhotos, signatures, restoreState, onSaveState, lang, setLang, theme, setTheme }) => {
    const [search, setSearch] = useState(restoreState?.search || '');
    const [filterStart, setFilterStart] = useState(restoreState?.filterStart || '');
    const [filterEnd, setFilterEnd] = useState(restoreState?.filterEnd || '');
    const [filterIssuer, setFilterIssuer] = useState(restoreState?.filterIssuer || '');
    const [isSidebarOpen, setIsSidebarOpen] = useState(false);
    const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);

    const scrollRef = useRef(null);
    const t = TEXT[lang];

    const normName = user?.name ? user.name.replace(/\s+/g, ' ').trim() : "";
    const activePhoto = userPhotos ? (userPhotos[normName] || user?.photo_url || "") : (user?.photo_url || "");
    const activeSig = signatures ? (signatures[normName] || user?.signature || "") : (user?.signature || "");
    const isAdmin = String(user.role).toLowerCase() === 'admin';

    const activeIssuers = useMemo(() => {
        const names = quotations.map(q => q.issuerName).filter(name => name && name.trim() !== "");
        return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b, 'th'));
    }, [quotations]);


    useLayoutEffect(() => {
        if (restoreState?.scrollY !== undefined && scrollRef.current) {
            const timer = setTimeout(() => {
                if (scrollRef.current) scrollRef.current.scrollTop = restoreState.scrollY;
            }, 0);
            return () => clearTimeout(timer);
        }
    }, []);

    const filtered = useMemo(() => {
        return quotations.filter(q => {
            if (!isAdmin && q.createdBy !== user.name) return false;
            if (isAdmin && filterIssuer && q.issuerName !== filterIssuer) return false;
            const matchesSearch = (q.customerName || "").toLowerCase().includes(search.toLowerCase()) || (q.quotationID || "").toLowerCase().includes(search.toLowerCase());
            let matchesDate = true;
            if (filterStart) matchesDate = matchesDate && (q.date >= filterStart);
            if (filterEnd) matchesDate = matchesDate && (q.date <= filterEnd);
            return matchesSearch && matchesDate;
        });
    }, [quotations, search, filterStart, filterEnd, filterIssuer, user, isAdmin]);

    const saveContextAndNavigate = (callback, arg) => {
        onSaveState({ search, filterStart, filterEnd, filterIssuer, scrollY: scrollRef.current ? scrollRef.current.scrollTop : 0 });
        callback(arg);
    };

    return (
        <div className="flex h-screen bg-[#f8fafc] dark:bg-gray-950 transition-colors relative overflow-hidden">
            {isSidebarOpen && <div className="fixed inset-0 bg-black/50 backdrop-blur-md z-40 transition-opacity duration-300" onClick={() => setIsSidebarOpen(false)} />}
            <div className={`fixed inset-y-0 left-0 w-80 bg-white dark:bg-gray-900 shadow-2xl z-50 transform sidebar-transition ${isSidebarOpen ? 'translate-x-0' : '-translate-x-full'}`}>
                <div className="h-full flex flex-col">
                    <div className="p-8 border-b border-gray-100 dark:border-gray-800">
                        <div className="flex items-center gap-4 mb-8">
                            <div className="w-12 h-12 rounded-2xl bg-gradient-to-br from-blue-600 to-indigo-600 flex items-center justify-center text-white shadow-xl shadow-blue-500/20"><FileText size={26} strokeWidth={2.5} /></div>
                            <div><h2 className="font-black text-xl text-gray-900 dark:text-white leading-none tracking-tight">{t.quotation_title}</h2><p className="text-[10px] text-gray-400 dark:text-gray-500 font-bold uppercase tracking-widest mt-1">{t.version} 2.0 Central</p></div>
                        </div>
                        <button onClick={() => { setIsSidebarOpen(false); onCreate(); }} className="w-full py-4 px-6 bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 text-white rounded-2xl font-black text-sm flex items-center justify-center gap-3 shadow-xl shadow-blue-500/30 transition-all active:scale-[0.97] hover:-translate-y-0.5"><Plus size={22} strokeWidth={3} /> {t.create_title}</button>
                    </div>
                    <div className="flex-1 overflow-y-auto px-8 py-6 space-y-8 scrollbar-hide">
                        <div className="space-y-4">
                            <h3 className="text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-[0.2em] px-1">{t.filter_by_date}</h3>
                            <div className="space-y-4">
                                <div><label className="block text-[10px] font-bold text-gray-400 dark:text-gray-500 mb-2 ml-1">{t.filter_start}</label><div className="relative"><Calendar className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400" size={16} /><input type="date" value={filterStart} onChange={e => setFilterStart(e.target.value)} className="w-full pl-12 pr-4 py-3 bg-gray-50 dark:bg-gray-800/50 rounded-2xl text-sm border-none focus:ring-2 focus:ring-blue-500 dark:text-white shadow-inner font-medium" /></div></div>
                                <div><label className="block text-[10px] font-bold text-gray-400 dark:text-gray-500 mb-2 ml-1">{t.filter_end}</label><div className="relative"><Calendar className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400" size={16} /><input type="date" value={filterEnd} onChange={e => setFilterEnd(e.target.value)} className="w-full pl-12 pr-4 py-3 bg-gray-50 dark:bg-gray-800/50 rounded-2xl text-sm border-none focus:ring-2 focus:ring-blue-500 dark:text-white shadow-inner font-medium" /></div></div>
                            </div>
                        </div>
                        {isAdmin && (
                            <div className="space-y-4">
                                <h3 className="text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-[0.2em] px-1">{t.filter_issuer}</h3>
                                <div className="relative"><User className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400" size={16} /><select value={filterIssuer} onChange={e => setFilterIssuer(e.target.value)} className="w-full pl-12 pr-4 py-3 bg-gray-50 dark:bg-gray-800/50 rounded-2xl text-sm border-none focus:ring-2 focus:ring-blue-500 dark:text-white shadow-inner font-medium appearance-none"><option value="">{t.all_issuers}</option>{activeIssuers.map(name => <option key={name} value={name}>{name}</option>)}</select><ChevronDown className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none" size={16} /></div>
                            </div>
                        )}
                    </div>
                    <div className="p-8 border-t border-gray-100 dark:border-gray-800 space-y-6">
                        <div className="flex items-center justify-between px-2"><ThemeToggle theme={theme} setTheme={setTheme} /><LanguageToggle lang={lang} setLang={setLang} /></div>
                        <div className="flex items-center gap-4 p-4 bg-gray-50 dark:bg-gray-800/80 rounded-3xl border border-gray-100 dark:border-gray-700 shadow-sm group relative">
                            <div className="w-12 h-12 rounded-2xl bg-blue-100 dark:bg-blue-900/50 flex items-center justify-center text-blue-600 dark:text-blue-300 shadow-inner group-hover:scale-105 transition-transform cursor-pointer overflow-hidden" onClick={() => onSaveState({ showProfile: true })}>{activePhoto ? <img src={activePhoto} className="w-full h-full object-cover bg-white" alt="avatar" /> : (activeSig ? <img src={activeSig} className="w-full h-full object-contain mix-blend-multiply dark:invert-0 bg-white" alt="avatar" /> : <UserCircle size={28} strokeWidth={1.5} />)}<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 flex items-center justify-center transition-opacity"><Edit size={16} className="text-white" /></div></div>
                            <div className="flex-1 min-w-0"><p className="text-sm font-black text-gray-900 dark:text-white truncate leading-none mb-1">{user.name}</p><div className="flex items-center gap-1.5"><div className="w-1.5 h-1.5 rounded-full bg-emerald-500"></div><p className="text-[10px] text-gray-500 dark:text-gray-400 font-bold uppercase tracking-wider">{user.role}</p></div></div>
                            <button onClick={onLogout} className="p-2.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-xl transition-all active:scale-90"><LogOut size={20} /></button>
                        </div>
                    </div>
                </div>
            </div>
            <div className="flex-1 flex flex-col overflow-hidden">
                <header className="h-24 flex items-center justify-between px-8 bg-white/70 dark:bg-gray-950/70 backdrop-blur-2xl border-b border-gray-100 dark:border-gray-900 sticky top-0 z-30 transition-all">
                    <div className="flex items-center gap-6"><button onClick={() => setIsSidebarOpen(true)} className="p-3 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-2xl transition-all active:scale-95 shadow-sm"><LucideIcons.Menu size={24} strokeWidth={2.5} /></button><div className="flex flex-col"><h1 className="text-2xl font-black text-gray-900 dark:text-white tracking-tight lg:block hidden">{t.dash_title}</h1><h1 className="text-xl font-black text-gray-900 dark:text-white tracking-tight lg:hidden">{t.dash_title}</h1><p className="text-[11px] text-gray-400 font-bold uppercase tracking-widest mt-0.5">{t.overview_reports}</p></div></div>
                    <div className="flex-1 max-w-xl mx-8 hidden md:block"><div className="relative group"><Search className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400 group-focus-within:text-blue-500 transition-colors" size={18} /><input type="text" placeholder={`${t.search}...`} value={search} onChange={e => setSearch(e.target.value)} className="w-full pl-12 pr-4 py-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-100 dark:border-gray-700 rounded-2xl text-sm font-medium focus:ring-2 focus:ring-blue-500 focus:bg-white dark:text-white transition-all shadow-sm placeholder-gray-400" /></div></div>
                </header>
                <header className="md:hidden h-20 px-8 flex items-center bg-white/70 dark:bg-gray-950/70 backdrop-blur-2xl border-b border-gray-100 dark:border-gray-900 sticky top-24 z-20"><div className="relative group w-full"><Search className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-400" size={18} /><input type="text" placeholder={`${t.search}...`} value={search} onChange={e => setSearch(e.target.value)} className="w-full pl-12 pr-4 py-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-100 dark:border-gray-700 rounded-2xl text-sm font-medium dark:text-white" /></div></header>
                <main className="flex-1 overflow-y-auto p-6 sm:p-10 scroll-smooth" ref={scrollRef} style={{ willChange: 'transform', transform: 'translateZ(0)' }}>
                    <div className="max-w-full mx-auto">
                        {filtered.length === 0 ? (
                            <div className="flex flex-col items-center justify-center py-32 text-gray-400 bg-white dark:bg-gray-900/50 rounded-[40px] border border-dashed border-gray-200 dark:border-gray-800 animate-in fade-in zoom-in duration-500"><div className="w-24 h-24 rounded-[32px] bg-gray-50 dark:bg-gray-800 flex items-center justify-center mb-6 opacity-50"><Search size={48} strokeWidth={1.5} className="text-gray-400" /></div><p className="text-xl font-bold text-gray-900 dark:text-white mb-2">{t.not_found}</p><p className="text-sm text-gray-500 font-medium">{t.search_tip}</p></div>
                        ) : (
                            <>
                                {/* Card View (Mobile & Tablet) */}
                                <div className="grid grid-cols-1 sm:grid-cols-2 lg:hidden gap-6 animate-in fade-in slide-in-from-bottom-6 duration-700">
                                    {filtered.map((q, idx) => (
                                        <MemoizedQuotationCard key={q.quotationID} q={q} idx={idx} lang={lang} onView={onView} onEdit={onEdit} onDelete={onDelete} isAdmin={isAdmin} user={user} saveContextAndNavigate={saveContextAndNavigate} />
                                    ))}
                                </div>

                                {/* Table View (Desktop) */}
                                <div className="hidden lg:block bg-white dark:bg-gray-900 rounded-[32px] border border-gray-100 dark:border-gray-800 shadow-sm overflow-hidden animate-in fade-in slide-in-from-bottom-6 duration-700">
                                    <div className="overflow-x-auto">
                                        <table className="w-full text-left border-collapse">
                                            <thead>
                                                <tr className="border-b border-gray-100 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-800/30">
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.doc_no}</th>
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.cust_info}</th>
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.date_label}</th>
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.by_label}</th>
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest">{t.net_total_label}</th>
                                                    <th className="py-5 px-6 text-[10px] font-black text-gray-400 dark:text-gray-500 uppercase tracking-widest text-right"></th>
                                                </tr>
                                            </thead>
                                            <tbody className="divide-y divide-gray-100 dark:divide-gray-800/50">
                                                {filtered.map((q) => {
                                                    const canEdit = isAdmin || q.createdBy === user.name;
                                                    return (
                                                        <tr 
                                                            key={q.quotationID} 
                                                            onClick={() => saveContextAndNavigate(onView, q)}
                                                            className="hover:bg-gray-50/50 dark:hover:bg-gray-800/30 transition-colors cursor-pointer group"
                                                        >
                                                            <td className="py-4 px-6">
                                                                <span className="text-[10px] font-black text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/30 px-2.5 py-1 rounded-full uppercase tracking-widest border border-blue-100 dark:border-blue-900/30">
                                                                    {q.quotationID}
                                                                </span>
                                                            </td>
                                                            <td className="py-4 px-6 font-bold text-gray-900 dark:text-white group-hover:text-blue-600 transition-colors">
                                                                {q.customerName || "Untitled Proposal"}
                                                            </td>
                                                            <td className="py-4 px-6 text-sm font-medium text-gray-600 dark:text-gray-400">
                                                                <span className="flex items-center gap-1.5"><Calendar size={13} className="text-gray-400" /> {formatDate(q.date, lang)}</span>
                                                            </td>
                                                            <td className="py-4 px-6 text-sm font-medium text-gray-600 dark:text-gray-400">
                                                                <span className="flex items-center gap-1.5"><User size={13} className="text-gray-400" /> {q.issuerName}</span>
                                                            </td>
                                                            <td className="py-4 px-6">
                                                                <span className="text-base font-black text-emerald-600 dark:text-emerald-400">
                                                                    ฿{q.netTotal.toLocaleString('th-TH', { minimumFractionDigits: 2 })}
                                                                </span>
                                                            </td>
                                                            <td className="py-4 px-6 text-right" onClick={(e) => e.stopPropagation()}>
                                                                <div className="flex items-center justify-end gap-2">
                                                                    {canEdit && (
                                                                        <>
                                                                            <button
                                                                                onClick={() => saveContextAndNavigate(onEdit, q)}
                                                                                className="p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/30 rounded-xl transition-all active:scale-[0.9]"
                                                                                title={t.edit_title}
                                                                            >
                                                                                <Edit size={16} />
                                                                            </button>
                                                                            <button
                                                                                onClick={() => onDelete(q)}
                                                                                className="p-2 text-gray-400 hover:text-red-600 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-xl transition-all active:scale-[0.9]"
                                                                                title={t.delete_btn || "Delete"}
                                                                            >
                                                                                <Trash2 size={16} />
                                                                            </button>
                                                                        </>
                                                                    )}
                                                                </div>
                                                            </td>
                                                        </tr>
                                                    );
                                                })}
                                            </tbody>
                                        </table>
                                    </div>
                                </div>
                            </>
                        )}
                    </div>
                </main>
            </div>
        </div>
    );
};

const CreateScreen = ({ onBack, onSave, customers, products, user, initialData, issuers, userPhones, signatures, userPhotos, suggestions, lang, theme, setTheme }) => {
    const [form, setForm] = useState({
        quotationID: '',
        date: getCurrentDate(),
        issuerName: user.name,
        customerName: '',
        phone: '',
        customerAddress: '',
        customerTaxId: '',
        vatType: 'no-vat',
        discount: 0,
        discountPercent: 0,
        note: '',
        createdBy: user.name,
        priceValidity: 'ภายใน 30 วัน',
        issuerPhone: initialData ? (initialData.issuerPhone || '') : (userPhones && userPhones[user.name] ? userPhones[user.name] : '')
    });
    const [items, setItems] = useState([{ number: 1, description: '', imageURL: '', detail: '', quantity: 1, unit: '', unitPrice: 0, amount: 0, supplementary: { included: [], warranty: [], payment: [] }, showDetail: false }]);
    const [isSuppModalOpen, setIsSuppModalOpen] = useState(false);
    const [currentEditingIndex, setCurrentEditingIndex] = useState(null);

    const [showPreview, setShowPreview] = useState(window.innerWidth >= 1024);
    const [showMobilePreview, setShowMobilePreview] = useState(false);
    const [previewZoom, setPreviewZoom] = useState(0.65);
    const [mobileZoom, setMobileZoom] = useState(0.55);
    const [isCompactMode, setIsCompactMode] = useState(false);

    const t = TEXT[lang];

    useEffect(() => {
        if (!initialData && userPhones && userPhones[user.name]) {
            setForm(prev => {
                if (!prev.issuerPhone) return { ...prev, issuerPhone: userPhones[user.name] };
                return prev;
            });
        }
    }, [userPhones, user.name, initialData]);

    useEffect(() => {
        if (initialData) {
            let editDate = initialData.date || '';
            if (editDate.includes('\u200B')) editDate = '';
            setForm({ ...initialData, date: editDate, discountPercent: 0 });
            const mappedItems = initialData.products.map(p => {
                const { text, supp } = parseDetailField(p.detail);
                return { ...p, detail: text, supplementary: supp || { included: [], warranty: [], payment: [] }, showDetail: false };
            });
            setItems(mappedItems);
        } else {
            google.script.run.withSuccessHandler(id => { setForm(prev => ({ ...prev, quotationID: id })); }).getNextQuotationNumberAPI();
        }
    }, [initialData]);

    const handleCustSelect = (val, obj) => {
        setForm(prev => ({
            ...prev,
            customerName: val,
            phone: obj ? (obj.phone || "") : prev.phone,
            customerAddress: obj ? (obj.address || "") : prev.customerAddress,
            customerTaxId: obj ? (obj.taxId || "") : prev.customerTaxId
        }));
    };

    const handleAddressLineChange = (index, val) => {
        const lines = (form.customerAddress || '').split('\n');
        while (lines.length < 2) lines.push('');
        lines[index] = val;
        setForm(prev => ({ ...prev, customerAddress: lines.join('\n') }));
    };

    const handleNoteLineChange = (index, val) => {
        const lines = (form.note || '').split('\n');
        while (lines.length < 3) lines.push('');
        lines[index] = val;
        setForm(prev => ({ ...prev, note: lines.join('\n') }));
    };

    const handleTaxIdChange = (val) => {
        const numeric = val.replace(/\D/g, '').slice(0, 13);
        setForm({ ...form, customerTaxId: numeric });
    };
    const showTaxExample = () => {
        premiumAlert.info(t.example_title, t.example_text);
    };

    const handleProdSelect = (idx, val, obj) => {
        const newItems = [...items];
        newItems[idx].description = val;
        if (obj) {
            newItems[idx].unit = obj.unit;
            newItems[idx].unitPrice = obj.price;
            newItems[idx].imageURL = obj.imageURL;
            const details = [obj.detail1, obj.detail2, obj.detail3, obj.detail4, obj.detail5];
            const combinedDetail = details.join('\n');
            newItems[idx].detail = combinedDetail;
        }
        calcAmount(newItems);
    };

    const handleItemChange = (idx, key, val) => { const newItems = [...items]; newItems[idx][key] = val; calcAmount(newItems); };

    const handleDetailLineChange = (itemIdx, lineIdx, val) => {
        const newItems = [...items];
        const currentDetail = newItems[itemIdx].detail || '';
        const parts = currentDetail.split(SUPP_SEPARATOR);
        const mainText = parts[0] || '';
        const suppPart = parts.length > 1 ? SUPP_SEPARATOR + parts[1] : '';
        let lines = mainText.split('\n');
        while (lines.length < 5) lines.push('');
        lines[lineIdx] = val;
        const newMainText = lines.join('\n');
        newItems[itemIdx].detail = newMainText + suppPart;
        setItems(newItems);
    };

    const toggleDetail = (idx) => {
        const newItems = [...items];
        newItems[idx].showDetail = !newItems[idx].showDetail;
        setItems(newItems);
    };

    const moveItem = (idx, direction) => {
        const newItems = [...items];
        if (direction === 'up' && idx > 0) {
            [newItems[idx], newItems[idx - 1]] = [newItems[idx - 1], newItems[idx]];
        } else if (direction === 'down' && idx < newItems.length - 1) {
            [newItems[idx], newItems[idx + 1]] = [newItems[idx + 1], newItems[idx]];
        }
        setItems(newItems.map((it, i) => ({ ...it, number: i + 1 })));
    };

    const calcAmount = (currItems) => { const updated = currItems.map(i => ({ ...i, amount: (parseFloat(i.quantity) || 0) * (parseFloat(i.unitPrice) || 0) })); setItems(updated); };
    const addItem = () => setItems([...items, { number: items.length + 1, description: '', imageURL: '', detail: '', quantity: 1, unit: '', unitPrice: 0, amount: 0, supplementary: { included: [], warranty: [], payment: [] }, showDetail: false }]);
    const removeItem = (idx) => { if (items.length > 1) { const n = items.filter((_, i) => i !== idx).map((it, i) => ({ ...it, number: i + 1 })); calcAmount(n); } };
    const openSuppModal = (idx) => { setCurrentEditingIndex(idx); setIsSuppModalOpen(true); };


    const saveSuppData = (suppData) => { if (currentEditingIndex !== null) { const newItems = [...items]; newItems[currentEditingIndex].supplementary = suppData; setItems(newItems); } };

    const totals = useMemo(() => {
        const total = items.reduce((s, i) => s + i.amount, 0);
        const discountVal = parseFloat(form.discount) || 0;
        const afterDiscGross = total - discountVal;
        let vat = 0, net = afterDiscGross, displayAfterDiscount = afterDiscGross;
        if (form.vatType === 'vat-exclude') { vat = afterDiscGross * 0.07; net = afterDiscGross + vat; displayAfterDiscount = afterDiscGross; }
        else if (form.vatType === 'vat-include') { net = afterDiscGross; const base = net / 1.07; vat = net - base; displayAfterDiscount = base; }
        return { total, afterDisc: displayAfterDiscount, vat, net };
    }, [items, form.discount, form.vatType]);

    const handleDiscountChange = (type, val) => {
        const numVal = parseFloat(val) || 0;
        const total = items.reduce((s, i) => s + i.amount, 0);
        if (type === 'percent') { const baht = (total * numVal) / 100; setForm(prev => ({ ...prev, discountPercent: numVal, discount: baht })); }
        else { const percent = total > 0 ? (numVal / total) * 100 : 0; setForm(prev => ({ ...prev, discount: numVal, discountPercent: percent })); }
    };

    const save = () => {
        if (!form.customerName) return premiumAlert.warn(t.alert_title, t.warn_cust);
        if (!form.phone) return premiumAlert.warn(t.alert_title, t.warn_phone);
        if (!form.customerAddress || form.customerAddress.trim() === "") return premiumAlert.warn(t.alert_title, t.warn_addr);
        if (items.length === 0) return premiumAlert.warn(t.alert_title, t.warn_item);
        
        premiumAlert.confirm(t.check_title, t.confirm_save, t.yes_save, t.no_cancel).then((result) => {
            if (result.isConfirmed) {
                const packedItems = items.map(item => {
                    const cleanItem = { ...item };
                    const hasSupp = item.supplementary && (item.supplementary.included.length > 0 || item.supplementary.warranty.length > 0 || item.supplementary.payment.length > 0);
                    let currentDetailText = cleanItem.detail || '';
                    if (currentDetailText.includes(SUPP_SEPARATOR)) currentDetailText = currentDetailText.split(SUPP_SEPARATOR)[0];
                    if (hasSupp) { cleanItem.detail = currentDetailText + SUPP_SEPARATOR + JSON.stringify(item.supplementary); }
                    else { cleanItem.detail = currentDetailText; }
                    return cleanItem;
                });
                const payload = { ...form, total: totals.total, afterDiscount: totals.afterDisc, vat: totals.vat, netTotal: totals.net, products: packedItems };
                onSave(payload);
            }
        });
    };

    const addressLines = (form.customerAddress || '').split('\n');
    const noteLines = (form.note || '').split('\n');

    const previewQuotation = useMemo(() => {
        const packedItems = items.map(item => {
            const cleanItem = { ...item };
            const hasSupp = item.supplementary && (item.supplementary.included.length > 0 || item.supplementary.warranty.length > 0 || item.supplementary.payment.length > 0);
            let currentDetailText = cleanItem.detail || '';
            if (currentDetailText.includes(SUPP_SEPARATOR)) currentDetailText = currentDetailText.split(SUPP_SEPARATOR)[0];
            if (hasSupp) { cleanItem.detail = currentDetailText + SUPP_SEPARATOR + JSON.stringify(item.supplementary); }
            else { cleanItem.detail = currentDetailText; }
            return cleanItem;
        });
        return {
            ...form,
            total: totals.total,
            afterDiscount: totals.afterDisc,
            vat: totals.vat,
            netTotal: totals.net,
            products: packedItems
        };
    }, [form, items, totals]);

    return (
        <div className="h-screen flex flex-col bg-slate-50 dark:bg-gray-900 transition-colors relative">
            <SupplementaryModal isOpen={isSuppModalOpen} onClose={() => setIsSuppModalOpen(false)} initialData={currentEditingIndex !== null ? items[currentEditingIndex].supplementary : null} onSave={saveSuppData} suggestions={suggestions} lang={lang} />

            {showMobilePreview && (
                <div className="fixed inset-0 z-50 bg-gray-100 dark:bg-gray-800 flex flex-col animate-in slide-in-from-bottom duration-300">
                    <div className="bg-white dark:bg-gray-900 px-4 py-3 shadow-md flex justify-between items-center sticky top-0 z-10 border-b border-gray-200 dark:border-gray-700">
                        <h2 className="font-bold text-gray-800 dark:text-white flex items-center gap-2"><Eye size={20} className="text-blue-600 dark:text-blue-400" /> {t.preview}</h2>
                        <button onClick={() => setShowMobilePreview(false)} className="p-2 bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-300 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"><X size={24} /></button>
                    </div>
                    <div className="flex-1 overflow-y-auto p-4 flex justify-center relative">
                        <div style={{ transform: `scale(${mobileZoom})`, transformOrigin: 'top center', transition: 'transform 0.2s' }} className="mb-20">
                            <QuotationSheet q={previewQuotation} signatures={signatures} userPhotos={userPhotos} lang={lang} isCompact={isCompactMode} />
                        </div>
                    </div>
                    <div className="absolute bottom-6 left-1/2 transform -translate-x-1/2 bg-gray-800/90 text-white backdrop-blur-md p-2 rounded-full shadow-lg flex items-center gap-4 z-50">
                        <button onClick={() => setMobileZoom(prev => Math.max(prev - 0.1, 0.3))} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomOut size={20} /></button>
                        <span className="text-xs font-mono w-8 text-center">{(mobileZoom * 100).toFixed(0)}%</span>
                        <button onClick={() => setMobileZoom(prev => Math.min(prev + 0.1, 1.5))} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomIn size={20} /></button>
                        <div className="w-px h-4 bg-gray-600"></div>
                        <button onClick={() => setMobileZoom(0.55)} className="px-3 py-1 text-xs hover:bg-white/20 rounded-full transition-colors">Reset</button>
                    </div>
                </div>
            )}

            <div className="bg-white dark:bg-gray-800 px-4 py-3 shadow-sm flex items-center gap-3 z-20 border-b border-gray-200 dark:border-gray-700 no-print transition-colors">
                <button onClick={onBack} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full text-gray-600 dark:text-gray-300"><ChevronLeft /></button>
                <h1 className="font-bold text-lg flex-1 text-gray-800 dark:text-white">{initialData ? t.edit_title : t.create_title}</h1>

                <label className="hidden lg:flex items-center gap-2 px-3 py-1.5 rounded-lg border border-gray-300 dark:border-gray-600 text-sm font-medium text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors cursor-pointer">
                    <input type="checkbox" checked={isCompactMode} onChange={(e) => setIsCompactMode(e.target.checked)} className="rounded text-blue-600" />
                    {t.compact_mode}
                </label>

                <button onClick={() => setShowMobilePreview(true)} className="lg:hidden flex items-center gap-1 px-3 py-1.5 rounded-lg bg-blue-50 dark:bg-gray-700 text-blue-600 dark:text-blue-400 text-sm font-bold border border-blue-100 dark:border-gray-600 shadow-sm active:scale-95 transition-all">
                    <Eye size={18} /> {t.preview}
                </button>

                <button onClick={() => setShowPreview(!showPreview)} className="hidden lg:flex items-center gap-2 px-3 py-1.5 rounded-lg border border-gray-300 dark:border-gray-600 text-sm font-medium text-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
                    {showPreview ? <><Columns size={16} /> {t.hide_preview}</> : <><Layout size={16} /> {t.show_preview}</>}
                </button>
            </div>

            <div className="flex-1 flex overflow-hidden">
                <div className={`flex-1 overflow-y-auto p-4 space-y-6 pb-24 transition-all duration-300 ${showPreview ? 'lg:w-1/2' : 'w-full'}`}>
                    <div className="lg:hidden bg-white dark:bg-gray-800 p-3 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 flex justify-between items-center transition-colors">
                        <span className="text-sm font-bold text-gray-700 dark:text-gray-300">{t.compact_mode}</span>
                        <input type="checkbox" checked={isCompactMode} onChange={(e) => setIsCompactMode(e.target.checked)} className="w-5 h-5 rounded text-blue-600 cursor-pointer" />
                    </div>

                    <div className="bg-white dark:bg-gray-800 p-5 rounded-2xl shadow-sm border-l-4 border-blue-500 relative transition-colors">
                        <h3 className="font-bold text-blue-700 dark:text-blue-400 mb-4 text-lg border-b border-blue-50 dark:border-gray-700 pb-2 flex items-center gap-2">{t.cust_info}</h3>
                        <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
                            <div className="bg-blue-50/50 dark:bg-gray-700 p-3 rounded-xl border border-blue-100 dark:border-gray-600"><label className="text-xs font-bold text-blue-600 dark:text-blue-400 block mb-1">{t.doc_no}</label><div className="font-bold text-gray-800 dark:text-white">{form.quotationID || t.doc_auto}</div></div>
                            <div className="bg-blue-50/50 dark:bg-gray-700 p-3 rounded-xl border border-blue-100 dark:border-gray-600">
                                <label className="text-xs font-bold text-blue-600 dark:text-blue-400 block mb-1">{t.date}</label>
                                <ThaiDatePicker value={form.date} onChange={d => setForm({ ...form, date: d })} lang={lang} />
                            </div>
                            <div className="bg-blue-50/50 dark:bg-gray-700 p-3 rounded-xl border border-blue-100 dark:border-gray-600">
                                <label className="text-xs font-bold text-blue-600 dark:text-blue-400 block mb-1">{t.issuer}</label>
                                <input type="text" value={form.issuerName || user.name} readOnly className="w-full bg-transparent font-medium text-gray-700 dark:text-gray-200 focus:outline-none" />
                            </div>
                        </div>

                        <div className="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
                            <div className="bg-blue-50/50 dark:bg-gray-700 p-3 rounded-xl border border-blue-100 dark:border-gray-600">
                                <label className="text-xs font-bold text-blue-600 dark:text-blue-400 block mb-1">{t.validity}</label>
                                <input type="text" maxLength={55} value={form.priceValidity} onChange={e => setForm({ ...form, priceValidity: e.target.value })} className="w-full bg-white dark:bg-gray-800 px-3 py-1.5 rounded-lg text-sm border border-blue-200 dark:border-gray-600 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-400" placeholder="..." />
                            </div>
                            <div className="bg-blue-50/50 dark:bg-gray-700 p-3 rounded-xl border border-blue-100 dark:border-gray-600">
                                <label className="text-xs font-bold text-blue-600 dark:text-blue-400 block mb-1">{t.issuer_phone}</label>
                                <input type="text" value={form.issuerPhone} onChange={e => setForm({ ...form, issuerPhone: e.target.value })} className="w-full bg-white dark:bg-gray-800 px-3 py-1.5 rounded-lg text-sm border border-blue-200 dark:border-gray-600 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-400" placeholder="..." />
                            </div>
                        </div>

                        <div className="space-y-3">
                            <SearchableDropdown placeholder={t.cust_search} options={customers} labelKey="name" value={form.customerName} onChange={handleCustSelect} className="bg-white dark:bg-gray-700 border-gray-200 dark:border-gray-600 focus:ring-blue-500 text-gray-900 dark:text-white" icon={<User size={18} />} />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <input placeholder={t.phone_ph} value={form.phone} onChange={e => setForm({ ...form, phone: e.target.value })} className="w-full bg-white dark:bg-gray-700 text-gray-900 dark:text-white p-3 rounded-xl border border-gray-200 dark:border-gray-600 focus:ring-2 focus:ring-blue-500 focus:outline-none" />
                                <div className="relative">
                                    <input
                                        placeholder={t.tax_ph}
                                        value={form.customerTaxId}
                                        onChange={e => handleTaxIdChange(e.target.value)}
                                        maxLength={13}
                                        className="w-full bg-white dark:bg-gray-700 text-gray-900 dark:text-white p-3 rounded-xl border border-gray-200 dark:border-gray-600 focus:ring-2 focus:ring-blue-500 focus:outline-none pr-10"
                                    />
                                    <button onClick={showTaxExample} className="absolute right-3 top-3 text-blue-500 dark:text-blue-400 hover:text-blue-700">
                                        <HelpCircle size={20} />
                                    </button>
                                </div>
                            </div>
                            <div>
                                <label className="text-xs font-bold text-gray-600 dark:text-gray-400 mb-1 block">{t.addr_label}</label>
                                {[0, 1].map(idx => (
                                    <div key={idx} className="relative mb-2 last:mb-0">
                                        <input
                                            type="text"
                                            maxLength={70}
                                            value={addressLines[idx] || ''}
                                            onChange={e => handleAddressLineChange(idx, e.target.value)}
                                            placeholder={`${t.addr_ph} ${idx + 1}...`}
                                            className={`w-full bg-white dark:bg-gray-700 text-gray-900 dark:text-white p-3 rounded-xl border focus:ring-2 focus:ring-blue-500 focus:outline-none ${(addressLines[idx] || '').length === 70 ? 'border-red-400 dark:border-red-500 focus:ring-red-400' : 'border-gray-200 dark:border-gray-600'}`}
                                        />
                                        <span className="absolute right-3 top-3 text-[10px] text-gray-400 dark:text-gray-500">
                                            {(addressLines[idx] || '').length}/70
                                        </span>
                                    </div>
                                ))}
                            </div>
                        </div>
                    </div>
                    <div className="bg-white dark:bg-gray-800 p-5 rounded-2xl shadow-sm border-l-4 border-indigo-500 relative transition-colors">
                        <div className="flex justify-between items-center mb-4 border-b border-indigo-50 dark:border-gray-700 pb-2"><h3 className="font-bold text-indigo-700 dark:text-indigo-400 text-lg flex items-center gap-2">{t.prod_title} <span className="text-sm font-normal text-indigo-400 dark:text-indigo-300 bg-indigo-50 dark:bg-gray-700 px-2 py-0.5 rounded-full">({items.length})</span></h3></div>
                        <div className="space-y-4">
                            {items.map((item, idx) => {
                                const rawText = item.detail ? item.detail.split(SUPP_SEPARATOR)[0] : '';
                                const lines = rawText.split('\n');

                                return (
                                    <div key={idx} className="bg-indigo-50/30 dark:bg-gray-700 p-4 rounded-xl border border-indigo-100 dark:border-gray-600 relative group transition-all hover:border-indigo-300 dark:hover:border-indigo-500">
                                        <div className="flex justify-between mb-3 items-center">
                                            <span className="text-xs font-bold text-indigo-400 dark:text-indigo-300 bg-indigo-50 dark:bg-gray-800 px-2 py-1 rounded-md shadow-sm border border-indigo-100 dark:border-gray-600">#{item.number}</span>
                                            <div className="flex items-center gap-1 bg-white dark:bg-gray-800 border border-indigo-100 dark:border-gray-600 rounded-lg p-1 shadow-sm">
                                                <button onClick={() => moveItem(idx, 'up')} disabled={idx === 0} className={`p-1 rounded-md flex items-center justify-center transition-all duration-200 ${idx > 0 ? 'text-indigo-400 dark:text-indigo-300 hover:bg-indigo-50 dark:hover:bg-gray-700 hover:text-indigo-700 dark:hover:text-indigo-100 active:scale-95 cursor-pointer' : 'text-gray-200 dark:text-gray-600 cursor-not-allowed'}`} title={t.move_up}>
                                                    <ArrowUp size={16} strokeWidth={2.5} />
                                                </button>
                                                <button onClick={() => moveItem(idx, 'down')} disabled={idx === items.length - 1} className={`p-1 rounded-md flex items-center justify-center transition-all duration-200 ${idx < items.length - 1 ? 'text-indigo-400 dark:text-indigo-300 hover:bg-indigo-50 dark:hover:bg-gray-700 hover:text-indigo-700 dark:hover:text-indigo-100 active:scale-95 cursor-pointer' : 'text-gray-200 dark:text-gray-600 cursor-not-allowed'}`} title={t.move_down}>
                                                    <ArrowDown size={16} strokeWidth={2.5} />
                                                </button>
                                                <div className="w-px h-4 bg-indigo-100 dark:bg-gray-600 mx-1"></div>
                                                <button onClick={() => removeItem(idx)} disabled={items.length <= 1} className={`p-1 rounded-md flex items-center justify-center transition-all duration-200 ${items.length > 1 ? 'text-red-400 dark:text-red-400 hover:bg-red-50 dark:hover:bg-gray-700 hover:text-red-600 dark:hover:text-red-300 active:scale-95 cursor-pointer' : 'text-gray-200 dark:text-gray-600 cursor-not-allowed'}`} title={t.remove}>
                                                    <Trash2 size={16} strokeWidth={2.5} />
                                                </button>
                                            </div>
                                        </div>
                                        <div className="flex gap-4 items-start">
                                            <div className="flex-shrink-0">{item.imageURL ? (<img src={item.imageURL} alt="img" className="w-20 h-20 object-cover rounded-lg border border-gray-200 dark:border-gray-600 bg-white dark:bg-gray-800 shadow-sm" />) : (<div className="w-20 h-20 bg-white dark:bg-gray-800 border border-dashed border-gray-300 dark:border-gray-600 rounded-lg flex items-center justify-center text-gray-400 dark:text-gray-500 text-xs">No Img</div>)}</div>
                                            <div className="flex-1 space-y-2">
                                                <SearchableDropdown placeholder={t.prod_search} options={products} labelKey="name" value={item.description} onChange={(v, o) => handleProdSelect(idx, v, o)} className="bg-white dark:bg-gray-800 border-indigo-200 dark:border-gray-600 focus:ring-indigo-500 text-gray-900 dark:text-white" />

                                                <button onClick={() => toggleDetail(idx)} className="text-xs text-blue-600 dark:text-blue-400 font-bold flex items-center gap-1 hover:text-blue-800 dark:hover:text-blue-300 transition-colors">
                                                    {item.showDetail ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
                                                    {item.showDetail ? t.hide_detail : t.show_detail}
                                                </button>

                                                {item.showDetail && (
                                                    <div className="bg-white dark:bg-gray-800 rounded-lg border border-indigo-200 dark:border-gray-600 p-2 space-y-1 animate-in fade-in zoom-in-95 duration-200 origin-top">
                                                        <label className="text-[10px] text-gray-400 dark:text-gray-500 ml-1">{t.desc} (Max 5 lines)</label>
                                                        {[...Array(5)].map((_, lineIdx) => (
                                                            <input
                                                                key={lineIdx}
                                                                type="text"
                                                                maxLength={68}
                                                                placeholder={`${t.detail_ph} ${lineIdx + 1}`}
                                                                value={lines[lineIdx] || ''}
                                                                onChange={e => handleDetailLineChange(idx, lineIdx, e.target.value)}
                                                                className="w-full bg-gray-50 dark:bg-gray-700 p-1.5 rounded border border-gray-100 dark:border-gray-600 text-xs text-gray-600 dark:text-gray-200 focus:ring-1 focus:ring-indigo-400 focus:bg-white dark:focus:bg-gray-600 focus:outline-none"
                                                            />
                                                        ))}
                                                        <div className="pt-2 border-t border-indigo-50 dark:border-gray-600 mt-1 space-y-2">
                                                            <div className="flex gap-2">
                                                                <input
                                                                    placeholder={t.img_url}
                                                                    value={item.imageURL}
                                                                    onChange={e => handleItemChange(idx, 'imageURL', e.target.value)}
                                                                    className="w-full bg-white dark:bg-gray-700 p-2 rounded-lg border border-indigo-200 dark:border-gray-600 text-xs text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-indigo-400"
                                                                />
                                                            </div>
                                                        </div>
                                                    </div>
                                                )}
                                            </div>
                                        </div>
                                        <div className="grid grid-cols-4 gap-2 mt-3 bg-white dark:bg-gray-800 p-2 rounded-lg border border-indigo-50 dark:border-gray-600"><div className="col-span-1"><label className="text-[10px] text-gray-400 dark:text-gray-500 ml-1">{t.qty}</label><input type="number" value={item.quantity} onChange={e => handleItemChange(idx, 'quantity', e.target.value)} className="w-full p-1 text-center font-bold text-gray-700 dark:text-white bg-transparent outline-none" /></div><div className="col-span-1 border-l border-gray-100 dark:border-gray-600 pl-2"><label className="text-[10px] text-gray-400 dark:text-gray-500 ml-1">{t.unit}</label><input type="text" value={item.unit} onChange={e => handleItemChange(idx, 'unit', e.target.value)} className="w-full p-1 text-center text-gray-600 dark:text-gray-300 bg-transparent outline-none" /></div><div className="col-span-1 border-l border-gray-100 dark:border-gray-600 pl-2"><label className="text-[10px] text-gray-400 dark:text-gray-500 ml-1">{t.price_unit}</label><input type="number" value={item.unitPrice} onChange={e => handleItemChange(idx, 'unitPrice', e.target.value)} className="w-full p-1 text-right text-gray-600 dark:text-gray-300 bg-transparent outline-none" /></div><div className="col-span-1 border-l border-gray-100 dark:border-gray-600 pl-2 bg-indigo-50 dark:bg-gray-700 rounded-r-md"><label className="text-[10px] text-indigo-400 dark:text-indigo-300 ml-1 block text-right pr-2">{t.total_col}</label><div className="p-1 text-right font-bold text-indigo-700 dark:text-indigo-300">{formatCurrency(item.amount)}</div></div></div>
                                        <div className="mt-3 flex justify-end"><button onClick={() => openSuppModal(idx)} className="text-xs bg-white dark:bg-gray-800 border border-indigo-200 dark:border-gray-600 text-indigo-600 dark:text-indigo-400 px-3 py-1.5 rounded-lg font-bold flex items-center gap-1 hover:bg-indigo-50 dark:hover:bg-gray-700 transition-colors shadow-sm">{item.supplementary && Object.values(item.supplementary).flat().length > 0 ? (<><CheckSquare size={14} className="text-green-500 dark:text-green-400" /> {t.edit_supp}</>) : (
                                            <><Plus size={14} /> {t.add_supp}</>
                                        )}</button></div>
                                    </div>
                                );
                            })}
                            <button onClick={addItem} className="w-full py-3 bg-white dark:bg-gray-800 border-2 border-dashed border-indigo-300 dark:border-indigo-600 text-indigo-500 dark:text-indigo-400 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-indigo-50 dark:hover:bg-gray-700 hover:border-indigo-400 dark:hover:border-indigo-500 transition-all active:scale-[0.99]"><Plus size={20} /> {t.add_prod}</button>
                        </div>
                    </div>
                    <div className="bg-white dark:bg-gray-800 p-5 rounded-2xl shadow-sm border-l-4 border-emerald-500 relative transition-colors">
                        <h3 className="font-bold text-emerald-700 dark:text-emerald-400 mb-4 text-lg border-b border-emerald-50 dark:border-gray-700 pb-2 flex items-center gap-2">{t.summary_title}</h3>
                        <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
                            <div className="space-y-4">
                                <div><label className="text-xs font-bold text-gray-600 dark:text-gray-400 mb-1 block">{t.vat_type} <span className="text-red-500">*</span></label><select value={form.vatType} onChange={e => setForm({ ...form, vatType: e.target.value })} className="w-full bg-white dark:bg-gray-700 p-3 rounded-xl border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-white focus:ring-2 focus:ring-emerald-400 outline-none font-medium transition-colors"><option value="no-vat">{t.vat_no}</option><option value="vat-exclude">{t.vat_ex}</option><option value="vat-include">{t.vat_in}</option></select></div>
                                <div className="grid grid-cols-2 gap-3"><div><label className="text-xs font-bold text-gray-500 dark:text-gray-400 mb-1 block">{t.disc_pct}</label><input type="number" value={form.discountPercent} onChange={e => handleDiscountChange('percent', e.target.value)} className="w-full bg-white dark:bg-gray-700 p-3 rounded-xl border border-gray-200 dark:border-gray-600 text-center text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-emerald-300" placeholder="0" /></div><div><label className="text-xs font-bold text-gray-500 dark:text-gray-400 mb-1 block">{t.disc_baht}</label><input type="number" value={form.discount} onChange={e => handleDiscountChange('baht', e.target.value)} className="w-full bg-white dark:bg-gray-700 p-3 rounded-xl border border-gray-200 dark:border-gray-600 text-right text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-emerald-300" placeholder="0" /></div></div>
                                <div>
                                    <label className="text-xs font-bold text-gray-500 dark:text-gray-400 mb-1 block">{t.note_add}</label>
                                    {[0, 1, 2].map(idx => (
                                        <div key={idx} className="relative mb-2 last:mb-0">
                                            <input
                                                type="text"
                                                maxLength={60}
                                                value={noteLines[idx] || ''}
                                                onChange={e => handleNoteLineChange(idx, e.target.value)}
                                                placeholder={`${t.note_line_ph} ${idx + 1}...`}
                                                className="w-full bg-gray-50 dark:bg-gray-700 p-2 rounded-lg border border-gray-200 dark:border-gray-600 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-emerald-300"
                                            />
                                            <span className="absolute right-3 top-2 text-[10px] text-gray-400 dark:text-gray-500">
                                                {(noteLines[idx] || '').length}/60
                                            </span>
                                        </div>
                                    ))}
                                </div>
                            </div>
                            <div className="space-y-3 text-sm bg-emerald-50/50 dark:bg-gray-700 p-4 rounded-xl border border-emerald-100 dark:border-gray-600 h-fit transition-colors">
                                <div className="flex justify-between items-center py-1"><span className="text-gray-600 dark:text-gray-300 font-medium">{t.total_label}:</span><span className="font-bold text-gray-800 dark:text-white">{formatCurrency(totals.total)}</span></div>
                                <div className="flex justify-between items-center py-1"><span className="text-gray-600 dark:text-gray-300 font-medium">{t.discount_label}:</span><span className="font-bold text-red-500 dark:text-red-400">{formatCurrency(form.discount)}</span></div>
                                <div className="flex justify-between items-center py-1 border-b border-emerald-200 dark:border-gray-600 pb-2"><span className="text-gray-600 dark:text-gray-300 font-medium">{t.after_discount_label}:</span><span className="font-bold text-gray-800 dark:text-white">{formatCurrency(totals.afterDisc)}</span></div>
                                <div className="flex justify-between items-center py-1"><span className="text-gray-600 dark:text-gray-300 font-medium">{t.vat_label}:</span><span className="font-bold text-gray-800 dark:text-white">{formatCurrency(totals.vat)}</span></div>
                                <div className="flex justify-between items-center bg-white dark:bg-gray-800 p-3 rounded-xl mt-2 shadow-sm border border-emerald-100 dark:border-gray-600"><span className="text-emerald-800 dark:text-emerald-400 font-bold text-lg">{t.net_total_label}:</span><span className="text-emerald-600 dark:text-emerald-400 font-bold text-2xl">{formatCurrency(totals.net)}</span></div>
                            </div>
                        </div>
                    </div>
                </div>

                <div className={`hidden lg:block transition-all duration-300 bg-gray-600 dark:bg-gray-950 overflow-y-auto border-l border-gray-300 dark:border-gray-800 relative ${showPreview ? 'w-1/2 p-6' : 'w-0 p-0'}`}>
                    {showPreview && (
                        <div className="absolute inset-0 overflow-y-auto flex flex-col items-center">
                            <div className="sticky top-0 z-10 w-full flex justify-center pt-6 pb-2">
                                <h3 className="text-white font-bold bg-gray-600/80 dark:bg-gray-900/80 backdrop-blur-sm px-4 py-1 rounded-full border border-white/20 shadow-sm">Real-time Preview</h3>
                            </div>

                            <div style={{ transform: `scale(${previewZoom})`, transformOrigin: 'top center', transition: 'transform 0.2s' }}>
                                <QuotationSheet q={previewQuotation} signatures={signatures} userPhotos={userPhotos} lang={lang} isCompact={isCompactMode} />
                            </div>

                            <div className="fixed bottom-24 right-8 bg-gray-800/90 text-white backdrop-blur-md p-2 rounded-full shadow-lg flex flex-col items-center gap-2 z-50">
                                <button onClick={() => setPreviewZoom(prev => Math.min(prev + 0.1, 1.5))} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomIn size={20} /></button>
                                <span className="text-[10px] font-mono w-8 text-center border-y border-gray-600 py-1">{(previewZoom * 100).toFixed(0)}%</span>
                                <button onClick={() => setPreviewZoom(prev => Math.max(prev - 0.1, 0.3))} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomOut size={20} /></button>
                            </div>
                        </div>
                    )}
                </div>
            </div>

            <div className="p-4 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700 sticky bottom-0 z-30 shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.1)] transition-colors">
                <button onClick={save} className="w-full py-3.5 bg-blue-600 text-white rounded-xl font-bold text-lg shadow-lg hover:bg-blue-700 active:scale-[0.99] transition-all flex items-center justify-center gap-2"><Save size={22} /> {t.save}</button>
            </div>
        </div>
    );
};

const ViewScreen = ({ q, onBack, signatures, userPhotos, user, lang }) => {
    const [loading, setLoading] = useState(false);
    const [zoom, setZoom] = useState(1);
    const [isCompactMode, setIsCompactMode] = useState(false);
    const t = TEXT[lang];

    const isAdmin = String(user.role).toLowerCase() === 'admin';
    const canAction = (isAdmin || user.name === q.createdBy);

    useLayoutEffect(() => {
        const updateZoom = () => {
            const w = window.innerWidth;
            if (w < 810) {
                setZoom((w - 20) / 794);
            }
        };
        window.addEventListener('resize', updateZoom);
        updateZoom();
        return () => window.removeEventListener('resize', updateZoom);
    }, []);

    const handleZoomIn = () => setZoom(prev => Math.min(prev + 0.1, 3.0));
    const handleZoomOut = () => setZoom(prev => Math.max(prev - 0.1, 0.3));

    useEffect(() => {
        const originalTitle = document.title;
        const timeStr = new Date().toLocaleTimeString('th-TH', { hour: '2-digit', minute: '2-digit' }).replace(':', '.');
        const dateStr = formatDate(q.date, lang).replace(/\//g, '-');
        document.title = `${t.quotation_title} ${q.customerName || "Cust"} ${dateStr} ${timeStr}`;
        return () => { document.title = originalTitle; };
    }, [q, lang, t.quotation_title]);

    const handleDownload = async () => {
        setLoading(true);
        await document.fonts.ready;
        const originalElement = document.getElementById('printable-content');
        const element = originalElement.cloneNode(true);

        const getCleanImageUrl = (url) => {
            if (!url) return "";
            let id = null;
            if (url.includes('drive.google.com') || url.includes('docs.google.com')) {
                const parts = url.match(/\/d\/([a-zA-Z0-9_-]+)/);
                if (parts && parts[1]) id = parts[1];
                else {
                    const match = url.match(/id=([a-zA-Z0-9_-]+)/);
                    if (match && match[1]) id = match[1];
                }
            }
            if (id) {
                return `https://drive.google.com/uc?export=view&id=${id}`;
            }
            return url;
        };

        const images = element.querySelectorAll('img');
        const originalImages = originalElement.querySelectorAll('img');

        const promises = Array.from(images).map(async (img, index) => {
            const originalImg = originalImages[index];
            if (originalImg) {
                img.style.width = getComputedStyle(originalImg).width;
                img.style.height = getComputedStyle(originalImg).height;
            }
            const cleanUrl = getCleanImageUrl(img.src);
            if (cleanUrl.startsWith('data:')) {
                await new Promise((resolve) => {
                    if (img.complete) resolve();
                    img.onload = resolve;
                    img.onerror = resolve;
                });
                return;
            }
            const proxyUrl = `https://wsrv.nl/?url=${encodeURIComponent(cleanUrl)}&output=webp`;
            img.crossOrigin = 'Anonymous';
            img.src = proxyUrl;
            await new Promise((resolve) => {
                if (img.complete) resolve();
                img.onload = resolve;
                img.onerror = resolve;
            });
        });

        await Promise.all(promises);
        await new Promise(resolve => setTimeout(resolve, 2000));

        const allElements = element.querySelectorAll('*');
        allElements.forEach(el => {
            el.style.letterSpacing = '0px';
            el.style.textRendering = 'auto';
        });

        element.style.width = '210mm';
        element.style.padding = '0';
        element.style.margin = '0';
        element.style.background = 'white';
        element.style.transform = 'none';

        const pages = element.querySelectorAll('.a4-page');
        pages.forEach(p => {
            p.style.minHeight = '296.5mm';
            p.style.height = '296.5mm';
            p.style.margin = '0';
            p.style.marginBottom = '0';
            p.style.padding = '10mm';
            p.style.position = 'relative';
            p.style.boxShadow = 'none';
            p.style.border = 'none';
            p.style.pageBreakAfter = 'always';
            p.style.overflow = 'hidden';
            p.classList.remove('scale-[0.7]', 'lg:scale-100');
        });

        if (pages.length > 0) {
            pages[pages.length - 1].style.pageBreakAfter = 'avoid';
        }

        element.querySelectorAll('.h-\\[100px\\]').forEach(el => el.classList.remove('h-[100px]'));

        const container = document.createElement('div');
        container.style.position = 'absolute';
        container.style.left = '-9999px';
        container.style.top = '0';
        container.appendChild(element);
        document.body.appendChild(container);

        const dateStr = formatDate(q.date, lang).replace(/\//g, '-');
        const opt = {
            margin: 0,
            filename: `${t.quotation_title}_${q.customerName}_${dateStr}.pdf`,
            image: { type: 'jpeg', quality: 0.98 },
            html2canvas: { scale: 2, useCORS: true, scrollY: 0, allowTaint: true, imageTimeout: 20000 },
            jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
        };

        try {
            await html2pdf().set(opt).from(element).save();
        } catch (err) {
            console.error(err);
            premiumAlert.error(t.error_title, t.pdf_fail);
        } finally {
            document.body.removeChild(container);
            setLoading(false);
        }
    };

    return (
        <div className="h-screen flex flex-col bg-gray-500 dark:bg-gray-900 overflow-hidden print:h-auto print:bg-white print:overflow-visible print:block relative transition-colors">
            {loading && <Loading text={t.downloading_msg} />}
            <div className="bg-gray-800 text-white px-4 py-3 shadow-md flex flex-wrap items-center gap-3 sticky top-0 z-20 no-print">
                <button onClick={onBack} className="p-2 hover:bg-white/20 rounded-full"><ChevronLeft /></button>
                <h1 className="font-bold text-lg flex-1 min-w-[200px] truncate">{t.detail_view} {q.quotationID}</h1>

                <label className="flex items-center gap-2 px-3 py-1.5 rounded-lg bg-gray-700 text-white text-sm font-medium cursor-pointer hover:bg-gray-600 transition-colors shadow-sm">
                    <input type="checkbox" checked={isCompactMode} onChange={(e) => setIsCompactMode(e.target.checked)} className="rounded text-blue-500" />
                    {t.compact_mode}
                </label>

                {canAction && (
                    <div className="flex gap-2 w-full sm:w-auto mt-2 sm:mt-0">
                        <button onClick={handleDownload} className="flex-1 sm:flex-none justify-center bg-emerald-600 px-3 py-1.5 rounded-lg text-sm font-bold flex items-center gap-2 hover:bg-emerald-700 transition-colors shadow-lg border border-emerald-500 whitespace-nowrap"><Download size={16} /> {t.download}</button>
                        <button onClick={() => {
                            const timeStr = new Date().toLocaleTimeString('th-TH', { hour: '2-digit', minute: '2-digit' }).replace(':', '.');
                            const dateStr = formatDate(q.date, lang).replace(/\//g, '-');
                            document.title = `${t.quotation_title} ${q.customerName || "Cust"} ${dateStr} ${timeStr}`;
                            setTimeout(() => window.print(), 100);
                        }} className="flex-1 sm:flex-none justify-center bg-white/20 px-3 py-1.5 rounded-lg text-sm font-bold flex items-center gap-2 hover:bg-white/30 whitespace-nowrap"><Printer size={16} /> {t.print}</button>
                    </div>
                )}
            </div>

            <div className="flex-1 overflow-y-auto p-4 sm:p-8 flex flex-col items-center print:p-0 print:m-0 print:overflow-visible print:block print:w-full">
                <div className="print:transform-none print:w-full print:block" style={{
                    transform: `scale(${zoom})`,
                    transformOrigin: 'top center',
                    width: 'fit-content',
                    transition: 'transform 0.2s ease-out'
                }}>
                    <div id="printable-content" className="print-content-fix">
                        <QuotationSheet q={q} signatures={signatures} userPhotos={userPhotos} lang={lang} isCompact={isCompactMode} />
                    </div>
                </div>
            </div>

            <div className="fixed bottom-6 left-1/2 transform -translate-x-1/2 bg-gray-800/90 text-white backdrop-blur-md p-2 rounded-full shadow-lg flex items-center gap-4 z-50 no-print transition-opacity hover:opacity-100 opacity-80">
                <button onClick={handleZoomOut} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomOut size={20} /></button>
                <span className="text-xs font-mono w-12 text-center">{(zoom * 100).toFixed(0)}%</span>
                <button onClick={handleZoomIn} className="p-2 hover:bg-white/20 rounded-full transition-colors"><ZoomIn size={20} /></button>
                <div className="w-px h-4 bg-gray-600"></div>
                <button onClick={() => setZoom(1)} className="px-3 py-1 text-xs hover:bg-white/20 rounded-full transition-colors">Reset</button>
            </div>

        </div>
    );
};

const App = () => {
    const [user, setUser] = useState(null);
    const [view, setView] = useState('login');
    const [data, setData] = useState({ customers: [], products: [], quotations: [], signatures: {}, issuers: [], userPhones: {}, userPhotos: {}, suppSuggestions: { included: [], warranty: [], payment: [] } });
    const [loading, setLoading] = useState(false);
    const [dashboardState, setDashboardState] = useState({ search: '', filterStart: '', filterEnd: '', filterIssuer: '', scrollY: 0 });
    const [lang, setLang] = useState('th');
    const [theme, setTheme] = useState('light');

    const [viewData, setViewData] = useState(null);
    const [editData, setEditData] = useState(null);
    const [isProfileOpen, setIsProfileOpen] = useState(false);

    useEffect(() => {
        const savedTheme = localStorage.getItem('theme_session');
        if (savedTheme) setTheme(savedTheme);
        const savedUser = localStorage.getItem('user_session');
        if (savedUser) { setUser(JSON.parse(savedUser)); setView('dashboard'); }
        loadSystemData();

        // Real-time Supabase Subscription
        const channel = window.serverFunctions.subscribeToChanges(() => {
            loadSystemData(true); // Silent reload for real-time
        });

        return () => {
            if (channel) channel.unsubscribe();
        };
    }, []);

    useEffect(() => {
        if (theme === 'dark') document.documentElement.classList.add('dark');
        else document.documentElement.classList.remove('dark');
        localStorage.setItem('theme_session', theme);
    }, [theme]);

    const loadSystemData = (isSilent = false) => {
        if (!isSilent) setLoading(true);
        google.script.run.withSuccessHandler(res => {
            setData(res);
            if (!isSilent) setLoading(false);
        }).getInitialData();
    };

    const handleLogin = (u) => { localStorage.setItem('user_session', JSON.stringify(u)); setUser(u); setView('dashboard'); loadSystemData(); };
    const handleLogout = () => { localStorage.removeItem('user_session'); setUser(null); setView('login'); setDashboardState({ search: '', filterStart: '', filterEnd: '', filterIssuer: '', scrollY: 0 }); };

    const handleDashboardAction = (type, q) => {
        if (type === 'create') setView('create');
        else if (type === 'view') { setViewData(q); setView('view'); }
        else if (type === 'edit') { setEditData(q); setView('create'); }
        else if (type === 'delete') {
            premiumAlert.confirm(TEXT[lang].confirm_delete_title, `${TEXT[lang].confirm_delete_text} ${q.quotationID}?`, TEXT[lang].delete_btn, TEXT[lang].cancel).then((result) => {
                if (result.isConfirmed) {
                    setLoading(true);
                    google.script.run.withSuccessHandler(() => {
                        loadSystemData();
                        premiumAlert.success(TEXT[lang].deleted_title, TEXT[lang].item_deleted);
                    }).deleteQuotation(q.quotationID, user.name, user.role);
                }
            });
        }
    };

    const handleSave = (payload) => {
        setLoading(true);
        const action = editData ? 'updateQuotation' : 'createQuotation';
        google.script.run.withSuccessHandler(res => {
            if (res.success) {
                loadSystemData();
                setEditData(null);
                setView('dashboard');
                premiumAlert.success(TEXT[lang].success_title, TEXT[lang].saved_success);
            } else {
                setLoading(false);
                premiumAlert.error(TEXT[lang].error_title, res.message);
            }
        })[action](payload, user.name, user.role);
    };

    const updateProfileSignature = (url) => {
        const newUser = { ...user, signature: url };
        setUser(newUser);
        localStorage.setItem('user_session', JSON.stringify(newUser));
        const normName = user.name ? user.name.replace(/\s+/g, ' ').trim() : "";
        const newSignatures = { ...data.signatures, [normName]: url };
        setData({ ...data, signatures: newSignatures });
    };

    const t = TEXT[lang];

    return (
        <div className={theme}>
            {loading && <Loading text={t.loading_msg} />}
            {view === 'login' && <LoginScreen onLogin={handleLogin} lang={lang} setLang={setLang} theme={theme} setTheme={setTheme} />}
            {view === 'dashboard' && (
                <DashboardScreen
                    quotations={data.quotations || []}
                    user={user}
                    issuers={data.issuers || []}
                    userPhotos={data.userPhotos || {}}
                    signatures={data.signatures || {}}
                    onCreate={() => handleDashboardAction('create')}
                    onView={(q) => handleDashboardAction('view', q)}
                    onEdit={(q) => handleDashboardAction('edit', q)}
                    onDelete={(q) => handleDashboardAction('delete', q)}
                    onLogout={handleLogout}
                    restoreState={dashboardState}
                    onSaveState={(st) => {
                        if (st.showProfile) setIsProfileOpen(true);
                        else setDashboardState(st);
                    }}
                    lang={lang} setLang={setLang} theme={theme} setTheme={setTheme}
                />
            )}
            {view === 'create' && (
                <CreateScreen
                    customers={data.customers || []}
                    products={data.products || []}
                    user={user}
                    initialData={editData}
                    issuers={data.issuers || []}
                    userPhones={data.userPhones || {}}
                    signatures={data.signatures || {}}
                    userPhotos={data.userPhotos || {}}
                    suggestions={data.suppSuggestions}
                    onBack={() => { setView('dashboard'); setEditData(null); }}
                    onSave={handleSave}
                    lang={lang} theme={theme} setTheme={setTheme}
                />
            )}
            {view === 'view' && <ViewScreen q={viewData} signatures={data.signatures || {}} userPhotos={data.userPhotos || {}} user={user} onBack={() => setView('dashboard')} lang={lang} />}

            <UserProfileModal
                isOpen={isProfileOpen}
                onClose={() => setIsProfileOpen(false)}
                user={user}
                currentSignature={user ? (data.signatures[user.name.replace(/\s+/g, ' ').trim()] || user.signature) : null}
                currentPhoto={user ? (data.userPhotos[user.name.replace(/\s+/g, ' ').trim()] || user.photo_url) : null}
                onUpdate={updateProfileSignature}
                lang={lang}
            />
        </div>
    );
};

const root = createRoot(document.getElementById('root'));
root.render(<App />);
