// ============================================
// CREATIVE STREAKS - QUOTATION & INVOICE SYSTEM
// helpers.jsx — config, API, utilities, shared components
// ============================================
const { useState, useEffect, useRef } = React

// ============================================
// CONFIG
// ============================================
// Backend: Cloudflare D1 melalui Pages Functions (/api/*)
// (dahulu Google Apps Script + Google Sheets — ditinggalkan 23 Julai 2026)
const API_BASE = "/api"

// Letak "logo.png" jika ada fail logo dalam folder ini; kosongkan untuk guna "CS"
const COMPANY_LOGO = "/Logocreativestreaks.avif"

const companyInfo = {
    name: "Creative Streaks",
    tagline: "Multimedia",
    ssm: "SA0593407-D",
    phone: "013-660 7039",
    email: "faisalazizbiz@gmail.com",
}

const bankDetails = {
    bank: "Maybank",
    accountName: "CREATIVE STREAKS MULTIMEDIA",
    accountNo: "562263596046",
}

// Fallback jika API gagal (data sebenar datang dari Google Sheets)
const initialQuotations = []
const initialInvoices = []

// ============================================
// API HELPERS
// ============================================
const api = {
    async request(path, options = {}) {
        try {
            const response = await fetch(API_BASE + path, {
                headers: { "Content-Type": "application/json" },
                ...options,
            })
            const result = await response.json()
            if (result && result.success === false) {
                console.error(`API ${path} gagal:`, result.error)
            }
            return result
        } catch (error) {
            // JANGAN pura-pura berjaya — ini pernah sembunyikan kegagalan sebenar
            console.error("API error:", path, error)
            return { success: false, error: error.message }
        }
    },

    getQuotations: () => api.request("/quotations"),
    getInvoices: () => api.request("/invoices"),

    // Satu endpoint utk cipta & kemaskini (upsert ikut id)
    saveQuotationDoc: (data) =>
        api.request("/quotations", {
            method: "POST",
            body: JSON.stringify(data),
        }),
    saveInvoiceDoc: (data) =>
        api.request("/invoices", { method: "POST", body: JSON.stringify(data) }),

    createQuotation: (data) => api.saveQuotationDoc(data),
    updateQuotation: (data) => api.saveQuotationDoc(data),
    createInvoice: (data) => api.saveInvoiceDoc(data),
    updateInvoice: (data) => api.saveInvoiceDoc(data),

    deleteQuotation: (id) =>
        api.request(`/quotations?id=${encodeURIComponent(id)}`, {
            method: "DELETE",
        }),
    deleteInvoice: (id) =>
        api.request(`/invoices?id=${encodeURIComponent(id)}`, {
            method: "DELETE",
        }),

    // Pautan kongsi pendek (awam)
    getShared: (code) =>
        api.request(`/share?code=${encodeURIComponent(code)}`),
}

// ============================================
// PDF GENERATION
// ============================================
const A4_WIDTH = 794
const A4_HEIGHT = 1123
const PDF_MARGIN = 20

const loadScript = (src) => {
    return new Promise((resolve, reject) => {
        if (document.querySelector(`script[src="${src}"]`)) {
            resolve()
            return
        }
        const script = document.createElement("script")
        script.src = src
        script.onload = resolve
        script.onerror = reject
        document.head.appendChild(script)
    })
}

const generatePDF = async (elementId, filename, type = "quotation") => {
    try {
        await loadScript(
            "https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"
        )
        await loadScript(
            "https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"
        )

        const element = document.getElementById(elementId)
        if (!element) {
            alert("Element not found")
            return
        }

        const loadingDiv = document.createElement("div")
        loadingDiv.id = "pdf-loading"
        loadingDiv.style.cssText =
            "position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);display:flex;align-items:center;justify-content:center;z-index:9999;"
        loadingDiv.innerHTML =
            '<div style="background:#fff;padding:30px 50px;border-radius:12px;text-align:center;"><div style="font-size:16px;font-weight:600;color:#111827;">Generating PDF...</div><div style="font-size:13px;color:#6B7280;margin-top:8px;">Please wait</div></div>'
        document.body.appendChild(loadingDiv)

        const canvas = await window.html2canvas(element, {
            scale: 2,
            useCORS: true,
            allowTaint: true,
            backgroundColor: "#ffffff",
            width: A4_WIDTH,
            windowWidth: A4_WIDTH,
        })

        const imgWidth = A4_WIDTH - PDF_MARGIN * 2
        const pageContentHeight = A4_HEIGHT - PDF_MARGIN * 2 - 20
        const ratio = imgWidth / canvas.width
        const scaledCanvasHeight = canvas.height * ratio
        const totalPages = Math.ceil(scaledCanvasHeight / pageContentHeight)

        const { jsPDF } = window.jspdf
        const pdf = new jsPDF({
            orientation: "portrait",
            unit: "px",
            format: [A4_WIDTH, A4_HEIGHT],
        })

        for (let page = 0; page < totalPages; page++) {
            if (page > 0) {
                pdf.addPage()
            }

            const sourceY = (page * pageContentHeight) / ratio
            const sourceHeight = Math.min(
                pageContentHeight / ratio,
                canvas.height - sourceY
            )
            const destHeight = sourceHeight * ratio

            const pageCanvas = document.createElement("canvas")
            pageCanvas.width = canvas.width
            pageCanvas.height = sourceHeight
            const ctx = pageCanvas.getContext("2d")
            ctx.fillStyle = "#ffffff"
            ctx.fillRect(0, 0, pageCanvas.width, pageCanvas.height)
            ctx.drawImage(
                canvas,
                0,
                sourceY,
                canvas.width,
                sourceHeight,
                0,
                0,
                canvas.width,
                sourceHeight
            )

            const pageImgData = pageCanvas.toDataURL("image/jpeg", 0.95)

            pdf.addImage(
                pageImgData,
                "JPEG",
                PDF_MARGIN,
                PDF_MARGIN,
                imgWidth,
                destHeight
            )

            pdf.setFontSize(10)
            pdf.setTextColor(150)
            pdf.text(
                `Page ${page + 1} of ${totalPages}`,
                A4_WIDTH / 2,
                A4_HEIGHT - 10,
                { align: "center" }
            )
        }

        document.body.removeChild(loadingDiv)
        pdf.save(filename)
    } catch (error) {
        console.error("PDF generation error:", error)
        const loadingEl = document.getElementById("pdf-loading")
        if (loadingEl) document.body.removeChild(loadingEl)
        alert("Failed to generate PDF. Please try again.")
    }
}

// ============================================
// DATE / TIMELINE HELPERS
// ============================================
const formatDate = (dateStr) => {
    if (!dateStr) return ""
    try {
        const date = new Date(dateStr)
        if (isNaN(date.getTime())) return dateStr
        const day = date.getDate()
        const months = [
            "January", "February", "March", "April", "May", "June",
            "July", "August", "September", "October", "November", "December",
        ]
        const month = months[date.getMonth()]
        const year = date.getFullYear()
        return `${day} ${month} ${year}`
    } catch (e) {
        return dateStr
    }
}

const toDateInputValue = (dateStr) => {
    if (!dateStr) return ""
    try {
        const date = new Date(dateStr)
        if (isNaN(date.getTime())) return ""
        return date.toISOString().split("T")[0]
    } catch (e) {
        return ""
    }
}

const calculateTimelineTotal = (timeline) => {
    if (!timeline || timeline.length === 0) return null

    let minTotal = 0
    let maxTotal = 0

    timeline.forEach((row) => {
        if (!row.duration) return

        const duration = row.duration
            .toLowerCase()
            .replace(/days?/gi, "")
            .trim()

        const rangeMatch = duration.match(/(\d+)\s*[-–]\s*(\d+)/)
        if (rangeMatch) {
            minTotal += parseInt(rangeMatch[1]) || 0
            maxTotal += parseInt(rangeMatch[2]) || 0
            return
        }

        const singleMatch = duration.match(/(\d+)/)
        if (singleMatch) {
            const num = parseInt(singleMatch[1]) || 0
            minTotal += num
            maxTotal += num
        }
    })

    if (minTotal === 0 && maxTotal === 0) return null

    if (minTotal === maxTotal) {
        return `${minTotal} days`
    }
    return `${minTotal}–${maxTotal} days`
}

// ============================================
// SHARED STYLES
// ============================================
const inputStyle = {
    width: "100%",
    padding: "12px 14px",
    borderRadius: 8,
    border: "1px solid #D1D5DB",
    fontSize: 14,
    outline: "none",
    boxSizing: "border-box",
}

const labelStyle = {
    fontSize: 12,
    fontWeight: 600,
    color: "#374151",
    marginBottom: 6,
    display: "block",
}

const cardStyle = {
    backgroundColor: "#FFF",
    borderRadius: 12,
    border: "1px solid #E5E7EB",
    marginBottom: 12,
}

// ============================================
// STATUS BADGE
// ============================================
function StatusBadge({ status, size = "normal" }) {
    const config = {
        draft: { bg: "#F3F4F6", color: "#6B7280", label: "Draft" },
        sent: { bg: "#FEF3C7", color: "#D97706", label: "Pending" },
        accepted: { bg: "#D1FAE5", color: "#059669", label: "Accepted" },
        rejected: { bg: "#FEE2E2", color: "#DC2626", label: "Rejected" },
        unpaid: { bg: "#FEF3C7", color: "#D97706", label: "Unpaid" },
        paid: { bg: "#D1FAE5", color: "#059669", label: "Paid" },
        overdue: { bg: "#FEE2E2", color: "#DC2626", label: "Overdue" },
    }
    const s = config[status] || config.draft
    const padding = size === "small" ? "4px 8px" : "6px 12px"
    const fontSize = size === "small" ? 11 : 12

    return (
        <span
            style={{
                padding,
                borderRadius: 20,
                fontSize,
                fontWeight: 600,
                backgroundColor: s.bg,
                color: s.color,
                display: "inline-block",
            }}
        >
            {s.label}
        </span>
    )
}

// ============================================
// STATUS SELECTOR (for editing status)
// ============================================
function StatusSelector({ currentStatus, type, onStatusChange, isPublicView }) {
    const [isOpen, setIsOpen] = useState(false)

    const quotationStatuses = [
        { value: "draft", label: "Draft", bg: "#F3F4F6", color: "#6B7280" },
        { value: "sent", label: "Pending", bg: "#FEF3C7", color: "#D97706" },
        { value: "accepted", label: "Accepted", bg: "#D1FAE5", color: "#059669" },
        { value: "rejected", label: "Rejected", bg: "#FEE2E2", color: "#DC2626" },
    ]

    const invoiceStatuses = [
        { value: "unpaid", label: "Unpaid", bg: "#FEF3C7", color: "#D97706" },
        { value: "paid", label: "Paid", bg: "#D1FAE5", color: "#059669" },
        { value: "overdue", label: "Overdue", bg: "#FEE2E2", color: "#DC2626" },
    ]

    const statuses = type === "quotation" ? quotationStatuses : invoiceStatuses
    const current =
        statuses.find((s) => s.value === currentStatus) || statuses[0]

    if (isPublicView) {
        return <StatusBadge status={currentStatus} />
    }

    return (
        <div style={{ position: "relative" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <StatusBadge status={currentStatus} />
                <button
                    onClick={() => setIsOpen(!isOpen)}
                    style={{
                        padding: "4px 8px",
                        borderRadius: 6,
                        border: "1px solid #E5E7EB",
                        backgroundColor: "#FFF",
                        color: "#6B7280",
                        fontSize: 11,
                        cursor: "pointer",
                        display: "flex",
                        alignItems: "center",
                        gap: 4,
                    }}
                >
                    <Icon name="edit" size={12} />
                    Edit
                </button>
            </div>

            {isOpen && (
                <>
                    <div
                        onClick={() => setIsOpen(false)}
                        style={{
                            position: "fixed",
                            top: 0,
                            left: 0,
                            right: 0,
                            bottom: 0,
                            zIndex: 998,
                        }}
                    />

                    <div
                        style={{
                            position: "absolute",
                            top: "100%",
                            right: 0,
                            marginTop: 4,
                            backgroundColor: "#FFF",
                            borderRadius: 10,
                            boxShadow: "0 4px 20px rgba(0,0,0,0.15)",
                            border: "1px solid #E5E7EB",
                            zIndex: 999,
                            minWidth: 140,
                            overflow: "hidden",
                        }}
                    >
                        {statuses.map((status) => (
                            <button
                                key={status.value}
                                onClick={() => {
                                    onStatusChange(status.value)
                                    setIsOpen(false)
                                }}
                                style={{
                                    width: "100%",
                                    padding: "10px 14px",
                                    border: "none",
                                    backgroundColor:
                                        currentStatus === status.value
                                            ? "#F3F4F6"
                                            : "#FFF",
                                    cursor: "pointer",
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 10,
                                    fontSize: 13,
                                }}
                            >
                                <span
                                    style={{
                                        width: 10,
                                        height: 10,
                                        borderRadius: "50%",
                                        backgroundColor: status.color,
                                    }}
                                />
                                <span
                                    style={{
                                        color: "#374151",
                                        fontWeight:
                                            currentStatus === status.value
                                                ? 600
                                                : 400,
                                    }}
                                >
                                    {status.label}
                                </span>
                                {currentStatus === status.value && (
                                    <span
                                        style={{
                                            marginLeft: "auto",
                                            color: "#10B981",
                                            display: "flex",
                                        }}
                                    >
                                        <Icon name="check" size={14} />
                                    </span>
                                )}
                            </button>
                        ))}
                    </div>
                </>
            )}
        </div>
    )
}

// ============================================
// LOGO DISPLAY COMPONENT
// ============================================
function LogoDisplay({
    logo,
    size = 32,
    bgColor = "#FFF",
    textColor = "#F97316",
    rounded = 6,
}) {
    const style = {
        width: size,
        height: size,
        borderRadius: rounded,
        background: bgColor,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        color: textColor,
        fontWeight: 700,
        fontSize: size * 0.375,
        flexShrink: 0,
        overflow: "hidden",
    }

    if (logo) {
        return (
            <div style={style}>
                <img
                    src={logo}
                    alt="Logo"
                    style={{
                        width: "100%",
                        height: "100%",
                        objectFit: "cover",
                    }}
                />
            </div>
        )
    }

    return <div style={style}>CS</div>
}

// ============================================
// ICON — Lucide (MIT) inline SVG, no emoji
// https://lucide.dev
// ============================================
const ICON_PATHS = {
    printer:
        '<polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/>',
    share:
        '<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/>',
    edit:
        '<path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4Z"/>',
    copy:
        '<rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/>',
    file:
        '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/>',
    trash:
        '<polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',
    search:
        '<circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/>',
    refresh:
        '<polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>',
    logout:
        '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>',
    "chevron-left": '<polyline points="15 18 9 12 15 6"/>',
    "chevron-right": '<polyline points="9 18 15 12 9 6"/>',
    "chevron-up": '<polyline points="18 15 12 9 6 15"/>',
    "chevron-down": '<polyline points="6 9 12 15 18 9"/>',
    "arrow-left":
        '<line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/>',
    plus: '<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>',
    check: '<polyline points="20 6 9 17 4 12"/>',
    "check-circle":
        '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/>',
    clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
    lock:
        '<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
    x: '<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>',
    grip:
        '<circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/>',
    user:
        '<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',
    clipboard:
        '<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><path d="M12 11h4"/><path d="M12 16h4"/><path d="M8 11h.01"/><path d="M8 16h.01"/>',
    calendar:
        '<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>',
    dollar:
        '<line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>',
    "credit-card":
        '<rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/>',
    "file-plus":
        '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="12" y1="18" x2="12" y2="12"/><line x1="9" y1="15" x2="15" y2="15"/>',
    send:
        '<line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/>',
    pin:
        '<line x1="12" x2="12" y1="17" y2="22"/><path d="M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24Z"/>',
    "trending-up":
        '<polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/>',
    receipt:
        '<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/><path d="M12 17.5v-11"/>',
    circle: '<circle cx="12" cy="12" r="10"/>',
    "dot-circle":
        '<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="3" fill="currentColor"/>',
    "list-checks":
        '<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>',
}

function Icon({ name, size = 16, color = "currentColor", strokeWidth = 2, style }) {
    const path = ICON_PATHS[name]
    if (!path) return null
    return (
        <svg
            width={size}
            height={size}
            viewBox="0 0 24 24"
            fill="none"
            stroke={color}
            strokeWidth={strokeWidth}
            strokeLinecap="round"
            strokeLinejoin="round"
            style={{ flexShrink: 0, display: "inline-block", verticalAlign: "middle", ...style }}
            dangerouslySetInnerHTML={{ __html: path }}
        />
    )
}

// Expose shared symbols for other Babel-compiled files (each runs in its own scope)
Object.assign(window, {
    useState: React.useState,
    useEffect: React.useEffect,
    useRef: React.useRef,
    COMPANY_LOGO,
    API_BASE,
    companyInfo,
    bankDetails,
    initialQuotations,
    initialInvoices,
    api,
    generatePDF,
    formatDate,
    toDateInputValue,
    calculateTimelineTotal,
    inputStyle,
    labelStyle,
    cardStyle,
    StatusBadge,
    StatusSelector,
    LogoDisplay,
    Icon,
})
