import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { useNomenclatureData } from '../../contexts/NomenclatureDataContext';
import { useAuth } from '../../contexts/AuthContext';
import FormOverlay from './FormOverlay';
import NomenclatureEntryForm from './NomenclatureEntryForm';
import './NomenclatureManagementOverlay.css';

export default function NomenclatureManagementOverlay({
    nomenclatureCode,
    isOpen,
    onClose,
    mode = 'manage',          // 'manage' or 'select'
    initialSelection = null,  // entry ID to pre-select
    onSelect,                 // called in 'select' mode when user picks entry
}) {
    const { currentUser } = useAuth();
    const canEdit = !!currentUser?.can_manage_entities;

    const {
        definitions, entries,
        createEntry, updateEntry, deleteEntry, toggleEntryActive,
    } = useNomenclatureData();

    const nomenclature = definitions[nomenclatureCode];
    const allEntries = entries[nomenclatureCode] || [];

    const [selectedId, setSelectedId] = useState(initialSelection);
    const [searchTerm, setSearchTerm] = useState('');
    const [showForm, setShowForm] = useState(false);
    const [formMode, setFormMode] = useState('add');
    const [editData, setEditData] = useState(null);
    const [isSaving, setIsSaving] = useState(false);
    const [error, setError] = useState('');

    // Track items before form opens to detect new additions
    const itemsBeforeFormRef = useRef(new Set());
    const selectedRowRef = useRef(null);
    const searchInputRef = useRef(null);
    const overlayRef = useRef(null);

    // Reset state when overlay opens
    useEffect(() => {
        if (isOpen) {
            setSelectedId(initialSelection);
            setSearchTerm('');
            setShowForm(false);
            setError('');
            setTimeout(() => searchInputRef.current?.focus(), 100);
        }
    }, [isOpen, initialSelection]);

    // Auto-scroll to selected item
    useEffect(() => {
        if (selectedRowRef.current) {
            selectedRowRef.current.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        }
    }, [selectedId]);

    // Auto-select newly added items after form closes
    useEffect(() => {
        if (!showForm && itemsBeforeFormRef.current.size > 0) {
            const currentIds = new Set(allEntries.map(e => e.id));
            for (const id of currentIds) {
                if (!itemsBeforeFormRef.current.has(id)) {
                    setSelectedId(id);
                    break;
                }
            }
            itemsBeforeFormRef.current = new Set();
        }
    }, [showForm, allEntries]);

    // Fields sorted by sort_order
    const sortedFields = useMemo(() => {
        if (!nomenclature?.fields) return [];
        return [...nomenclature.fields].sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));
    }, [nomenclature]);

    // Search fields: all text-type field keys
    const searchFieldKeys = useMemo(() => {
        return sortedFields
            .filter(f => f.field_type === 'text' || f.field_type === 'choice')
            .map(f => f.key);
    }, [sortedFields]);

    // Filtered entries by search
    const filteredEntries = useMemo(() => {
        if (!searchTerm.trim()) return allEntries;
        const q = searchTerm.toLowerCase();
        return allEntries.filter(entry => {
            return searchFieldKeys.some(key => {
                const val = entry.data?.[key];
                return val && String(val).toLowerCase().includes(q);
            });
        });
    }, [allEntries, searchTerm, searchFieldKeys]);

    // Selected entry object
    const selectedEntry = useMemo(
        () => allEntries.find(e => e.id === selectedId) || null,
        [allEntries, selectedId]
    );

    // Escape key to close (only when form is not open)
    useEffect(() => {
        if (!isOpen || showForm) return;
        const handleKeyDown = (e) => {
            if (e.key === 'Escape') onClose();
        };
        document.addEventListener('keydown', handleKeyDown);
        return () => document.removeEventListener('keydown', handleKeyDown);
    }, [isOpen, showForm, onClose]);

    // Prevent body scroll
    useEffect(() => {
        if (isOpen) {
            document.body.style.overflow = 'hidden';
            return () => { document.body.style.overflow = ''; };
        }
    }, [isOpen]);

    const handleRowClick = useCallback((entry) => {
        setSelectedId(entry.id);
    }, []);

    const handleRowDoubleClick = useCallback((entry) => {
        if (mode === 'select' && onSelect) {
            onSelect(entry.id);
            onClose();
        }
    }, [mode, onSelect, onClose]);

    const handleAddClick = () => {
        // Track current items to detect new one after save
        itemsBeforeFormRef.current = new Set(allEntries.map(e => e.id));
        setFormMode('add');
        setEditData(null);
        setShowForm(true);
        setError('');
    };

    const handleEditClick = () => {
        if (!selectedEntry) return;
        setFormMode('edit');
        setEditData(selectedEntry.data);
        setShowForm(true);
        setError('');
    };

    const handleFormSave = async (formData) => {
        setIsSaving(true);
        setError('');
        try {
            if (formMode === 'add') {
                await createEntry(nomenclature.id, formData);
            } else {
                await updateEntry(selectedId, { data: formData });
            }
            setShowForm(false);
        } catch (err) {
            const data = err.response?.data;
            if (typeof data === 'string') {
                setError(data);
            } else if (data) {
                const messages = [];
                for (const [key, val] of Object.entries(data)) {
                    if (Array.isArray(val)) messages.push(`${key}: ${val.join(', ')}`);
                    else if (typeof val === 'string') messages.push(`${key}: ${val}`);
                    else messages.push(`${key}: ${JSON.stringify(val)}`);
                }
                setError(messages.join('; ') || 'Failed to save');
            } else {
                setError('Failed to save entry');
            }
        } finally {
            setIsSaving(false);
        }
    };

    const handleDeleteClick = async () => {
        if (!selectedEntry) return;
        if (!window.confirm('Delete this entry?')) return;
        setError('');
        try {
            await deleteEntry(selectedId);
            setSelectedId(null);
        } catch {
            setError('Failed to delete entry');
        }
    };

    const handleToggleActive = async () => {
        if (!selectedEntry) return;
        setError('');
        try {
            await toggleEntryActive(selectedId, selectedEntry.is_active);
        } catch {
            setError('Failed to update entry');
        }
    };

    const handleSelectClick = () => {
        if (!selectedEntry || !onSelect) return;
        onSelect(selectedEntry.id);
        onClose();
    };

    // Smart backdrop click: only close if mousedown+mouseup both on backdrop
    const mouseDownTargetRef = useRef(null);
    const handleMouseDown = (e) => { mouseDownTargetRef.current = e.target; };
    const handleMouseUp = (e) => {
        if (mouseDownTargetRef.current === overlayRef.current && e.target === overlayRef.current) {
            onClose();
        }
        mouseDownTargetRef.current = null;
    };

    if (!isOpen || !nomenclature) return null;

    return createPortal(
        <div
            className="nui-mgmt-overlay"
            ref={overlayRef}
            onMouseDown={handleMouseDown}
            onMouseUp={handleMouseUp}
        >
            <div className="nui-mgmt-content" onClick={(e) => e.stopPropagation()}>
                {/* Header */}
                <div className="nui-mgmt-header">
                    <h2>{nomenclature.name}</h2>
                    <button className="nui-mgmt-close" onClick={onClose} type="button">&times;</button>
                </div>

                {/* Toolbar */}
                <div className="nui-mgmt-toolbar">
                    <input
                        ref={searchInputRef}
                        type="text"
                        className="nui-mgmt-search"
                        placeholder={`Search ${nomenclature.name}...`}
                        value={searchTerm}
                        onChange={(e) => setSearchTerm(e.target.value)}
                    />
                    {canEdit && (
                        <button className="nui-mgmt-add-btn" onClick={handleAddClick} type="button">
                            + Add New
                        </button>
                    )}
                </div>

                {error && <div className="nui-mgmt-error">{error}</div>}

                {/* Table */}
                <div className="nui-mgmt-table-container">
                    <table className="nui-mgmt-table">
                        <thead>
                            <tr>
                                <th className="nui-mgmt-th-id">ID</th>
                                {sortedFields.map(f => (
                                    <th key={f.key}>{f.label || f.key}</th>
                                ))}
                                <th className="nui-mgmt-th-status">Active</th>
                                {canEdit && <th className="nui-mgmt-th-actions"></th>}
                            </tr>
                        </thead>
                        <tbody>
                            {filteredEntries.length === 0 ? (
                                <tr>
                                    <td colSpan={sortedFields.length + 3} className="nui-mgmt-empty">
                                        {searchTerm ? 'No entries match your search' : 'No entries yet. Click "+ Add New" to create one.'}
                                    </td>
                                </tr>
                            ) : (
                                filteredEntries.map(entry => (
                                    <tr
                                        key={entry.id}
                                        ref={entry.id === selectedId ? selectedRowRef : undefined}
                                        className={`nui-mgmt-row ${selectedId === entry.id ? 'nui-mgmt-row--selected' : ''} ${!entry.is_active ? 'nui-mgmt-row--inactive' : ''}`}
                                        onClick={() => handleRowClick(entry)}
                                        onDoubleClick={() => handleRowDoubleClick(entry)}
                                    >
                                        <td className="nui-mgmt-td-id">{entry.id}</td>
                                        {sortedFields.map(f => (
                                            <td key={f.key}>
                                                {f.field_type === 'bool'
                                                    ? (entry.data?.[f.key] ? 'Yes' : 'No')
                                                    : (entry.data?.[f.key] ?? '')
                                                }
                                            </td>
                                        ))}
                                        <td className="nui-mgmt-td-status">
                                            <span
                                                className={`nui-mgmt-active-badge ${entry.is_active ? 'nui-mgmt-active-badge--active' : 'nui-mgmt-active-badge--inactive'}`}
                                                onClick={canEdit ? (e) => { e.stopPropagation(); setSelectedId(entry.id); toggleEntryActive(entry.id, entry.is_active); } : undefined}
                                                title={canEdit ? (entry.is_active ? 'Click to deactivate' : 'Click to activate') : undefined}
                                                style={canEdit ? { cursor: 'pointer' } : undefined}
                                            >
                                                {entry.is_active ? 'Active' : 'Inactive'}
                                            </span>
                                        </td>
                                        {canEdit && (
                                            <td className="nui-mgmt-td-actions">
                                                <button
                                                    className="nui-mgmt-edit-btn"
                                                    onClick={(e) => { e.stopPropagation(); setSelectedId(entry.id); setTimeout(() => { setFormMode('edit'); setEditData(entry.data); setShowForm(true); }, 0); }}
                                                    title="Edit"
                                                    type="button"
                                                >
                                                    &#9998;
                                                </button>
                                            </td>
                                        )}
                                    </tr>
                                ))
                            )}
                        </tbody>
                    </table>
                </div>

                {/* Footer */}
                <div className="nui-mgmt-footer">
                    <div className="nui-mgmt-footer-info">
                        {filteredEntries.length} {filteredEntries.length === 1 ? 'entry' : 'entries'}
                        {searchTerm && ` (filtered)`}
                    </div>
                    <div className="nui-mgmt-footer-actions">
                        {canEdit && selectedEntry && (
                            <>
                                <button
                                    className="nui-mgmt-delete-btn"
                                    onClick={handleDeleteClick}
                                    type="button"
                                >
                                    Delete
                                </button>
                                <button
                                    className="nui-mgmt-footer-edit-btn"
                                    onClick={handleEditClick}
                                    type="button"
                                >
                                    Edit
                                </button>
                            </>
                        )}
                        {mode === 'select' && (
                            <button
                                className="nui-mgmt-select-btn"
                                onClick={handleSelectClick}
                                disabled={!selectedEntry}
                                type="button"
                            >
                                Select
                            </button>
                        )}
                    </div>
                </div>
            </div>

            {/* Form overlay (renders on top, z-index 13000) */}
            <FormOverlay
                isOpen={showForm}
                onClose={() => setShowForm(false)}
                title={formMode === 'edit' ? `Edit ${nomenclature.name} Entry` : `Add New ${nomenclature.name} Entry`}
            >
                <NomenclatureEntryForm
                    fields={sortedFields}
                    mode={formMode}
                    initialData={editData}
                    onSave={handleFormSave}
                    onCancel={() => setShowForm(false)}
                    isSaving={isSaving}
                />
            </FormOverlay>
        </div>,
        document.body
    );
}
