import React, { useEffect, useState } from 'react';
import FullCalendar, { EventInput } from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction';
import '../styles/Calendar.css';

// Define colors for each beamline
const beamlineColors: { [key: string]: string } = {
    PXI: '#FF5733',
    PXII: '#33FF57',
    PXIII: '#3357FF',
    Unknown: '#CCCCCC', // Gray color for unknown beamlines
};

// Custom event interface
interface CustomEvent extends EventInput {
    beamline: string;
    beamtime_shift: string;
    isSubmitted?: boolean; // Track if information is submitted
}

// Define experiment modes
const experimentModes = ['SDU-Scheduled', 'SDU-queued', 'Remote', 'In-person'];

// Utility function to darken a hex color
const darkenColor = (color: string, percent: number): string => {
    const num = parseInt(color.slice(1), 16); // Convert hex to number
    const amt = Math.round(2.55 * percent); // Calculate amount to darken
    const r = (num >> 16) + amt; // Red
    const g = (num >> 8 & 0x00FF) + amt; // Green
    const b = (num & 0x0000FF) + amt; // Blue

    // Ensure values stay within 0-255 range
    const newColor = (0x1000000 + (r < 255 ? (r < 0 ? 0 : r) : 255) * 0x10000 + (g < 255 ? (g < 0 ? 0 : g) : 255) * 0x100 + (b < 255 ? (b < 0 ? 0 : b) : 255)).toString(16).slice(1);
    return `#${newColor}`;
};

const Calendar: React.FC = () => {
    const [events, setEvents] = useState<CustomEvent[]>([]);
    const [selectedEventId, setSelectedEventId] = useState<string | null>(null);
    const [eventDetails, setEventDetails] = useState<CustomEvent | null>(null);
    const [userDetails, setUserDetails] = useState({
        name: '',
        firstName: '',
        phone: '',
        email: '',
        extAccount: '',
        experimentMode: experimentModes[0],
    });
    const [shipments, setShipments] = useState<any[]>([]); // State for shipments
    const [selectedDewars, setSelectedDewars] = useState<string[]>([]); // Track selected dewars for the experiment

    useEffect(() => {
        const fetchEvents = async () => {
            try {
                const response = await fetch('/beamtimedb.json');
                const data = await response.json();
                const events: CustomEvent[] = [];

                data.beamtimes.forEach((beamtime: any) => {
                    const date = new Date(beamtime.date);
                    beamtime.shifts.forEach((shift: any) => {
                        const beamline = shift.beamline || 'Unknown';
                        const beamtime_shift = shift.beamtime_shift || 'morning';

                        const event: CustomEvent = {
                            id: `${beamline}-${date.toISOString()}-${beamtime_shift}`,
                            start: new Date(date.setHours(0, 0, 0)),
                            end: new Date(date.setHours(23, 59, 59)),
                            title: `${beamline}: ${beamtime_shift}`,
                            beamline,
                            beamtime_shift,
                            isSubmitted: false,
                        };

                        events.push(event);
                    });
                });

                console.log('Fetched events array:', events);
                setEvents(events);
            } catch (error) {
                console.error('Error fetching events:', error);
            }
        };

        const fetchShipments = async () => {
            try {
                const response = await fetch('/shipmentdb.json');

                // Check for HTTP errors
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                // Parse the JSON response
                const data = await response.json();

                const availableDewars: any[] = [];

                data.shipments.forEach(shipment => {
                    if (shipment.shipment_status === "In Transit") {
                        shipment.dewars.forEach(dewar => {
                            if (dewar.shippingStatus === "shipped" && dewar.returned === "") {
                                availableDewars.push(dewar);
                            }
                        });
                    }
                });

                console.log('Available Dewars:', availableDewars);
                setShipments(availableDewars);
            } catch (error) {
                console.error('Error fetching shipments:', error);
                // Optionally display the error to the user in the UI
            }
        };

        fetchEvents();
        fetchShipments();
    }, []);

    const handleEventClick = (eventInfo: any) => {
        const clickedEventId = eventInfo.event.id;
        setSelectedEventId(clickedEventId);

        const selectedEvent = events.find(event => event.id === clickedEventId) || null;
        setEventDetails(selectedEvent);
    };

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
        const { name, value } = e.target;
        setUserDetails(prevDetails => ({
            ...prevDetails,
            [name]: value,
        }));
    };

    const handleDewarSelection = (dewarId: string) => {
        setSelectedDewars(prevSelectedDewars => {
            if (prevSelectedDewars.includes(dewarId)) {
                return prevSelectedDewars.filter(id => id !== dewarId); // Remove if already selected
            } else {
                return [...prevSelectedDewars, dewarId]; // Add if not selected
            }
        });
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();

        if (eventDetails) {
            const updatedEvents = events.map(event =>
                event.id === eventDetails.id
                    ? { ...event, isSubmitted: true, selectedDewars } // Associate selected dewars
                    : event
            );
            setEvents(updatedEvents);
        }

        console.log('User Details:', userDetails);
        console.log('Selected Dewars:', selectedDewars);

        // Reset user details and selected dewars after submission
        setUserDetails({
            name: '',
            firstName: '',
            phone: '',
            email: '',
            extAccount: '',
            experimentMode: experimentModes[0],
        });
        setSelectedDewars([]); // Reset selected dewars
    };

    const eventContent = (eventInfo: any) => {
        const beamline = eventInfo.event.extendedProps.beamline || 'Unknown';
        const isSelected = selectedEventId === eventInfo.event.id;
        const isSubmitted = eventInfo.event.extendedProps.isSubmitted;

        const backgroundColor = isSubmitted
            ? darkenColor(beamlineColors[beamline] || beamlineColors.Unknown, -20)
            : isSelected
                ? '#FFD700'
                : (beamlineColors[beamline] || beamlineColors.Unknown);

        return (
            <div
                style={{
                    backgroundColor: backgroundColor,
                    color: 'white',
                    border: isSelected ? '2px solid black' : 'none',
                    borderRadius: '3px',
                    display: 'flex',
                    justifyContent: 'center',
                    alignItems: 'center',
                    height: '100%',
                    width: '100%',
                    cursor: 'pointer',
                    overflow: 'hidden',
                    boxSizing: 'border-box',
                }}
            >
                {eventInfo.event.title}
            </div>
        );
    };

    return (
        <div className="calendar-container">
            <h2>Beamline Calendar</h2>
            <FullCalendar
                plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
                initialView="dayGridMonth"
                events={events}
                eventContent={eventContent}
                height={700}
                headerToolbar={{
                    left: 'prev,next',
                    center: 'title',
                    right: 'dayGridMonth',
                }}
                eventClick={handleEventClick}
            />

            {eventDetails && (
                <div className="event-details">
                    <h3>Event Details</h3>
                    <p><strong>Beamline:</strong> {eventDetails.beamline}</p>
                    <p><strong>Shift:</strong> {eventDetails.beamtime_shift}</p>

                    <h4>Select Dewars</h4>
                    <ul>
                        {shipments.map(dewar => (
                            <li key={dewar.id}>
                                <input
                                    type="checkbox"
                                    id={dewar.id}
                                    checked={selectedDewars.includes(dewar.id)}
                                    onChange={() => handleDewarSelection(dewar.id)}
                                />
                                <label htmlFor={dewar.id}>{dewar.dewar_name} (Pucks: {dewar.number_of_pucks})</label>
                            </li>
                        ))}
                    </ul>

                    <h4>User Information</h4>
                    <form onSubmit={handleSubmit}>
                        <label>
                            Name:
                            <input
                                type="text"
                                name="name"
                                value={userDetails.name}
                                onChange={handleInputChange}
                            />
                        </label>
                        <br />
                        <label>
                            First Name:
                            <input
                                type="text"
                                name="firstName"
                                value={userDetails.firstName}
                                onChange={handleInputChange}
                            />
                        </label>
                        <br />
                        <label>
                            Phone:
                            <input
                                type="text"
                                name="phone"
                                value={userDetails.phone}
                                onChange={handleInputChange}
                            />
                        </label>
                        <br />
                        <label>
                            Email:
                            <input
                                type="email"
                                name="email"
                                value={userDetails.email}
                                onChange={handleInputChange}
                            />
                        </label>
                        <br />
                        <label>
                            External Account:
                            <input
                                type="text"
                                name="extAccount"
                                value={userDetails.extAccount}
                                onChange={handleInputChange}
                            />
                        </label>
                        <br />
                        <label>
                            Experiment Mode:
                            <select
                                name="experimentMode"
                                value={userDetails.experimentMode}
                                onChange={handleInputChange}
                            >
                                {experimentModes.map(mode => (
                                    <option key={mode} value={mode}>{mode}</option>
                                ))}
                            </select>
                        </label>
                        <br />
                        <button type="submit">Submit</button>
                    </form>
                </div>
            )}
        </div>
    );
};

export default Calendar;
