import { useEffect, useState } from 'react';
import { Get } from '../../pocketbase/Get';
import { Authentication } from '../../pocketbase/Authentication';

// Add HighlightText component
const HighlightText = ({ text, searchTerms }: { text: string | number | null | undefined, searchTerms: string[] }) => {
    // Convert input to string and handle null/undefined
    const textStr = String(text ?? '');

    if (!searchTerms.length || !textStr) return <>{textStr}</>;

    try {
        const escapedTerms = searchTerms.map(term =>
            term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
        );
        const parts = textStr.split(new RegExp(`(${escapedTerms.join('|')})`, 'gi'));

        return (
            <>
                {parts.map((part, i) => {
                    const isMatch = searchTerms.some(term =>
                        part.toLowerCase().includes(term.toLowerCase())
                    );
                    return isMatch ? (
                        <mark key={i} className="bg-primary/20 rounded px-1">{part}</mark>
                    ) : (
                        <span key={i}>{part}</span>
                    );
                })}
            </>
        );
    } catch (error) {
        console.error('Error in HighlightText:', error);
        return <>{textStr}</>;
    }
};

interface AttendeeEntry {
    user_id: string;
    time_checked_in: string;
    food: string;
}

interface User {
    id: string;
    name: string;
    email: string;
    pid: string;
    member_id: string;
    member_type: string;
    graduation_year: string;
    major: string;
}

interface Event {
    id: string;
    event_name: string;
    attendees: AttendeeEntry[];
}

export default function Attendees() {
    const [eventId, setEventId] = useState<string>('');
    const [eventName, setEventName] = useState<string>('');
    const [users, setUsers] = useState<Map<string, User>>(new Map());
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [attendeesList, setAttendeesList] = useState<AttendeeEntry[]>([]);
    const [searchTerm, setSearchTerm] = useState('');
    const [filteredAttendees, setFilteredAttendees] = useState<AttendeeEntry[]>([]);
    const [processedSearchTerms, setProcessedSearchTerms] = useState<string[]>([]);

    const get = Get.getInstance();
    const auth = Authentication.getInstance();

    // Listen for the custom event
    useEffect(() => {
        const handleUpdateAttendees = (e: CustomEvent<{ eventId: string; eventName: string }>) => {
            console.log('Received updateAttendees event:', e.detail);
            setEventId(e.detail.eventId);
            setEventName(e.detail.eventName);
        };

        // Add event listener
        window.addEventListener('updateAttendees', handleUpdateAttendees as EventListener);

        // Cleanup
        return () => {
            window.removeEventListener('updateAttendees', handleUpdateAttendees as EventListener);
        };
    }, []);

    // Filter attendees when search term or attendees list changes
    useEffect(() => {
        if (!searchTerm.trim()) {
            setFilteredAttendees(attendeesList);
            setProcessedSearchTerms([]);
            return;
        }

        const terms = searchTerm.toLowerCase().split(/\s+/).filter(Boolean);
        setProcessedSearchTerms(terms);

        const filtered = attendeesList.filter(attendee => {
            const user = users.get(attendee.user_id);
            if (!user) return false;

            const searchableValues = [
                user.name,
                user.email,
                user.pid,
                user.member_id,
                user.member_type,
                user.graduation_year,
                user.major,
                attendee.food,
                new Date(attendee.time_checked_in).toLocaleString(),
            ].map(value => (value || '').toString().toLowerCase());

            return terms.every(term =>
                searchableValues.some(value => value.includes(term))
            );
        });

        setFilteredAttendees(filtered);
    }, [searchTerm, attendeesList, users]);

    // Function to download attendees as CSV
    const downloadAttendeesCSV = () => {
        // Create CSV headers
        const headers = [
            'Name',
            'Email',
            'PID',
            'Member ID',
            'Member Type',
            'Graduation Year',
            'Major',
            'Check-in Time',
            'Food Choice'
        ];

        // Create CSV rows
        const rows = attendeesList.map(attendee => {
            const user = users.get(attendee.user_id);
            const checkInTime = new Date(attendee.time_checked_in).toLocaleString();
            return [
                user?.name || 'Unknown User',
                user?.email || 'N/A',
                user?.pid || 'N/A',
                user?.member_id || 'N/A',
                user?.member_type || 'N/A',
                user?.graduation_year || 'N/A',
                user?.major || 'N/A',
                checkInTime,
                attendee.food || 'N/A'
            ];
        });

        // Combine headers and rows
        const csvContent = [
            headers.join(','),
            ...rows.map(row => row.map(cell => `"${cell}"`).join(','))
        ].join('\n');

        // Create blob and download
        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);

        link.setAttribute('href', url);
        link.setAttribute('download', `${eventName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_attendees.csv`);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };

    // Fetch event data when eventId changes
    useEffect(() => {
        const fetchEventData = async () => {
            if (!eventId) {
                console.log('No eventId provided');
                return;
            }

            if (!auth.isAuthenticated()) {
                console.log('User not authenticated');
                setError('Authentication required');
                return;
            }

            try {
                setLoading(true);
                setError(null);

                console.log('Fetching event data for:', eventId);
                const event = await get.getOne<Event>('events', eventId);

                if (!event.attendees || !Array.isArray(event.attendees)) {
                    console.log('No attendees found or invalid format');
                    setAttendeesList([]);
                    return;
                }

                console.log('Found attendees:', {
                    count: event.attendees.length,
                    sample: event.attendees.slice(0, 2)
                });
                setAttendeesList(event.attendees);

                // Fetch user details
                const userIds = [...new Set(event.attendees.map(a => a.user_id))];
                console.log('Fetching details for users:', userIds);

                const userPromises = userIds.map(async (userId) => {
                    try {
                        return await get.getOne<User>('users', userId);
                    } catch (error) {
                        console.error(`Failed to fetch user ${userId}:`, error);
                        return null;
                    }
                });

                const userResults = await Promise.all(userPromises);
                const userMap = new Map<string, User>();

                userResults.forEach(user => {
                    if (user) {
                        userMap.set(user.id, user);
                    }
                });

                console.log('Fetched user details:', {
                    totalUsers: userMap.size,
                    userIds: Array.from(userMap.keys())
                });
                setUsers(userMap);
            } catch (error) {
                console.error('Failed to fetch event data:', error);
                setError('Failed to load event data');
                setAttendeesList([]);
            } finally {
                setLoading(false);
            }
        };

        fetchEventData();
    }, [eventId]); // Re-run when eventId changes

    // Reset state when modal is closed
    useEffect(() => {
        const handleModalClose = () => {
            setEventId('');
            setAttendeesList([]);
            setUsers(new Map());
            setError(null);
        };

        const modal = document.getElementById('attendeesModal');
        if (modal) {
            modal.addEventListener('close', handleModalClose);
            return () => modal.removeEventListener('close', handleModalClose);
        }
    }, []);

    if (loading) {
        return (
            <div className="flex items-center justify-center p-8">
                <span className="loading loading-spinner loading-lg"></span>
            </div>
        );
    }

    if (error) {
        return (
            <div className="alert alert-error">
                <svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
                <span>{error}</span>
            </div>
        );
    }

    if (!eventId) {
        return null;
    }

    if (!attendeesList || attendeesList.length === 0) {
        return (
            <div className="text-center py-8 text-base-content/70">
                <svg xmlns="http://www.w3.org/2000/svg" className="h-12 w-12 mx-auto mb-4 opacity-50" viewBox="0 0 20 20" fill="currentColor">
                    <path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z" />
                </svg>
                <p>No attendees yet</p>
            </div>
        );
    }

    return (
        <div className="flex flex-col h-[calc(100vh-16rem)]">
            <div className="flex flex-col gap-4 mb-4">
                {/* Search and Actions Row */}
                <div className="flex justify-between items-center gap-4">
                    <div className="flex-1 flex gap-2">
                        <div className="join flex-1">
                            <div className="join-item bg-base-200 flex items-center px-3">
                                <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 opacity-70" viewBox="0 0 20 20" fill="currentColor">
                                    <path fillRule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clipRule="evenodd" />
                                </svg>
                            </div>
                            <input
                                type="text"
                                placeholder="Search attendees..."
                                className="input input-bordered join-item w-full"
                                value={searchTerm}
                                onChange={(e) => setSearchTerm(e.target.value)}
                            />
                        </div>
                    </div>
                    <button
                        className="btn btn-primary btn-sm gap-2"
                        onClick={downloadAttendeesCSV}
                    >
                        <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
                            <path fillRule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clipRule="evenodd" />
                        </svg>
                        Download CSV
                    </button>
                </div>

                {/* Stats Row */}
                <div className="flex justify-between items-center">
                    <div className="text-sm opacity-70">
                        Total Attendees: {attendeesList.length}
                    </div>
                    {searchTerm && (
                        <div className="text-sm opacity-70">
                            Showing: {filteredAttendees.length} matches
                        </div>
                    )}
                </div>
            </div>

            {/* Updated table with highlighting */}
            <div className="overflow-x-auto flex-1">
                <table className="table table-zebra w-full">
                    <thead className="sticky top-0 bg-base-100">
                        <tr>
                            <th className="bg-base-100">Name</th>
                            <th className="bg-base-100">Email</th>
                            <th className="bg-base-100">PID</th>
                            <th className="bg-base-100">Member ID</th>
                            <th className="bg-base-100">Member Type</th>
                            <th className="bg-base-100">Graduation Year</th>
                            <th className="bg-base-100">Major</th>
                            <th className="bg-base-100">Check-in Time</th>
                            <th className="bg-base-100">Food Choice</th>
                        </tr>
                    </thead>
                    <tbody>
                        {filteredAttendees.map((attendee, index) => {
                            const user = users.get(attendee.user_id);
                            const checkInTime = new Date(attendee.time_checked_in).toLocaleString();

                            return (
                                <tr key={`${attendee.user_id}-${index}`}>
                                    <td><HighlightText text={user?.name || 'Unknown User'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.email || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.pid || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.member_id || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.member_type || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.graduation_year || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={user?.major || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={checkInTime} searchTerms={processedSearchTerms} /></td>
                                    <td><HighlightText text={attendee.food || 'N/A'} searchTerms={processedSearchTerms} /></td>
                                </tr>
                            );
                        })}
                    </tbody>
                </table>
            </div>
        </div>
    );
}
