import {__} from "@wordpress/i18n";
import Checkbox from "../../../../../../fields/checkbox";
import Pagination from "../../../../../../sections/pagination";
import {getFormatedDate} from "../../../../../../../../helpers";
import Tooltip from "../../../../../../fields/tooltip";

/**
 * Comprehensive User Agent Parser with Memoization
 * Accurately detects browser, OS, and device information from user agent strings
 *
 * @param {string} userAgent - The user agent string to parse
 * @returns {Object} Parsed information including browser, OS, and device details
 */
const parseUserAgent = (() => {
    // Memoization cache to avoid re-parsing the same user agent
    const cache = new Map();
    const MAX_CACHE_SIZE = 100; // Limit cache size to prevent memory issues

    return function (userAgent) {
        if (!userAgent || typeof userAgent !== 'string') {
            return {
                browser: 'Unknown',
                browserVersion: null,
                os: 'Unknown',
                osVersion: null,
                deviceType: 'unknown',
                isMobile: false,
                isTablet: false,
                isDesktop: false
            };
        }

        // Check cache first
        if (cache.has(userAgent)) {
            return cache.get(userAgent);
        }

        const ua = userAgent;
        let browser = 'Unknown';
        let browserVersion = null;
        let os = 'Unknown';
        let osVersion = null;
        let deviceType = 'unknown';

        // ==========================================
        // BROWSER DETECTION
        // ==========================================
        // Order matters! Check most specific first

        // Internet Explorer (IE 11 and older)
        if (ua.includes('MSIE') || ua.includes('Trident/')) {
            browser = 'Internet Explorer';
            if (ua.includes('MSIE')) {
                const match = ua.match(/MSIE (\d+(?:\.\d+)*)/);
                browserVersion = match ? match[1] : null;
            } else if (ua.includes('rv:')) {
                // IE 11 doesn't use MSIE, uses rv: instead
                const match = ua.match(/rv:(\d+(?:\.\d+)*)/);
                browserVersion = match ? match[1] : null;
            }
        }
        // Samsung Internet (check before Chrome since it contains Chrome)
        else if (ua.includes('SamsungBrowser/')) {
            browser = 'Samsung Internet';
            const match = ua.match(/SamsungBrowser\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // UC Browser (check before Chrome since it contains Chrome)
        else if (ua.includes('UCBrowser/') || ua.includes('UC Browser/')) {
            browser = 'UC Browser';
            const match = ua.match(/(?:UCBrowser|UC Browser)\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Yandex Browser (check before Chrome since it contains Chrome)
        else if (ua.includes('YaBrowser/')) {
            browser = 'Yandex';
            const match = ua.match(/YaBrowser\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Edge (Chromium-based)
        else if (ua.includes('Edg/')) {
            browser = 'Edge';
            const match = ua.match(/Edg\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Edge (Legacy EdgeHTML)
        else if (ua.includes('Edge/')) {
            browser = 'Edge Legacy';
            const match = ua.match(/Edge\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Opera (check before Chrome since it contains Chrome)
        else if (ua.includes('OPR/') || ua.includes('Opera/')) {
            browser = 'Opera';
            if (ua.includes('OPR/')) {
                const match = ua.match(/OPR\/(\d+(?:\.\d+)*)/);
                browserVersion = match ? match[1] : null;
            } else {
                const match = ua.match(/Opera\/(\d+(?:\.\d+)*)/);
                browserVersion = match ? match[1] : null;
            }
        }
            // Brave (difficult to detect as it mimics Chrome, check for brave-specific indicators)
            // Note: Brave intentionally doesn't include identifiable markers in UA to prevent fingerprinting
        // This detection may not work in all cases
        else if (ua.includes('Brave/') || ua.includes('Brave Chrome/')) {
            browser = 'Brave';
            const match = ua.match(/(?:Brave\/|Chrome\/)(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Chrome iOS (CriOS) - check before regular Chrome
        else if (ua.includes('CriOS/')) {
            browser = 'Chrome';
            const match = ua.match(/CriOS\/(\d+(?:\.\d+(?:\.\d+)*)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Firefox iOS (FxiOS) - check before regular Firefox
        else if (ua.includes('FxiOS/')) {
            browser = 'Firefox';
            const match = ua.match(/FxiOS\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Chrome (Desktop/Android)
        else if (ua.includes('Chrome/')) {
            browser = 'Chrome';
            const match = ua.match(/Chrome\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Firefox (Desktop/Android)
        else if (ua.includes('Firefox/')) {
            browser = 'Firefox';
            const match = ua.match(/Firefox\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }
        // Safari (must be checked after Chrome/Edge/etc since they contain "Safari")
        else if (ua.includes('Safari/') && !ua.includes('Chrome') && !ua.includes('CriOS') && !ua.includes('Edg')) {
            browser = 'Safari';
            const match = ua.match(/Version\/(\d+(?:\.\d+)*)/);
            browserVersion = match ? match[1] : null;
        }

        // ==========================================
        // OPERATING SYSTEM DETECTION
        // ==========================================
        // IMPORTANT: Check iOS/iPadOS BEFORE macOS since they contain "Mac OS X" in UA

        // iOS (iPhone) - Check FIRST before macOS
        if (ua.includes('iPhone')) {
            os = 'iOS';
            const match = ua.match(/(?:iPhone )?OS (\d+[._]\d+(?:[._]\d+)*)/);
            if (match) {
                osVersion = match[1].replace(/_/g, '.');
            }
        }
        // iPadOS (iPad) - Check SECOND before macOS
        else if (ua.includes('iPad')) {
            os = 'iPadOS';
            const match = ua.match(/(?:CPU OS |OS )(\d+[._]\d+(?:[._]\d+)*)/);
            if (match) {
                osVersion = match[1].replace(/_/g, '.');
            }
        }
        // iPod Touch
        else if (ua.includes('iPod')) {
            os = 'iOS';
            const match = ua.match(/(?:iPhone )?OS (\d+[._]\d+(?:[._]\d+)*)/);
            if (match) {
                osVersion = match[1].replace(/_/g, '.');
            }
        }
        // Windows Phone
        else if (ua.includes('Windows Phone')) {
            os = 'Windows Phone';
            const match = ua.match(/Windows Phone (?:OS )?(\d+(?:\.\d+)*)/);
            osVersion = match ? match[1] : null;
        }
        // Windows
        else if (ua.includes('Windows NT')) {
            os = 'Windows';
            const match = ua.match(/Windows NT (\d+(?:\.\d+)*)/);
            if (match) {
                const ntVersion = match[1];
                // Map NT versions to friendly Windows versions
                const windowsVersionMap = {
                    '10.0': '10/11', // Windows 10 and 11 both use NT 10.0
                    '6.3': '8.1',
                    '6.2': '8',
                    '6.1': '7',
                    '6.0': 'Vista',
                    '5.2': 'XP x64',
                    '5.1': 'XP',
                    '5.0': '2000'
                };
                osVersion = windowsVersionMap[ntVersion] || ntVersion;
            }
        }
        // Android (check before Linux since it contains "Linux")
        else if (ua.includes('Android')) {
            os = 'Android';
            const match = ua.match(/Android (\d+(?:\.\d+)*)/);
            osVersion = match ? match[1] : null;
        }
        // Chrome OS
        else if (ua.includes('CrOS')) {
            os = 'Chrome OS';
            const match = ua.match(/CrOS [^ ]+ (\d+(?:\.\d+)*)/);
            osVersion = match ? match[1] : null;
        }
        // macOS (check AFTER iOS/iPadOS since they contain "Mac OS X")
        else if (ua.includes('Mac OS X') || ua.includes('Macintosh')) {
            os = 'macOS';
            const match = ua.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)*)/);
            if (match) {
                osVersion = match[1].replace(/_/g, '.');
            }
        }
        // Linux (check last since Android and Chrome OS also contain Linux)
        else if (ua.includes('Linux')) {
            os = 'Linux';
            // Try to get distribution info if available
            const distMatch = ua.match(/Linux ([^;)]+)/);
            osVersion = distMatch ? distMatch[1] : null;
        }

        // ==========================================
        // DEVICE TYPE DETECTION
        // ==========================================

        const mobileKeywords = /Mobile|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i;
        const tabletKeywords = /iPad|Tablet|PlayBook/i;

        const isMobile = mobileKeywords.test(ua) && !tabletKeywords.test(ua);
        const isTablet = tabletKeywords.test(ua);
        const isDesktop = !isMobile && !isTablet;

        if (isMobile) {
            deviceType = 'mobile';
        } else if (isTablet) {
            deviceType = 'tablet';
        } else if (isDesktop) {
            deviceType = 'desktop';
        }

        const result = {
            browser,
            browserVersion,
            os,
            osVersion,
            deviceType,
            isMobile,
            isTablet,
            isDesktop,
            // Original user agent for reference
            userAgent: ua
        };

        // Store in cache (with size limit to prevent memory issues)
        if (cache.size >= MAX_CACHE_SIZE) {
            // Remove oldest entry (first entry in Map)
            const firstKey = cache.keys().next().value;
            cache.delete(firstKey);
        }
        cache.set(userAgent, result);

        return result;
    };
})();

/**
 * Get initials from name
 */
const getInitials = (name) => {
    if (!name) return '?';
    const parts = name.trim().split(/\s+/);
    if (parts.length === 1) return parts[0].substring(0, 2).toUpperCase();
    return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
};

/**
 * Get device icon based on OS
 */
const getDeviceIcon = (os) => {
    if (!os || os === 'Unknown') {
        return (
            <svg className="lbaic-settings-leads-table-icon-svg unknown" viewBox="0 0 24 24" fill="none">
                <use href="#lbaic-settings-device-unknown"/>
            </svg>
        );
    }

    const osLower = os.toLowerCase();
    let iconId = 'lbaic-settings-device-unknown';

    if (osLower.includes('mac') || osLower.includes('darwin')) {
        iconId = 'lbaic-settings-device-macos';
    } else if (osLower.includes('win')) {
        iconId = 'lbaic-settings-device-windows';
    } else if (osLower.includes('android')) {
        iconId = 'lbaic-settings-device-android';
    } else if (osLower.includes('ios') || osLower.includes('iphone') || osLower.includes('ipad')) {
        iconId = 'lbaic-settings-device-ios';
    } else if (osLower.includes('linux') || osLower.includes('chrome os')) {
        iconId = 'lbaic-settings-device-linux';
    }

    return (
        <svg
            className={`lbaic-settings-leads-table-icon-svg${iconId === 'lbaic-settings-device-unknown' ? ' unknown' : ''}`}
            viewBox="0 0 24 24" fill="none">
            <use href={`#${iconId}`}/>
        </svg>
    );
};

/**
 * Get browser icon based on browser name
 */
const getBrowserIcon = (browser) => {
    if (!browser || browser === 'Unknown') {
        return (
            <svg className="lbaic-settings-leads-table-icon-svg unknown" viewBox="0 0 24 24" fill="none">
                <use href="#lbaic-settings-globe"/>
            </svg>
        );
    }

    const browserLower = browser.toLowerCase();
    let iconId = 'lbaic-settings-globe'; // Default to globe for unknown/other

    // Check in order of specificity
    if (browserLower.includes('internet explorer')) {
        iconId = 'lbaic-settings-browser-ie';
    } else if (browserLower.includes('edge legacy')) {
        iconId = 'lbaic-settings-browser-microsoft-edge';
    } else if (browserLower.includes('edge')) {
        iconId = 'lbaic-settings-browser-microsoft-edge';
    } else if (browserLower.includes('samsung')) {
        iconId = 'lbaic-settings-browser-samsung';
    } else if (browserLower.includes('uc browser')) {
        iconId = 'lbaic-settings-browser-uc';
    } else if (browserLower.includes('yandex')) {
        iconId = 'lbaic-settings-browser-yandex';
    } else if (browserLower.includes('brave')) {
        iconId = 'lbaic-settings-browser-brave';
    } else if (browserLower.includes('chrome')) {
        iconId = 'lbaic-settings-browser-chrome';
    } else if (browserLower.includes('firefox')) {
        iconId = 'lbaic-settings-browser-firefox';
    } else if (browserLower.includes('safari')) {
        iconId = 'lbaic-settings-browser-safari';
    } else if (browserLower.includes('opera')) {
        iconId = 'lbaic-settings-browser-opera';
    }

    return (
        <svg className={`lbaic-settings-leads-table-icon-svg${iconId === 'lbaic-settings-globe' ? ' unknown' : ''}`}
             viewBox="0 0 24 24" fill="none">
            <use href={`#${iconId}`}/>
        </svg>
    );
};

/**
 * Status configuration
 */
const STATUS_CONFIG = {
    new: __("New", 'limb-chatbot'),
    contacted: __("Contacted", 'limb-chatbot'),
    qualified: __("Qualified", 'limb-chatbot')
};

function CellContent({columnId, value, column, row}) {
    // Handle status column
    if (columnId === 'status') {
        const status = value || 'new';
        const label = STATUS_CONFIG[status] || STATUS_CONFIG.new;

        return (
            <div className="lbaic-settings-leads-table-status">
                {/*<span*/}
                {/*    className={`lbaic-settings-leads-table-status-dot lbaic-settings-leads-table-status-dot--${status}`}/>*/}
                <span
                    className={`lbaic-settings-leads-table-status-badge lbaic-settings-leads-table-status-badge--${status}`}>
                    {label}
                </span>
            </div>
        );
    }

    // Handle source column
    if (columnId === 'source' && value?.title) {
        return (
            <div className="lbaic-settings-leads-table-source">
                <div className="lbaic-settings-leads-table-source-name">{value.title}</div>
                <div className="lbaic-settings-leads-table-source-form">({value.type})</div>
            </div>
        );
    }

    // Handle captured column
    if (columnId === 'captured') {
        return <span className="lbaic-settings-leads-table-text">{getFormatedDate(value)}</span>;
    }

    // Handle created_at column
    if (columnId === 'created_at') {
        return <span className="lbaic-settings-leads-table-text">{getFormatedDate(value)}</span>;
    }

    // Handle geolocation column (visitor data)
    if (columnId === 'geolocation') {
        if (!value || typeof value !== 'object') {
            return <span
                className="lbaic-settings-leads-table-text lbaic-settings-leads-table-null">{__("N/A", 'limb-chatbot')}</span>;
        }

        const parts = [];
        if (value.city) parts.push(value.city);
        if (value.state) parts.push(value.state);
        if (value.country) parts.push(value.country);

        const location = parts.length > 0 ? parts.join(', ') : __("N/A", 'limb-chatbot');
        return <span className="lbaic-settings-leads-table-text">{location}</span>;
    }

    // Handle device_info column (visitor data) - show only OS and device type
    if (columnId === 'device_info') {
        if (!value || typeof value !== 'object') {
            return <span
                className="lbaic-settings-leads-table-text lbaic-settings-leads-table-null">{__("N/A", 'limb-chatbot')}</span>;
        }

        let os = __("Unknown", 'limb-chatbot');
        let osVersion = '';

        // Always parse from user_agent if available (backend parser may be incorrect)
        if (value?.user_agent) {
            const parsed = parseUserAgent(value.user_agent);
            os = parsed.os;
            osVersion = parsed.osVersion || '';
        } else {
            // Fallback to backend parsed data only if user_agent is not available
            os = value?.os || __("Unknown", 'limb-chatbot');
            osVersion = value?.os_version || '';
        }

        const parts = [];
        if (os) {
            parts.push(os);
        }
        if (osVersion) {
            parts.push(osVersion);
        }

        const device = parts.length > 0 ? parts.join(' ') : __("Unknown", 'limb-chatbot');

        // Get device icon
        const deviceIcon = getDeviceIcon(os);

        return (
            <div className="lbaic-settings-leads-table-cell-with-icon">
                <Tooltip
                    label={device}
                    width={80}
                    className='no-hover-bg'
                >
                    <div className="lbaic-settings-leads-table-icon">
                        {deviceIcon}
                    </div>
                </Tooltip>
            </div>
        );
    }

    // Handle browser column (visitor data)
    if (columnId === 'browser') {
        const deviceInfo = row?.device_info;
        if (!deviceInfo || typeof deviceInfo !== 'object') {
            return <span
                className="lbaic-settings-leads-table-text lbaic-settings-leads-table-null">{__("N/A", 'limb-chatbot')}</span>;
        }

        let browserName = __("Unknown", 'limb-chatbot');
        let browserVersion = '';

        // Always parse from user_agent if available (backend parser may be incorrect)
        if (deviceInfo.user_agent) {
            const parsed = parseUserAgent(deviceInfo.user_agent);
            browserName = parsed.browser;
            browserVersion = parsed.browserVersion || '';
        } else {
            // Fallback to backend parsed data only if user_agent is not available
            browserName = deviceInfo.browser || __("Unknown", 'limb-chatbot');
            browserVersion = deviceInfo.browser_version || '';
        }

        const parts = [];
        if (browserName) {
            parts.push(browserName);
        }
        if (browserVersion) {
            parts.push(browserVersion);
        }

        const browser = parts.length > 0 ? parts.join(' ') : __("Unknown", 'limb-chatbot');

        const browserIcon = getBrowserIcon(browserName);

        return (
            <div className="lbaic-settings-leads-table-cell-with-icon">
                <Tooltip label={browser} width={80} className='no-hover-bg'>
                    <div className="lbaic-settings-leads-table-icon">
                        {browserIcon}
                    </div>
                </Tooltip>
            </div>
        );
    }

    // Handle wp_user column (visitor data)
    if (columnId === 'wp_user') {
        if (!value || typeof value !== 'object' || !value.name) {
            return <span
                className="lbaic-settings-leads-table-text lbaic-settings-leads-table-null">{__("N/A", 'limb-chatbot')}</span>;
        }

        const displayName = value.name;
        const avatarUrl = value.avatar_urls?.['48'] || value.avatar_urls?.['24'] || value.avatar_urls?.['96'];

        return (
            <>
                {avatarUrl ? (
                    <div className="lbaic-settings-leads-table-avatar">
                        <img
                            src={avatarUrl}
                            alt={displayName}
                            className="lbaic-settings-leads-table-avatar-img"
                        />
                    </div>
                ) : (
                    <div className="lbaic-settings-leads-table-avatar">
                        <span className="lbaic-settings-leads-table-avatar-initials">
                            {getInitials(displayName)}
                        </span>
                    </div>
                )}
                <div className="lbaic-settings-leads-table-name-text">{displayName}</div>
            </>
        );
    }

    // Handle name-like fields (full_name, name, etc.) - show with avatar
    if (columnId === 'full_name' || columnId === 'name' || column?.label?.toLowerCase().includes('name')) {
        const displayName = value || __("N/A", 'limb-chatbot');

        return (
            <>
                {Boolean(value) && (
                    <div className="lbaic-settings-leads-table-avatar">
                        <span className="lbaic-settings-leads-table-avatar-initials">
                            {getInitials(displayName)}
                        </span>
                    </div>
                )}
                <div
                    className={`lbaic-settings-leads-table-name-text${!value ? ' lbaic-settings-leads-table-null' : ''}`}>{displayName}</div>
            </>
        );
    }

    // Render value
    return <span
        className={`lbaic-settings-leads-table-text${!value ? ' lbaic-settings-leads-table-null' : ''}`}>{value || __("N/A", 'limb-chatbot')}</span>;
}

export default function Table({
                                  selectedRows,
                                  selectAll,
                                  onLeadSelect,
                                  onSelectAll,
                                  onRowClick,
                                  allColumns = [],
                                  visibleColumns = [],
                                  tableData = [],
                                  pagination,
                                  loading,
                                  isDataFetched,
                                  _callback,
                                  emptyLabel,
                                  paginationProps
                              }) {
    // Separate columns: status (always first), configurable columns, and always-visible columns
    const statusColumn = allColumns.find(c => c.id === 'status');
    const otherColumns = allColumns.filter(c => c.id !== 'status');

    // Always include columns marked as alwaysVisible, plus the ones in visibleColumns
    const visibleOtherColumns = visibleColumns.length
        ? otherColumns.filter((c) => c.alwaysVisible || visibleColumns.includes(c.id))
        : otherColumns;

    // Status is always visible as the first column
    const columns = statusColumn
        ? [statusColumn, ...visibleOtherColumns]
        : visibleOtherColumns;

    // Calculate intermediate state: some (but not all) items on current page are selected
    const currentPageIds = tableData.map(lead => lead.id);
    const someSelected = currentPageIds.some(id => selectedRows.includes(id));
    const isIntermediateChecked = someSelected && !selectAll;

    if (!isDataFetched) {
        return null;
    }

    return (
        <>
            <div className="lbaic-settings-leads-table-container">
                <div className="lbaic-settings-leads-table-wrapper">
                    <table className="lbaic-settings-leads-table">
                        <thead>
                        <tr>
                            {/*<th className="lbaic-settings-leads-table-th lbaic-settings-leads-table-th-checkbox">
                                <Checkbox
                                    isChecked={selectAll}
                                    isIntermediateChecked={isIntermediateChecked}
                                    toggleValue={onSelectAll}
                                    id="lbaic-settings-leads-select-all"
                                    className="lbaic-settings-leads-table-checkbox-wrapper"
                                />
                            </th>*/}
                            {columns.map((col) => (
                                <th key={col.id} className="lbaic-settings-leads-table-th">{col.label}</th>
                            ))}
                        </tr>
                        </thead>
                        <tbody>
                        {tableData.length > 0 ? (
                            tableData.map((lead) => (
                                <tr
                                    key={lead.id}
                                    className="lbaic-settings-leads-table-tr"
                                    onClick={(e) => onRowClick(e, lead.id)}
                                >
                                    {/*<td className="lbaic-settings-leads-table-td">
                                        <div className="lbaic-settings-leads-table-cell">
                                            <Checkbox
                                                isChecked={selectedRows.includes(lead.id)}
                                                toggleValue={() => onLeadSelect(lead.id)}
                                                id={`lbaic-settings-leads-checkbox-${lead.id}`}
                                                className="lbaic-settings-leads-table-checkbox-wrapper"
                                            />
                                        </div>
                                    </td>*/}
                                    {columns.map((col) => (
                                        <td key={col.id} className="lbaic-settings-leads-table-td">
                                            <div className="lbaic-settings-leads-table-cell">
                                                <CellContent
                                                    columnId={col.id}
                                                    value={lead[col.id]}
                                                    column={col}
                                                    row={lead}
                                                />
                                            </div>
                                        </td>
                                    ))}
                                </tr>
                            ))
                        ) : (
                            <tr>
                                <td
                                    colSpan={columns.length + 1}
                                    className="lbaic-settings-leads-table-td"
                                    style={{textAlign: 'center', padding: '32px'}}
                                >
                                    <span
                                        className="lbaic-settings-leads-table-text">{emptyLabel}</span>
                                </td>
                            </tr>
                        )}
                        </tbody>
                    </table>
                </div>
            </div>
            {/* Pagination */}
            {Boolean(pagination) && (
                <Pagination
                    page={pagination.page}
                    perPage={pagination.perPage}
                    total={pagination.total}
                    goTo={(page) => _callback(page, pagination.perPage)}
                    loading={loading}
                    {...paginationProps}
                />
            )}
        </>
    );
}
