/**
 * File upload component for collaboration forms
 * Provides drag-and-drop file upload, file list display, and file management.
 *
 * Uses FileManagerCallbacks for upload/remove operations and FormFileAttachment
 * as the data shape stored in form_data.
 */
'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useRef, useState, useCallback } from 'react';
import { cn } from '../utils/cn.js';
import { use_logger } from '../logger/context.js';
import { optional_import } from '../utils/optional_import.js';
import { HiTrash, HiDocument, HiDocumentText, HiCheckCircle, HiLockClosed, HiLockOpen, HiRefresh, HiEye, HiExclamationCircle, HiCloudUpload } from 'react-icons/hi';
import { FaSpinner } from 'react-icons/fa';
import { ClarificationDialog } from './clarification/clarification_dialog.js';
/**
 * Get file icon based on MIME type and filename
 */
function get_file_icon(mime_type, file_name) {
    const extension = (file_name || '').split('.').pop()?.toLowerCase() || '';
    const mime = (mime_type || '').toLowerCase();
    if (mime === 'application/pdf' || extension === 'pdf') {
        return _jsx(HiDocument, { className: "h-8 w-8 text-sky-500" });
    }
    return _jsx(HiDocumentText, { className: "h-8 w-8 text-sky-500" });
}
/**
 * Format file size for display
 */
function format_file_size(bytes) {
    if (bytes === 0)
        return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
}
/**
 * Get status badge for a file
 */
function StatusBadge({ status }) {
    if (!status || status === 'active')
        return null;
    const config = {
        missing: { label: 'Missing', className: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300' },
        soft_deleted: { label: 'Deleted', className: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300' },
        orphaned: { label: 'Orphaned', className: 'bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300' },
    };
    const cfg = config[status];
    if (!cfg)
        return null;
    return (_jsx("span", { className: cn('text-[10px] px-1 py-0.5 rounded font-medium', cfg.className), children: cfg.label }));
}
/**
 * Collaboration form file upload component
 */
export function CollabFormFileUpload({ field_id_final, accept_files_public = false, accept_files_private = false, files_dir, max_size, min_files, max_files = 10, file_accept, file_validator, file_manager, files: controlled_files, on_files_change, private_files: controlled_private_files, on_private_files_change, private_files_permission, can_access_private_files: can_access_private_files_prop, show_file_status = false, allow_reupload = false, file_statuses = {}, scope_id, uploaded_by, validating_file_ids, error_file_ids, passed_file_ids, error_file_details, clarification_items, clarification_callbacks, private_files_class_name, default_file_accordion_open = false, hide_upload_dropzone = false, autofill_dropzone, }) {
    const logger = use_logger();
    const file_input_ref = useRef(null);
    const private_file_input_ref = useRef(null);
    const [internal_files, set_internal_files] = useState([]);
    const [internal_private_files, set_internal_private_files] = useState([]);
    const [is_dragging, set_is_dragging] = useState(false);
    const [is_dragging_private, set_is_dragging_private] = useState(false);
    const [upload_errors, set_upload_errors] = useState({});
    const [uploading_files, set_uploading_files] = useState(new Set());
    const [has_permission, set_has_permission] = useState(false);
    const [permission_loading, set_permission_loading] = useState(true);
    // Use controlled files if provided, otherwise use internal state
    const files = controlled_files !== undefined ? controlled_files : internal_files;
    const is_controlled = controlled_files !== undefined;
    const private_files = controlled_private_files !== undefined ? controlled_private_files : internal_private_files;
    const is_private_controlled = controlled_private_files !== undefined;
    // Check permission for private files
    React.useEffect(() => {
        if (!accept_files_private) {
            set_permission_loading(false);
            set_has_permission(false);
            return;
        }
        if (can_access_private_files_prop !== undefined) {
            set_has_permission(can_access_private_files_prop);
            set_permission_loading(false);
            return;
        }
        // Without explicit prop, default to false for private files
        set_permission_loading(false);
        set_has_permission(false);
    }, [accept_files_private, can_access_private_files_prop]);
    const show_private_section = !!(accept_files_private && has_permission && !permission_loading);
    /**
     * Update files state (public files)
     */
    const update_files = useCallback((new_files) => {
        if (!is_controlled) {
            set_internal_files(new_files);
        }
        on_files_change?.(new_files);
    }, [is_controlled, on_files_change]);
    /**
     * Update private files state
     */
    const update_private_files = useCallback((new_files) => {
        if (!is_private_controlled) {
            set_internal_private_files(new_files);
        }
        on_private_files_change?.(new_files);
    }, [is_private_controlled, on_private_files_change]);
    /**
     * Toggle file visibility (move between public and private)
     */
    const toggle_file_visibility = useCallback((file_id, current_visibility) => {
        if (current_visibility === 'public') {
            const file_to_move = files.find(f => f.file_id === file_id);
            if (file_to_move) {
                update_files(files.filter(f => f.file_id !== file_id));
                update_private_files([...private_files, { ...file_to_move, visibility: 'private' }]);
            }
        }
        else {
            const file_to_move = private_files.find(f => f.file_id === file_id);
            if (file_to_move) {
                update_private_files(private_files.filter(f => f.file_id !== file_id));
                update_files([...files, { ...file_to_move, visibility: 'public' }]);
            }
        }
    }, [files, private_files, update_files, update_private_files]);
    /**
     * Validate file before upload
     */
    const validate_file = useCallback((file) => {
        if (file_validator) {
            const custom_error = file_validator(file);
            if (custom_error)
                return custom_error;
        }
        if (files.length >= max_files) {
            return `Maximum ${max_files} files allowed`;
        }
        if (max_size && file.size > max_size) {
            return `File size exceeds maximum of ${format_file_size(max_size)}`;
        }
        if (file_accept) {
            const accept_patterns = file_accept.split(',').map(p => p.trim());
            const file_extension = '.' + file.name.split('.').pop()?.toLowerCase();
            const file_mime = file.type;
            const matches = accept_patterns.some(pattern => {
                if (pattern.startsWith('.'))
                    return file_extension === pattern.toLowerCase();
                if (pattern.includes('/*'))
                    return file_mime.startsWith(pattern.split('/')[0] + '/');
                return file_mime === pattern;
            });
            if (!matches)
                return `File type not allowed. Accepted: ${file_accept}`;
        }
        return null;
    }, [files.length, max_files, max_size, file_accept, file_validator]);
    /**
     * Upload file via file_manager.upload callback
     */
    const upload_file = useCallback(async (file, visibility = 'public') => {
        const uploading_id = `${Date.now()}-${file.name}`;
        try {
            set_uploading_files(prev => new Set(prev).add(uploading_id));
            const attachment = await file_manager.upload(file, {
                entity_type: 'form_field',
                entity_id: field_id_final,
                visibility,
                scope_id,
                uploaded_by,
                metadata: files_dir ? { files_dir } : undefined,
            });
            set_upload_errors(prev => {
                const next = { ...prev };
                delete next[uploading_id];
                return next;
            });
            return attachment;
        }
        catch (error) {
            const error_message = error instanceof Error ? error.message : 'Upload failed';
            set_upload_errors(prev => ({ ...prev, [uploading_id]: error_message }));
            return null;
        }
        finally {
            set_uploading_files(prev => {
                const next = new Set(prev);
                next.delete(uploading_id);
                return next;
            });
        }
    }, [field_id_final, file_manager, files_dir, scope_id, uploaded_by]);
    /**
     * Handle file selection (public files)
     */
    const handle_files_selected = useCallback(async (selected_files) => {
        if (!selected_files || selected_files.length === 0)
            return;
        const files_to_upload = [];
        const errors = {};
        Array.from(selected_files).forEach(file => {
            const error = validate_file(file);
            if (error) {
                errors[file.name] = error;
            }
            else {
                files_to_upload.push(file);
            }
        });
        if (Object.keys(errors).length > 0) {
            set_upload_errors(prev => ({ ...prev, ...errors }));
        }
        const upload_promises = files_to_upload.map(file => upload_file(file, 'public'));
        const uploaded = await Promise.all(upload_promises);
        const successful = uploaded.filter((f) => f !== null);
        if (successful.length > 0) {
            update_files([...files, ...successful]);
        }
    }, [files, validate_file, upload_file, update_files]);
    /**
     * Handle private file selection
     */
    const handle_private_files_selected = useCallback(async (selected_files) => {
        if (!selected_files || selected_files.length === 0)
            return;
        const files_to_upload = [];
        const errors = {};
        Array.from(selected_files).forEach(file => {
            const error = validate_file(file);
            if (error) {
                errors[file.name] = error;
            }
            else {
                files_to_upload.push(file);
            }
        });
        if (Object.keys(errors).length > 0) {
            set_upload_errors(prev => ({ ...prev, ...errors }));
        }
        const upload_promises = files_to_upload.map(file => upload_file(file, 'private'));
        const uploaded = await Promise.all(upload_promises);
        const successful = uploaded.filter((f) => f !== null);
        if (successful.length > 0) {
            update_private_files([...private_files, ...successful]);
        }
    }, [private_files, validate_file, upload_file, update_private_files]);
    // Drag handlers (public)
    const handle_drag_enter = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging(true);
    }, []);
    const handle_drag_leave = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging(false);
    }, []);
    const handle_drag_over = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
    }, []);
    const handle_drop = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging(false);
        handle_files_selected(e.dataTransfer.files);
    }, [handle_files_selected]);
    // Drag handlers (private)
    const handle_private_drag_enter = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging_private(true);
    }, []);
    const handle_private_drag_leave = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging_private(false);
    }, []);
    const handle_private_drop = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        set_is_dragging_private(false);
        handle_private_files_selected(e.dataTransfer.files);
    }, [handle_private_files_selected]);
    // Input handlers
    const handle_input_change = useCallback((e) => {
        handle_files_selected(e.target.files);
        if (file_input_ref.current)
            file_input_ref.current.value = '';
    }, [handle_files_selected]);
    const handle_private_input_change = useCallback((e) => {
        handle_private_files_selected(e.target.files);
        if (private_file_input_ref.current)
            private_file_input_ref.current.value = '';
    }, [handle_private_files_selected]);
    /**
     * Handle file delete — calls file_manager.remove then updates state
     */
    const handle_delete_file = useCallback(async (file_id) => {
        const file = files.find(f => f.file_id === file_id);
        if (!file)
            return;
        if (min_files !== undefined && files.length <= min_files) {
            set_upload_errors(prev => ({ ...prev, delete_error: `Minimum ${min_files} files required` }));
            return;
        }
        try {
            await file_manager.remove(file.file_id, file.ref_id);
        }
        catch (error) {
            logger.warn('[CollabFormFileUpload] Error removing file reference', {
                file_id, ref_id: file.ref_id,
                error: error instanceof Error ? error.message : String(error),
            });
        }
        update_files(files.filter(f => f.file_id !== file_id));
        set_upload_errors(prev => { const next = { ...prev }; delete next.delete_error; return next; });
        // Remove clarifications that reference this file
        if (clarification_items && clarification_callbacks?.on_doc_delete) {
            for (const item of clarification_items) {
                if (item.doc_references.some(ref => ref.file_id === file_id)) {
                    clarification_callbacks.on_doc_delete(item.id, file_id);
                }
            }
        }
    }, [files, min_files, update_files, file_manager, logger, clarification_items, clarification_callbacks]);
    /**
     * Handle private file delete
     */
    const handle_delete_private_file = useCallback(async (file_id) => {
        const file = private_files.find(f => f.file_id === file_id);
        if (!file)
            return;
        try {
            await file_manager.remove(file.file_id, file.ref_id);
        }
        catch (error) {
            logger.warn('[CollabFormFileUpload] Error removing private file reference', {
                file_id, ref_id: file.ref_id,
                error: error instanceof Error ? error.message : String(error),
            });
        }
        update_private_files(private_files.filter(f => f.file_id !== file_id));
        // Remove clarifications that reference this file
        if (clarification_items && clarification_callbacks?.on_doc_delete) {
            for (const item of clarification_items) {
                if (item.doc_references.some(ref => ref.file_id === file_id)) {
                    clarification_callbacks.on_doc_delete(item.id, file_id);
                }
            }
        }
    }, [private_files, update_private_files, file_manager, logger, clarification_items, clarification_callbacks]);
    /**
     * Handle re-upload for a missing file
     */
    const handle_reupload = useCallback(async (original_file_id, visibility) => {
        if (!file_manager.reupload)
            return;
        // Create a file input and trigger selection
        const input = document.createElement('input');
        input.type = 'file';
        if (file_accept)
            input.accept = file_accept;
        input.onchange = async () => {
            const file = input.files?.[0];
            if (!file)
                return;
            const uploading_id = `reupload-${original_file_id}`;
            set_uploading_files(prev => new Set(prev).add(uploading_id));
            try {
                const new_attachment = await file_manager.reupload(file, original_file_id, {
                    entity_type: 'form_field',
                    entity_id: field_id_final,
                    visibility,
                    scope_id,
                    uploaded_by,
                });
                // Replace the old attachment with the new one
                if (visibility === 'public') {
                    update_files(files.map(f => f.file_id === original_file_id ? new_attachment : f));
                }
                else {
                    update_private_files(private_files.map(f => f.file_id === original_file_id ? new_attachment : f));
                }
            }
            catch (error) {
                set_upload_errors(prev => ({
                    ...prev,
                    [uploading_id]: error instanceof Error ? error.message : 'Re-upload failed',
                }));
            }
            finally {
                set_uploading_files(prev => {
                    const next = new Set(prev);
                    next.delete(uploading_id);
                    return next;
                });
            }
        };
        input.click();
    }, [file_manager, field_id_final, file_accept, scope_id, uploaded_by, files, private_files, update_files, update_private_files]);
    /**
     * Get download URL for a file
     */
    const get_file_url = useCallback((attachment) => {
        return file_manager.get_download_url(attachment.file_id, attachment.visibility);
    }, [file_manager]);
    /** Simple file_id → URL resolver for ClarificationDialog */
    const get_download_url_by_id = useCallback((file_id) => {
        return file_manager.get_download_url(file_id);
    }, [file_manager]);
    // Build accordion title
    const accordion_title = accept_files_public && show_private_section
        ? `Files (${files.length} public, ${private_files.length} private)`
        : show_private_section && !accept_files_public
            ? private_files.length > 0 ? `Private Files (${private_files.length})` : 'Private Files'
            : files.length > 0 ? `Files (${files.length})` : 'Files';
    return (_jsx("div", { className: "cls_collab_file_upload space-y-2", suppressHydrationWarning: true, children: (accept_files_public || accept_files_private) ? (_jsx(FileUploadAccordion, { field_id_final: field_id_final, title: accordion_title, is_dragging: is_dragging, on_drag_enter: handle_drag_enter, on_drag_leave: handle_drag_leave, on_drag_over: handle_drag_over, on_drop: handle_drop, file_input_ref: file_input_ref, file_accept: file_accept, on_input_change: handle_input_change, files: files, uploading_files: uploading_files, upload_errors: upload_errors, get_file_url: get_file_url, on_file_delete: handle_delete_file, format_file_size: format_file_size, max_files: max_files, min_files: min_files, accept_files_public: accept_files_public, show_private_section: show_private_section, private_files: private_files, private_file_input_ref: private_file_input_ref, is_dragging_private: is_dragging_private, on_private_drag_enter: handle_private_drag_enter, on_private_drag_leave: handle_private_drag_leave, on_private_drop: handle_private_drop, on_private_input_change: handle_private_input_change, on_private_file_delete: handle_delete_private_file, on_toggle_visibility: toggle_file_visibility, show_file_status: show_file_status, allow_reupload: allow_reupload, file_statuses: file_statuses, on_reupload: handle_reupload, validating_file_ids: validating_file_ids, error_file_ids: error_file_ids, passed_file_ids: passed_file_ids, error_file_details: error_file_details, clarification_items: clarification_items, clarification_callbacks: clarification_callbacks, get_download_url: get_download_url_by_id, private_files_class_name: private_files_class_name, default_file_accordion_open: default_file_accordion_open, hide_upload_dropzone: hide_upload_dropzone, autofill_dropzone: autofill_dropzone })) : null }));
}
/**
 * PDF Preview Dialog - wraps hazo_pdf PdfViewer in a full-screen Radix Dialog.
 * PdfViewer is passed as a prop to avoid hard dependency on hazo_pdf.
 */
function PdfPreviewDialog({ PdfViewerComponent, open, on_close, url, file_name, }) {
    const [DialogPrimitive, set_dialog_primitive] = React.useState(null);
    React.useEffect(() => {
        import('@radix-ui/react-dialog').then((mod) => {
            set_dialog_primitive(mod);
        }).catch(() => {
            // Dialog not available
        });
    }, []);
    if (!DialogPrimitive)
        return null;
    const fullScreenStyles = {
        position: 'fixed',
        top: '16px',
        left: '16px',
        right: '16px',
        bottom: '16px',
        width: 'calc(100vw - 32px)',
        height: 'calc(100vh - 32px)',
        maxWidth: 'none',
        maxHeight: 'none',
        transform: 'none',
        display: 'flex',
        flexDirection: 'column',
        zIndex: 50,
        backgroundColor: 'hsl(var(--background, 0 0% 100%))',
        borderRadius: '8px',
        overflow: 'hidden',
    };
    return (_jsx(DialogPrimitive.Root, { open: open, onOpenChange: (o) => { if (!o)
            on_close(); }, children: _jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Overlay, { style: { position: 'fixed', inset: 0, zIndex: 50, backgroundColor: 'rgba(0,0,0,0.5)' } }), _jsxs(DialogPrimitive.Content, { style: fullScreenStyles, "aria-describedby": undefined, children: [_jsx(DialogPrimitive.Title, { className: "sr-only", children: file_name }), _jsx("div", { style: { width: '100%', height: '100%' }, children: _jsx(PdfViewerComponent, { url: url, display_filename: file_name, fit_to_width: true, toolbar_enabled: true, on_close: on_close, className: "h-full w-full" }) })] })] }) }));
}
/**
 * File upload accordion component with dynamic imports
 */
function FileUploadAccordion({ field_id_final, title, is_dragging, on_drag_enter, on_drag_leave, on_drag_over, on_drop, file_input_ref, file_accept, on_input_change, files, uploading_files, upload_errors, get_file_url, on_file_delete, format_file_size, max_files, min_files, accept_files_public = false, show_private_section = false, private_files = [], private_file_input_ref, is_dragging_private = false, on_private_drag_enter, on_private_drag_leave, on_private_drop, on_private_input_change, on_private_file_delete, on_toggle_visibility, show_file_status = false, allow_reupload = false, file_statuses = {}, on_reupload, validating_file_ids, error_file_ids, passed_file_ids, error_file_details, clarification_items, clarification_callbacks, get_download_url, private_files_class_name, default_file_accordion_open = false, hide_upload_dropzone = false, autofill_dropzone, }) {
    const logger = use_logger();
    const [AccordionComponents, set_accordion_components] = React.useState(null);
    const [is_loading, set_is_loading] = React.useState(true);
    const [is_mounted, set_is_mounted] = React.useState(false);
    // PDF preview state
    const [preview_file, set_preview_file] = React.useState(null);
    const [PdfViewer, set_pdf_viewer] = React.useState(null);
    // Clarification dialog state - tracks which file_id's issues dialog is open
    const [issues_dialog_file_id, set_issues_dialog_file_id] = React.useState(null);
    React.useEffect(() => { set_is_mounted(true); }, []);
    // Try to load PdfViewer from hazo_pdf (optional peer dependency)
    React.useEffect(() => {
        if (!is_mounted)
            return;
        optional_import('hazo_pdf').then((mod) => {
            if (mod.PdfViewer) {
                set_pdf_viewer(() => mod.PdfViewer);
            }
        }).catch(() => {
            // hazo_pdf not installed — PDF preview disabled
        });
    }, [is_mounted]);
    // Controlled accordion state + auto-open when files are added
    const [accordion_value, set_accordion_value] = React.useState((files.length > 0 || default_file_accordion_open) ? 'files' : undefined);
    const prev_files_count = React.useRef(files.length);
    React.useEffect(() => {
        if (prev_files_count.current === 0 && files.length > 0) {
            set_accordion_value('files');
        }
        prev_files_count.current = files.length;
    }, [files.length]);
    React.useEffect(() => {
        if (!is_mounted)
            return;
        const load_accordion = async () => {
            try {
                set_is_loading(true);
                const accordion_module = await import('hazo_ui').catch(() => null);
                if (accordion_module) {
                    set_accordion_components({
                        Accordion: accordion_module.Accordion,
                        AccordionItem: accordion_module.AccordionItem,
                        AccordionTrigger: accordion_module.AccordionTrigger,
                        AccordionContent: accordion_module.AccordionContent,
                    });
                }
                else {
                    logger.warn('[CollabFormFileUpload] shadcn Accordion not found', {
                        install_command: 'npx shadcn@latest add accordion',
                    });
                }
            }
            catch (error) {
                logger.warn('[CollabFormFileUpload] Error loading accordion components', {
                    error: error instanceof Error ? error.message : String(error),
                });
            }
            finally {
                set_is_loading(false);
            }
        };
        load_accordion();
    }, [is_mounted]);
    if (!is_mounted || is_loading || !AccordionComponents) {
        return (_jsx("div", { className: "cls_collab_file_upload_loading text-sm text-muted-foreground", suppressHydrationWarning: true }));
    }
    const { Accordion, AccordionItem, AccordionTrigger, AccordionContent } = AccordionComponents;
    const is_files_required = min_files !== undefined && min_files >= 1;
    /**
     * Render a single file item
     */
    const render_file_item = (attachment, visibility, delete_handler) => {
        const is_uploading = Array.from(uploading_files).some(id => id.includes(attachment.file_id) || id.includes(attachment.file_name));
        const file_status = file_statuses[attachment.file_id] ?? attachment.status;
        const is_missing = file_status === 'missing';
        const has_error = error_file_ids?.has(attachment.file_id);
        const has_passed = !has_error && passed_file_ids?.has(attachment.file_id);
        const error_details = error_file_details?.[attachment.file_id];
        return (_jsxs("div", { className: cn("cls_collab_file_item flex-shrink-0 w-24 flex flex-col items-center gap-1 p-2 border rounded-md hover:bg-muted transition-colors relative", has_error && "border-red-300 dark:border-red-800", has_passed && "border-green-300 dark:border-green-800"), children: [_jsxs("a", { href: get_file_url(attachment), target: "_blank", rel: "noopener noreferrer", className: cn("flex flex-col items-center gap-1 w-full", (is_uploading || is_missing) && "pointer-events-none opacity-50"), "aria-disabled": is_uploading || is_missing, children: [_jsxs("div", { className: "relative", children: [get_file_icon(attachment.mime_type, attachment.file_name), has_error && (_jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 rounded-full bg-red-500 text-white text-[9px] font-bold", children: "!" })), has_passed && (_jsx("span", { className: "absolute -top-1 -right-1 flex items-center justify-center w-4 h-4 rounded-full bg-green-500 text-white", children: _jsx(HiCheckCircle, { className: "h-4 w-4" }) }))] }), _jsx("span", { className: "text-xs text-center truncate w-full", title: attachment.file_name, children: attachment.file_name }), _jsx("span", { className: "text-xs text-muted-foreground", children: format_file_size(attachment.file_size) })] }), show_file_status && file_status && file_status !== 'active' && (_jsx(StatusBadge, { status: file_status })), has_error && error_details && error_details.length > 0 && (_jsxs("button", { type: "button", onClick: () => set_issues_dialog_file_id(attachment.file_id), className: "flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded bg-red-100 text-red-700 hover:bg-red-200 dark:bg-red-900/30 dark:text-red-400 dark:hover:bg-red-900/50 transition-colors", title: "View validation issues", children: [_jsx(HiExclamationCircle, { className: "h-3 w-3 flex-shrink-0" }), error_details.length, " ", error_details.length === 1 ? 'issue' : 'issues'] })), _jsxs("div", { className: "flex items-center gap-1", children: [PdfViewer && !is_missing && (() => {
                            const ext = (attachment.file_name || '').split('.').pop()?.toLowerCase() || '';
                            const mime = (attachment.mime_type || '').toLowerCase();
                            const is_previewable = mime === 'application/pdf' || ext === 'pdf'
                                || mime.startsWith('image/') || ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext);
                            return is_previewable ? (_jsx("button", { type: "button", onClick: (e) => {
                                    e.stopPropagation();
                                    set_preview_file(attachment);
                                }, className: "text-blue-500 hover:text-blue-600 p-1", title: "Preview file", "aria-label": `Preview ${attachment.file_name}`, children: _jsx(HiEye, { className: "h-4 w-4" }) })) : null;
                        })(), allow_reupload && is_missing && on_reupload && (_jsx("button", { type: "button", onClick: () => on_reupload(attachment.file_id, visibility), className: "text-blue-600 hover:text-blue-700 p-1", title: "Re-upload file", "aria-label": `Re-upload ${attachment.file_name}`, children: _jsx(HiRefresh, { className: "h-4 w-4" }) })), accept_files_public && show_private_section && on_toggle_visibility && (_jsx("button", { type: "button", onClick: () => on_toggle_visibility(attachment.file_id, visibility), className: cn("p-1 transition-colors", visibility === 'private'
                                ? "text-amber-600 hover:text-amber-700"
                                : "text-muted-foreground hover:text-foreground"), disabled: is_uploading, "aria-label": visibility === 'private' ? `Make ${attachment.file_name} public` : `Make ${attachment.file_name} private`, title: visibility === 'private' ? 'Make public' : 'Make private', children: visibility === 'private' ? (_jsx(HiLockClosed, { className: "h-4 w-4" })) : (_jsx(HiLockOpen, { className: "h-4 w-4" })) })), _jsx("button", { type: "button", onClick: () => delete_handler(attachment.file_id), className: "text-destructive hover:text-destructive/80 p-1", disabled: is_uploading, "aria-label": `Delete ${attachment.file_name}`, children: _jsx(HiTrash, { className: "h-4 w-4" }) })] }), is_uploading && (_jsx("div", { className: "absolute inset-0 bg-background/50 flex items-center justify-center rounded-md", children: _jsx("div", { className: "text-xs text-muted-foreground", children: "Uploading..." }) })), !is_uploading && validating_file_ids?.has(attachment.file_id) && (_jsx("div", { className: "absolute inset-0 bg-background/50 flex items-center justify-center rounded-md", children: _jsxs("div", { className: "flex flex-col items-center gap-1", children: [_jsx(FaSpinner, { className: "h-4 w-4 animate-spin text-amber-500" }), _jsx("span", { className: "text-xs text-muted-foreground", children: "Validating..." })] }) }))] }, attachment.file_id));
    };
    /**
     * Render file upload section (drop zone + file list)
     */
    const render_file_section = (section_type, section_files, section_is_dragging, section_on_drag_enter, section_on_drag_leave, section_on_drop, section_file_input_ref, section_on_input_change, section_on_delete, input_id_suffix) => (_jsxs("div", { className: "space-y-3", children: [autofill_dropzone && section_type === 'public' ? (autofill_dropzone) : !hide_upload_dropzone && (_jsxs("div", { className: cn('cls_collab_file_drop_zone border-2 border-dashed rounded-md p-4 text-center transition-colors', section_is_dragging
                    ? 'border-primary bg-primary/5'
                    : 'border-input hover:border-primary/50 hover:bg-muted/50', section_files.length >= max_files && 'opacity-50 cursor-not-allowed'), onDragEnter: section_on_drag_enter, onDragLeave: section_on_drag_leave, onDragOver: on_drag_over, onDrop: section_on_drop, children: [_jsx("input", { ref: section_file_input_ref, type: "file", id: `${field_id_final}-${input_id_suffix}`, className: "hidden", accept: file_accept, multiple: true, onChange: section_on_input_change, disabled: section_files.length >= max_files }), _jsxs("label", { htmlFor: `${field_id_final}-${input_id_suffix}`, className: cn('cursor-pointer flex flex-col items-center justify-center gap-1', section_files.length >= max_files && 'cursor-not-allowed opacity-50'), children: [_jsx(HiCloudUpload, { className: "h-5 w-5 text-muted-foreground" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Drag and drop files here, or click to select" }), file_accept && (_jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: ["Accepted: ", file_accept] }))] })] })), section_files.length > 0 && (_jsx("div", { className: "cls_collab_file_list", children: _jsx("div", { className: "flex overflow-x-auto gap-2 pb-2", children: section_files.map(attachment => render_file_item(attachment, section_type, section_on_delete)) }) }))] }));
    return (_jsxs("div", { suppressHydrationWarning: true, children: [_jsx(Accordion, { type: "single", collapsible: true, value: accordion_value, onValueChange: set_accordion_value, className: "w-full", children: _jsxs(AccordionItem, { value: "files", children: [_jsxs(AccordionTrigger, { className: "text-sm font-medium", children: [title, is_files_required && _jsx("span", { className: "text-destructive ml-1", children: "*" })] }), _jsx(AccordionContent, { children: _jsxs("div", { className: "space-y-4", children: [Object.keys(upload_errors).length > 0 && (_jsx("div", { className: "space-y-1", children: Object.entries(upload_errors).map(([key, error]) => (_jsx("p", { className: "text-sm text-destructive", children: error }, key))) })), accept_files_public && show_private_section ? (_jsxs(Accordion, { type: "multiple", defaultValue: ['public-files', 'private-files'], className: "w-full", children: [_jsxs(AccordionItem, { value: "public-files", className: "border-b-0", children: [_jsx(AccordionTrigger, { className: "text-sm font-medium py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(HiLockOpen, { className: "h-4 w-4 text-muted-foreground" }), _jsxs("span", { children: ["Public Files (", files.length, ")"] })] }) }), _jsx(AccordionContent, { className: "pb-4", children: render_file_section('public', files, is_dragging, on_drag_enter, on_drag_leave, on_drop, file_input_ref, on_input_change, on_file_delete, 'public-file-input') })] }), _jsxs(AccordionItem, { value: "private-files", className: "border-b-0", children: [_jsx(AccordionTrigger, { className: "text-sm font-medium py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(HiLockClosed, { className: "h-4 w-4 text-amber-600" }), _jsxs("span", { children: ["Private Files (", private_files.length, ")"] })] }) }), _jsx(AccordionContent, { className: "pb-4", children: _jsx("div", { className: cn('rounded-md p-3', private_files_class_name || 'bg-muted'), children: private_file_input_ref && on_private_drag_enter && on_private_drag_leave && on_private_drop && on_private_input_change && on_private_file_delete && render_file_section('private', private_files, is_dragging_private, on_private_drag_enter, on_private_drag_leave, on_private_drop, private_file_input_ref, on_private_input_change, on_private_file_delete, 'private-file-input') }) })] })] })) : show_private_section && !accept_files_public ? (_jsxs("div", { className: cn('rounded-md p-3 space-y-4', private_files_class_name || 'bg-muted'), children: [_jsxs("div", { className: "flex items-center gap-2 text-sm text-amber-600 mb-2", children: [_jsx(HiLockClosed, { className: "h-4 w-4" }), _jsx("span", { className: "font-medium", children: "Private Files" })] }), private_file_input_ref && on_private_drag_enter && on_private_drag_leave && on_private_drop && on_private_input_change && on_private_file_delete && render_file_section('private', private_files, is_dragging_private, on_private_drag_enter, on_private_drag_leave, on_private_drop, private_file_input_ref, on_private_input_change, on_private_file_delete, 'private-file-input')] })) : accept_files_public ? (_jsxs("div", { className: "space-y-4", children: [autofill_dropzone ? (autofill_dropzone) : !hide_upload_dropzone && (_jsxs("div", { className: cn('cls_collab_file_drop_zone border-2 border-dashed rounded-md p-6 text-center transition-colors', is_dragging
                                                    ? 'border-primary bg-primary/5'
                                                    : 'border-input hover:border-primary/50 hover:bg-muted/50', files.length >= max_files && 'opacity-50 cursor-not-allowed'), onDragEnter: on_drag_enter, onDragLeave: on_drag_leave, onDragOver: on_drag_over, onDrop: on_drop, children: [_jsx("input", { ref: file_input_ref, type: "file", id: `${field_id_final}-file-input`, className: "hidden", accept: file_accept, multiple: true, onChange: on_input_change, disabled: files.length >= max_files }), _jsxs("label", { htmlFor: `${field_id_final}-file-input`, className: cn('cursor-pointer flex flex-col items-center justify-center gap-1', files.length >= max_files && 'cursor-not-allowed opacity-50'), children: [_jsx(HiCloudUpload, { className: "h-5 w-5 text-muted-foreground" }), _jsx("p", { className: "text-sm text-muted-foreground", children: "Drag and drop files here, or click to select" }), file_accept && (_jsxs("p", { className: "text-xs text-muted-foreground", children: ["Accepted: ", file_accept] }))] })] })), files.length > 0 && (_jsx("div", { className: "cls_collab_file_list space-y-2", children: _jsx("div", { className: "flex overflow-x-auto gap-2 pb-2", children: files.map(attachment => render_file_item(attachment, 'public', on_file_delete)) }) }))] })) : null] }) })] }) }), PdfViewer && preview_file && (_jsx(PdfPreviewDialog, { PdfViewerComponent: PdfViewer, open: !!preview_file, on_close: () => set_preview_file(null), url: get_file_url(preview_file), file_name: preview_file.file_name })), issues_dialog_file_id && clarification_items && (() => {
                const file_clarifications = clarification_items.filter(item => (item.status === 'pending' || item.status === 'responded') &&
                    item.doc_references.some(ref => ref.file_id === issues_dialog_file_id));
                const file_attachment = [...files, ...private_files].find(f => f.file_id === issues_dialog_file_id);
                const file_label = file_attachment?.file_name ?? 'File';
                return (_jsx(ClarificationDialog, { open: true, on_open_change: (open) => { if (!open)
                        set_issues_dialog_file_id(null); }, field_label: file_label, items: file_clarifications, read_only: !clarification_callbacks, callbacks: clarification_callbacks, get_download_url: get_download_url }));
            })()] }));
}
//# sourceMappingURL=collab_form_file_upload.js.map