import { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';
import { setPageTitle } from '../../store/themeConfigSlice';
import Avatar from '../../components/Avatar';
import user from '../../assets/images/auth/user.png';
import Datepicker from '../../components/Datepicker';
import IconTag from '../../components/Icon/IconTag';
import Dropdown from '../../components/Dropdown';
import SearchBar from '../../components/SearchBar';
import Button from '../../components/Buttons';
import IconChevronLeft from '../../components/Icon/IconChevronLeft';
import IconChevronRight from '../../components/Icon/IconChevronRight';
import IconExport from '../../components/Icon/IconExport';
import api from '../../api/axios';
import { toast } from 'react-toastify';
import config from '../../config';
import * as XLSX from 'xlsx';

// -----------------------------
// TYPES
// -----------------------------
interface SlotInfo {
    time: string;
    start_time: string;
    end_time: string;
    batch: string | null;
    status: 'free' | 'full';
}

interface StaffMember {
    id: number;
    name: string;
    avatar: string | null;
    role: string;
    skills: string[];
    stats: {
        total: number;
        free: number;
        full: number;
    };
    slots: SlotInfo[];
}

interface PaginationData {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
    next_page_url: string | null;
    prev_page_url: string | null;
}

// -----------------------------
// COMPONENT
// -----------------------------
const FreeSlotList = () => {
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch(setPageTitle('Free Slot List'));
    }, [dispatch]);

    // State
    const [staffList, setStaffList] = useState<StaffMember[]>([]);
    const [loading, setLoading] = useState(true);
    const [selectedDate, setSelectedDate] = useState<Date>(new Date());
    const [search, setSearch] = useState("");
    const [perPage, setPerPage] = useState(9);
    const [pagination, setPagination] = useState<PaginationData>({
        current_page: 1,
        last_page: 1,
        per_page: 25,
        total: 0,
        next_page_url: null,
        prev_page_url: null
    });

    const storageBaseUrl = config.storageUrl;

    // Helper function to get the full image URL
    const getImageUrl = (imagePath: string | null): string => {
        if (!imagePath) return user;
        if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) {
            return imagePath;
        }
        return `${storageBaseUrl}/${imagePath}`;
    };

    // Export to Excel function
    const handleExport = () => {
        if (staffList.length === 0) {
            toast.warning('No data to export');
            return;
        }

        try {
            // Prepare data for export
            const exportData: any[] = [];

            // Get all unique time slots for headers
            const allTimeSlots = staffList[0]?.slots.map(slot => slot.time) || [];

            staffList.forEach((staff) => {
                const row: any = {
                    'Staff Name': staff.name,
                    'Role': staff.role,
                    'Skills': staff.skills.join(', '),
                    'Total Slots': staff.stats.total,
                    'Full Slots': staff.stats.full,
                    'Free Slots': staff.stats.free,
                };

                // Add each time slot as a column
                staff.slots.forEach((slot) => {
                    // Create a clean column name from the time slot
                    const columnName = slot.time;
                    row[columnName] = slot.status === 'full' ? slot.batch || 'Occupied' : 'Free';
                });

                exportData.push(row);
            });

            // Create worksheet
            const worksheet = XLSX.utils.json_to_sheet(exportData);

            // Auto-size columns
            const columnWidths: { [key: string]: number } = {};
            exportData.forEach((row) => {
                Object.keys(row).forEach((key) => {
                    const valueLength = row[key] ? row[key].toString().length : 10;
                    columnWidths[key] = Math.max(columnWidths[key] || 0, valueLength);
                });
            });

            worksheet['!cols'] = Object.keys(columnWidths).map(key => ({
                wch: Math.min(columnWidths[key] + 2, 30) // Max width of 30
            }));

            // Create workbook
            const workbook = XLSX.utils.book_new();
            XLSX.utils.book_append_sheet(workbook, worksheet, 'Free Slots');

            // Generate filename with date
            const dateStr = selectedDate.toISOString().split('T')[0];
            const fileName = `Free_Slots_${dateStr}.xlsx`;

            // Save file
            XLSX.writeFile(workbook, fileName);

            toast.success('Data exported successfully!');
        } catch (error) {
            console.error('Export error:', error);
            toast.error('Failed to export data');
        }
    };

    // Fetch free slots
    const fetchFreeSlots = async (page = 1) => {
        setLoading(true);
        try {
            const params: any = {
                page,
                per_page: perPage,
                date: selectedDate.toLocaleDateString('en-CA')
            };

            if (search) {
                params.search = search;
            }

            const response = await api.get('/training/free-slots', { params });

            if (response.data.status === true) {
                setStaffList(response.data.data.data);
                setPagination({
                    current_page: response.data.data.current_page,
                    last_page: response.data.data.last_page,
                    per_page: response.data.data.per_page,
                    total: response.data.data.total,
                    next_page_url: response.data.data.next_page_url,
                    prev_page_url: response.data.data.prev_page_url
                });
            } else {
                toast.error(response.data.message || 'Failed to fetch free slots');
            }
        } catch (error: any) {
            console.error('Error fetching free slots:', error);
            toast.error(error.response?.data?.message || 'Failed to fetch free slots');
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        fetchFreeSlots();
    }, [selectedDate, perPage]);

    const handleSearch = () => {
        fetchFreeSlots(1);
    };

    const handlePageChange = (page: number) => {
        if (page >= 1 && page <= pagination.last_page) {
            fetchFreeSlots(page);
        }
    };

    const handlePerPageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
        setPerPage(Number(e.target.value));
    };

    // Skeleton loader
    const TableSkeleton = () => (
        <>
            {[...Array(6)].map((_, index) => (
                <tr key={index} className="animate-pulse border-t">
                    <td className="p-4 sticky left-0 bg-white z-10 border-r">
                        <div className="flex items-center gap-3">
                            <div className="w-10 h-10 bg-gray-200 rounded-full"></div>
                            <div>
                                <div className="h-4 w-28 bg-gray-200 rounded mb-1"></div>
                                <div className="h-3 w-20 bg-gray-200 rounded"></div>
                            </div>
                        </div>
                    </td>
                    {[...Array(9)].map((_, idx) => (
                        <td key={idx} className="p-3 text-center">
                            <div className="h-8 bg-gray-100 rounded mx-auto w-20"></div>
                        </td>
                    ))}
                </tr>
            ))}
        </>
    );

    return (
        <>
            <div className="flex items-center justify-between mb-4 flex-wrap">
                <ul className="flex space-x-2 items-center">
                    <li>
                        <Link to="/free_slot" className="text-primary text-lg hover:underline">
                            Free Slot
                        </Link>
                    </li>
                    <li className="before:content-['/'] ml-2">
                        Manage Training
                    </li>
                </ul>
                <div className="flex gap-2">
                    {/* Export Current Page Button */}
                    <Button
                        icon={<IconExport/>}
                        iconPosition='left'
                        onClick={handleExport}
                    >
                        Export
                    </Button>
                </div>
            </div>

            <div className="p-4 rounded-xl shadow-md bg-white">
                <div className="grid grid-cols-12 gap-5">
                    <div className="col-span-6">
                        <SearchBar
                            placeholder="Search by Staff Name, Batch Name, Skills, Role..."
                            onSearch={(val: string) => {
                                setSearch(val);
                                handleSearch();
                            }}
                            onRefresh={() => {
                                setSearch("");
                                fetchFreeSlots(1);
                            }}
                        />
                    </div>
                    <div className="col-span-6 flex justify-end">
                        <Datepicker
                            value={selectedDate}
                            onChange={(date) => {
                                const newDate = Array.isArray(date) ? date[0] : date;
                                setSelectedDate(newDate ?? new Date());
                            }}
                        />
                    </div>
                    <div className="col-span-12 overflow-x-auto">
                        <table className="min-w-max w-full border-collapse text-sm">
                            <thead>
                                <tr className="bg-gray-100">
                                    <th className="p-4 text-left sticky left-0 bg-gray-100 z-20 min-w-[280px] border-r">
                                        Staff Details
                                    </th>
                                    {/* Generate time slots header */}
                                    {(staffList[0]?.slots || []).map((slot, index) => (
                                        <th
                                            key={index}
                                            className="p-3 text-center min-w-[130px] border-r font-medium whitespace-nowrap"
                                        >
                                            {slot.time}
                                        </th>
                                    ))}
                                </tr>
                            </thead>
                            <tbody>
                                {loading ? (
                                    <TableSkeleton />
                                ) : (
                                    staffList.map((staff) => (
                                        <tr key={staff.id} className="border-t hover:bg-gray-50">
                                            {/* Staff Info Column */}
                                            <td className="p-4 sticky left-0 bg-white z-10 border-r">
                                                <div className="flex items-center gap-3">
                                                    <Avatar src={getImageUrl(staff.avatar)} size="md" />
                                                    <div className="flex flex-col w-full">
                                                        <div className="flex items-center justify-between gap-3">
                                                            <span className="font-semibold">{staff.name}</span>
                                                            {staff.skills.length > 0 && (
                                                                <Dropdown
                                                                    btnClassName="cursor-pointer"
                                                                    button={<IconTag />}
                                                                >
                                                                    <div className="flex flex-col gap-2 min-w-[180px] p-2">
                                                                        {staff.skills.map((skill, index) => (
                                                                            <span
                                                                                key={index}
                                                                                className="text-xs px-2 py-1 border rounded bg-gray-50"
                                                                            >
                                                                                {skill}
                                                                            </span>
                                                                        ))}
                                                                    </div>
                                                                </Dropdown>
                                                            )}
                                                        </div>
                                                        <span className="text-gray-500 text-xs">{staff.role}</span>
                                                        <div className="flex gap-2 mt-2">
                                                            <span className="bg-green-100 text-gray-700 px-2 py-1 rounded border text-md">
                                                                Class: <b>{staff.stats.full}</b>
                                                            </span>
                                                            <span className="bg-red-50 text-gray-600 px-2 py-1 rounded border text-md">
                                                                Free: <b>{staff.stats.free}</b>
                                                            </span>
                                                        </div>
                                                    </div>
                                                </div>
                                            </td>

                                            {/* Time Slots */}
                                            {staff.slots.map((slot, index) => (
                                                <td
                                                    key={index}
                                                    className={`text-center p-3 border-r font-medium relative ${
                                                        slot.status === 'full'
                                                            ? 'bg-green-100 text-green-700'
                                                            : 'bg-red-50 text-red-500'
                                                    }`}
                                                >
                                                    {slot.status === 'full' ? (
                                                        <div className="relative group inline-block">
                                                            {/* Truncated text */}
                                                            <span className="cursor-help">
                                                                {slot.batch && slot.batch.length > 12
                                                                    ? `${slot.batch.substring(0, 12)}...`
                                                                    : slot.batch
                                                                }
                                                            </span>

                                                            {/* Custom Tooltip */}
                                                            <div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 hidden group-hover:block z-50">
                                                                <div className="bg-gray-900 text-white text-xs rounded-lg py-2 px-3 shadow-lg whitespace-nowrap">
                                                                    <div className="font-medium mb-1">Batch Details</div>
                                                                    <div className="text-gray-200">{slot.batch}</div>
                                                                    <div className="text-gray-400 text-xs mt-1">
                                                                        {slot.start_time} - {slot.end_time}
                                                                    </div>
                                                                </div>
                                                                {/* Tooltip Arrow */}
                                                                <div className="absolute top-full left-1/2 transform -translate-x-1/2 -mt-0.5">
                                                                    <div className="border-4 border-transparent border-t-gray-900"></div>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    ) : (
                                                        <span className="text-xs">Free</span>
                                                    )}
                                                </td>
                                            ))}
                                        </tr>
                                    ))
                                )}
                            </tbody>
                        </table>
                    </div>

                    {/* Pagination */}
                    {!loading && staffList.length > 0 && (
                        <div className="flex flex-col sm:flex-row justify-between items-center gap-4 mt-6 pt-4 border-t col-span-12">
                            <div className="text-sm text-gray-600">
                                Showing {((pagination.current_page - 1) * pagination.per_page) + 1} to{' '}
                                {Math.min(pagination.current_page * pagination.per_page, pagination.total)} of{' '}
                                {pagination.total} entries
                                <select
                                    value={perPage}
                                    onChange={handlePerPageChange}
                                    className="ml-3 px-2 py-1 border rounded-md text-sm"
                                >
                                    <option value={10}>10</option>
                                    <option value={25}>25</option>
                                    <option value={50}>50</option>
                                </select>
                            </div>
                            <div className="flex gap-2">
                                <button
                                    onClick={() => handlePageChange(pagination.current_page - 1)}
                                    disabled={pagination.current_page === 1}
                                    className="w-8 h-8 flex items-center justify-center border rounded-full disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50 transition-colors"
                                >
                                    <IconChevronLeft className="w-4 h-4" />
                                </button>
                                <div className="flex gap-1">
                                    {(() => {
                                        const pages = [];
                                        const maxVisible = 5;
                                        let startPage = Math.max(1, pagination.current_page - Math.floor(maxVisible / 2));
                                        let endPage = Math.min(pagination.last_page, startPage + maxVisible - 1);

                                        if (endPage - startPage + 1 < maxVisible) {
                                            startPage = Math.max(1, endPage - maxVisible + 1);
                                        }

                                        for (let i = startPage; i <= endPage; i++) {
                                            pages.push(i);
                                        }

                                        return pages.map((pageNum) => (
                                            <button
                                                key={pageNum}
                                                onClick={() => handlePageChange(pageNum)}
                                                className={`w-8 h-8 flex items-center justify-center border rounded-full transition-colors ${
                                                    pagination.current_page === pageNum
                                                        ? 'bg-primary text-white border-primary'
                                                        : 'hover:bg-gray-50'
                                                }`}
                                            >
                                                {pageNum}
                                            </button>
                                        ));
                                    })()}
                                </div>
                                <button
                                    onClick={() => handlePageChange(pagination.current_page + 1)}
                                    disabled={pagination.current_page === pagination.last_page}
                                    className="w-8 h-8 flex items-center justify-center border rounded-full hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                                >
                                    <IconChevronRight className="w-4 h-4" />
                                </button>
                            </div>
                        </div>
                    )}
                </div>
            </div>
        </>
    );
};

export default FreeSlotList;
