import React, {useState, useEffect, useRef} from "react";
import { useNavigate } from "react-router-dom";
import { AuthService, EventsService, CustomerService, ResourceService } from "../../services";
import moment from 'moment';
import { Breadcrumb, Tabs, Tab, Button, Modal, Dropdown } from "react-bootstrap";
import { useCalendarApp, ScheduleXCalendar } from '@schedule-x/react';
import {
  viewMonthGrid,
	createViewDay,
	createViewWeek,
	createViewMonthGrid
} from '@schedule-x/calendar';
import { createEventsServicePlugin } from '@schedule-x/events-service';
import { createEventModalPlugin} from '@schedule-x/event-modal';
import '@schedule-x/theme-default/dist/calendar.css';
import { Filter } from "react-bootstrap-icons";
import DatePicker from "react-datepicker";


const EventsCalendar = () => {
  const navigate = useNavigate();
  const [events, setEvents] = useState([]);
  const calendarColumnRef = useRef(null);
  const [listHeight, setListHeight] = useState(null);
	const [allEvents, setAllEvents] = useState([]);
  const [customers, setCustomers] = useState([]);
	const [resources, setResources] = useState([]);
	const [fromDate, setFromDate] = useState(new Date(new Date().getFullYear(), new Date().getMonth(), 1));
  const [toDate, setToDate] = useState(new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0));
	const [currentTotalTranslate1, setCurrentTotalTranslate1] = useState(0);
	const [currentTotalTranslate2, setCurrentTotalTranslate2] = useState(0);
	const [currentTotalResource, setCurrentTotalResource] = useState(0);
	const [showDeletedItems, setShowDeletedItems] = useState(false);
	const [selectedColorFilters, setSelectedColorFilters] = useState([]);
	const [timeData, setTimeData] = useState([]);
	const [showFilterDropdown, setShowFilterDropdown] = useState(false);
	const eventsServicePlugin = createEventsServicePlugin();
	const eventModalService = createEventModalPlugin();
	const [groupedEvents, setGroupedEvents] = useState(new Map());
	const [currentRangeStart, setCurrentRangeStart] = useState(null);
	const [currentRangeEnd, setCurrentRangeEnd] = useState(null);
	const [showCreationModal, setShowCreationModal] = useState(false);
	const [newEventStartDateTime, setNewEventStartDateTime] = useState(new Date());
	const [newEventEndDateTime, setNewEventEndDateTime] = useState(new Date());
	const [newEventColor, setNewEventColor] = useState('');

	// Medical appointment specific fields
	const [newEventCustomer, setNewEventCustomer] = useState('');
	const [newEventResource, setNewEventResource] = useState('');
	const [newEventInterpreter, setNewEventInterpreter] = useState('');
	const [newEventFasting, setNewEventFasting] = useState('');
	const [newEventNeedId, setNewEventNeedId] = useState('');
	const [newEventNewPatient, setNewEventNewPatient] = useState('');
	const [newEventDisability, setNewEventDisability] = useState('');
	const [newEventTransMethod, setNewEventTransMethod] = useState('');

	// Helper function to format name from "lastname, firstname" to "firstname lastname"
	const formatFullName = (name) => {
		if (!name) return '';
		if (name.includes(',')) {
			const parts = name.split(',').map(part => part.trim());
			return `${parts[1]} ${parts[0]}`; // firstname lastname
		}
		return name;
	};

	// Helper function to format event title - now uses full name, CSS handles overflow
	const formatEventTitle = (customerName, startTime) => {
		const fullName = formatFullName(customerName);
		return fullName;
	};

	// Get full name for description/tooltip
	const getEventDescription = (customerName, doctorName) => {
		const fullName = formatFullName(customerName);
		return doctorName ? `${fullName} - ${doctorName}` : fullName;
	};

	const calendar = useCalendarApp({
		views: [createViewMonthGrid(), createViewDay(), createViewWeek()],
		monthGridOptions: {
			nEventsPerDay: 50,
		},
		defaultView: viewMonthGrid.name,
		skipValidation: true,
		selectedDate: moment(new Date()).format('YYYY-MM-DD HH:mm'),
		events: events,
		plugins: [eventModalService, eventsServicePlugin],
		callbacks: {
			onRangeUpdate(range) {
				setCurrentRangeStart(range.start);
				setCurrentRangeEnd(range.end);
				const startDate = new Date(range.start);
				const endDate = new Date(range.end);
				setFromDate(new Date(startDate.getFullYear(), startDate.getMonth(), 1)); 
				setToDate(new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0));
			},
			onClickDate(date) {
				// Disabled: prevent creating new event by tapping calendar date
				return;
			},
			onClickDateTime(dateTime) {
				// Disabled: prevent creating new event by tapping calendar time slot
				return;
			}
		}
	});

	// Filter events based on current calendar range
	const getFilteredEvents = () => {
		if (!currentRangeStart || !currentRangeEnd) {
			const now = moment();
			return events.filter(event => {
				const eventDate = moment(event.start_time);
				return eventDate.isSame(now, 'month');
			});
		}
		
		const rangeStart = moment(currentRangeStart);
		const rangeEnd = moment(currentRangeEnd);
		
		return events.filter(event => {
			const eventDate = moment(event.start_time);
			return eventDate.isBetween(rangeStart, rangeEnd, 'day', '[]');
		});
	};

	const getGroupedEvents = () => {
		const eventsDateMap = new Map();
		const filteredEvents = getFilteredEvents();
		for (const eventItem of filteredEvents) {
			const dateString = moment(eventItem.start_time).format('MMM Do, YYYY');
			if (eventsDateMap.has(dateString)) {
				eventsDateMap.set(dateString, [...eventsDateMap.get(dateString), eventItem]);
			} else {
				const value = [];
				value.push(eventItem);				
				eventsDateMap.set(dateString, value);
			}
		}
		// Sort each day by earliest start time first
		eventsDateMap.forEach((items, key) => {
			const sortedItems = [...items].sort((a, b) => {
				const aTime = moment(a?.start_time).valueOf();
				const bTime = moment(b?.start_time).valueOf();
				return aTime - bTime;
			});
			eventsDateMap.set(key, sortedItems);
		});
		return eventsDateMap;
	};


  useEffect(() => {
    if (!AuthService.canAccessLegacySystem()) {
      window.alert('You haven\'t login yet OR this user does not have access to this page. Please change an admin account to login.')
      AuthService.logout();
      navigate(`/login`);
    }
    CustomerService.getAllActiveCustomers().then((data) => {
      setCustomers(data.data);
    });
		ResourceService.getAll().then((data) => {
			setResources(data.data);
		});
		EventsService.getTimeData().then(data => {
			setTimeData(data.data);
		});
  }, []);

	useEffect(() => {
		EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then(data => setAllEvents(data?.data));
	}, [fromDate, toDate]);

	useEffect(() => {
		if (customers?.length > 0 && resources.length > 0) {
			const orignialEvents = [...allEvents];
			setEvents(orignialEvents?.filter(item => item.type === 'medical')?.map((item) => {
				const customerField = item?.data?.customer ? (customers?.find(c => c.id === item?.data?.customer)?.name || item?.data?.client_name || '') : (item?.data?.client_name || '');
				const doctorField = item?.data?.resource ? ((resources?.find(r => r.id === item?.data?.resource))?.name || item?.data?.resource_name || '') : (item?.data?.resource_name || '');
				item.event_id = item.id;
				item.customer = customerField;
				item.doctor = doctorField;
				item.phone = item?.data?.resource ? ((resources?.find(r => r.id === item?.data?.resource))?.phone || item?.data?.resource_phone || '') : (item?.data?.resource_phone || '');
				item.contact = item?.data?.resource? ((resources?.find(r => r.id === item?.data?.resource))?.contact || item?.data?.resource_contact || '') : (item?.data?.resource_contact || '')
				item.address = item?.data?.resource ? ((resources?.find(r => r.id === item?.data?.resource))?.address || item?.data?.resource_address || '') : (item?.data?.resource_address || '');
				item.translation = item?.data?.interpreter || '';
				item.newPatient = item?.data?.new_patient || '';
				item.needId = item?.data?.need_id || '';
				item.disability = item?.data?.disability || '';
				item.startTime = item?.start_time? `${moment(new Date(item?.start_time)).format('YYYY-MM-DD HH:mm')}` : '' ;
				item.endTime = item?.start_time? `${moment(new Date(item?.end_time)).format('YYYY-MM-DD HH:mm')}` : '' ;
				item.fasting = item?.data?.fasting || '';
				item.transportation = item?.link_event_name || '';
				item.title = formatEventTitle(customerField, item?.start_time);
				item.description = getEventDescription(customerField, doctorField);
				item.start = item?.start_time? `${moment(new Date(item?.start_time)).format('YYYY-MM-DD HH:mm')}` : `${moment().format('YYYY-MM-DD HH:mm')}`;
				item.end = item?.stop_time? `${moment(new Date(item?.stop_time)).format('YYYY-MM-DD HH:mm')}` : (item?.start_time? `${moment(item?.start_time).format('YYYY-MM-DD HH:mm')}` : `${moment().format('YYYY-MM-DD HH:mm')}`);
				const transportationInfo = EventsService.getTransportationInfo(allEvents, item, timeData);
				const { isFutureEvent, maxTranslate1, maxTranslate2, maxResource, totalTranslate1, totalTranslate2, totalResource} = transportationInfo;
				item.color = item?.color;
				item._options = { additionalClasses: [`event-${item?.color || 'primary'}`]};
				item.showWarnings = isFutureEvent;
				item.maxTranslate1 = maxTranslate1;
				item.maxTranslate2 = maxTranslate2;
				item.maxResource = maxResource;
				item.totalTranslate1 = totalTranslate1;
				setCurrentTotalTranslate1(item.totalTranslate1);
				item.totalTranslate2 = totalTranslate2;
				setCurrentTotalTranslate2(item.totalTranslate2);
				item.totalResource = totalResource;
				setCurrentTotalResource(item.totalResource);
				return item;
			})?.filter(item => (!showDeletedItems && item.status === 'active') || showDeletedItems)
			?.filter(item => {
				if (selectedColorFilters.length === 0) return true;
				if (selectedColorFilters.includes(item.color)) return true;
				// When "Drop-Off Only" (purple) is selected, also show events with no label
				if (selectedColorFilters.includes('purple') && !item.color) return true;
				return false;
			}));
		}
	}, [customers, resources, timeData, allEvents, showDeletedItems, selectedColorFilters])



	useEffect(() => {	
		if (events && calendar) {
			calendar?.eventsService?.set(events);
			setGroupedEvents(getGroupedEvents());
		}
	}, [events, currentRangeStart, currentRangeEnd]);

	// Sync list column height with calendar column height
	useEffect(() => {
		const updateListHeight = () => {
			if (calendarColumnRef.current) {
				const calendarHeight = calendarColumnRef.current.offsetHeight;
				setListHeight(calendarHeight);
			}
		};
		
		const timer = setTimeout(updateListHeight, 100);
		window.addEventListener('resize', updateListHeight);
		
		return () => {
			clearTimeout(timer);
			window.removeEventListener('resize', updateListHeight);
		};
	}, [events]);

	
  const redirectToAdmin = () => {
    navigate(`/medical`)
  }

  const goToCreateNew = () => {
    navigate(`/medical/events`)
  }

  const goToList = () => {
		navigate(`/medical/events/list`)
  }

  const goToMultipleList = () => {
		navigate(`/medical/events/multiple-list`)
  }

  const goToView = (id) => {
    navigate(`/medical/events/${id}`)
  }

	const toggleColorFilter = (colorValue) => {
		setSelectedColorFilters(prev => 
			prev.includes(colorValue) 
				? prev.filter(c => c !== colorValue) 
				: [...prev, colorValue]
		);
	};

	const FilterAndClose = () => {
    setShowFilterDropdown(false);
  }

	const cleanFilterAndClose = () => {
    setShowFilterDropdown(false);
    setShowDeletedItems(false);
		setSelectedColorFilters([]);
  }

	const customComponents = {
		eventModal: ({calendarEvent}) => {
			return <>
				<div className="sx__event-modal__title">{calendarEvent?.customer}</div>
				{calendarEvent?.doctor && <div className="sx__event-modal__time">{`${calendarEvent?.doctor}`}</div>}
				<div className="sx__event-modal__time">{`${calendarEvent?.start}`}</div>
			</>
		}
	};

	const customMenu = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <h6>Filter By</h6>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Show Deleted Events</div>
							<input type="checkbox" value={showDeletedItems} checked={showDeletedItems === true} onClick={() => setShowDeletedItems(!showDeletedItems)} />
            </div>
          </div>
					<hr style={{ margin: '8px 0' }} />
					<div style={{ display: 'flex', flexDirection: 'column' }}>
						<div className="field-label" style={{ marginBottom: '8px' }}>Filter by Type</div>
						{EventsService.labelOptions.map((item) => (
							<div key={item.value} className="d-flex align-items-center mb-1" style={{ cursor: 'pointer' }} onClick={() => toggleColorFilter(item.value)}>
								<input 
									type="checkbox" 
									checked={selectedColorFilters.includes(item.value)} 
									onChange={() => toggleColorFilter(item.value)} 
									style={{ marginRight: '8px', marginLeft: '0' }}
									onClick={(e) => e.stopPropagation()}
								/>
								<span 
									className={`event-${item.value}`}
									style={{ 
										width: '14px', 
										height: '14px', 
										borderRadius: '3px', 
										display: 'inline-block', 
										marginRight: '6px',
										flexShrink: 0
									}}
								></span>
								<span style={{ fontSize: '12px' }}>{item.label}</span>
							</div>
						))}
						{selectedColorFilters.length > 0 && (
							<div style={{ marginTop: '4px' }}>
								<span 
									style={{ fontSize: '11px', color: '#0066B1', cursor: 'pointer', textDecoration: 'underline' }} 
									onClick={() => setSelectedColorFilters([])}
								>
									Clear all
								</span>
							</div>
						)}
					</div>
          <div className="list row" style={{ marginTop: '8px' }}>
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => cleanFilterAndClose()}> Cancel </button>
              <button className="btn btn-primary btn-sm float-right" onClick={() => FilterAndClose()}> Filter </button>
            </div>
          </div>
        </div>
      );
    },
  );

	const calendarView = <div className="multi-columns-container" style={{ display: 'flex', alignItems: 'flex-start', width: '100%' }}>
		<div className="column-container" ref={calendarColumnRef} style={{ minWidth: '1000px', flexShrink: 0, display: 'flex', flexDirection: 'column' }}>
			{calendar && <ScheduleXCalendar customComponents={customComponents} calendarApp={calendar} />}
			{/* Legend */}
			<div className="calendar-legend mt-3">
				<h6 className="text-muted mb-2" style={{ fontSize: '12px' }}>Legend:</h6>
				<div className="d-flex flex-wrap gap-3">
					{EventsService.labelOptions?.map((item) => (
						<div key={item.value} className="d-flex align-items-center">
							<span 
								className={`event-${item.value}`}
								style={{ 
									width: '16px', 
									height: '16px', 
									borderRadius: '4px', 
									display: 'inline-block', 
									marginRight: '6px'
								}}
							></span>
							<span style={{ fontSize: '12px' }}>{item.label}</span>
						</div>
					))}
				</div>
			</div>
		</div>
		<div className="column-container calendar-list-column" style={{ display: 'flex', flexDirection: 'column', flex: 1, minWidth: 0 }}>
			<div className="column-card" style={{ height: listHeight ? `${listHeight}px` : 'auto', overflowY: 'auto', overflowX: 'hidden', padding: '16px', display: 'flex', flexDirection: 'column', width: '100%', boxSizing: 'border-box' }}>
				<h6 className="text-primary mb-3">List</h6>
				<div style={{ flex: 1, overflowY: 'auto', width: '100%' }}>
					{(!groupedEvents || groupedEvents.size === 0) && (
						<div style={{ padding: '24px', textAlign: 'center', color: '#999' }}>
							No events for this period
						</div>
					)}
					{
						Array.from(groupedEvents?.keys())?.map((key) => {
							return <div key={key}>
								<h6 className="text-primary me-2">{key}</h6>
								{
									groupedEvents.get(key).map(eventItem => <div 
										key={eventItem.id}
										className={`event-${eventItem.color || 'primary'} mb-3 event-list-item-container`}
										onClick={() => goToView(eventItem.id)}
										style={{ cursor: 'pointer', padding: '8px 12px', borderRadius: '4px' }}
									>
										<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
											<span className="sx__month-agenda-event__title">{formatFullName(eventItem.customer)}</span>
											<span style={{ fontSize: '12px' }}>{moment(eventItem?.start_time).format('HH:mm')} - {moment(eventItem?.stop_time || eventItem?.start_time).format('HH:mm')}</span>
										</div>
										<div className="sx__event-modal__time" style={{ fontSize: '12px', marginTop: '4px' }}>Provider: {eventItem?.doctor || '-'}</div>
									</div>)
								}
							</div>
						})
					}
				</div>
			</div>
		</div>
	</div>

const handleClose = () => {
	setShowCreationModal(false);
	setNewEventStartDateTime(undefined);
	setNewEventEndDateTime(undefined);
	setNewEventColor('');
	setNewEventCustomer('');
	setNewEventResource('');
	setNewEventInterpreter('');
	setNewEventFasting('');
	setNewEventNeedId('');
	setNewEventNewPatient('');
	setNewEventDisability('');
	setNewEventTransMethod('');
}

const handleSave = () => {
	const userName = localStorage.getItem('user') && JSON.parse(localStorage.getItem('user'))?.name;
	const selectedCustomer = customers.find(c => c.id === newEventCustomer);
	const selectedResource = resources.find(r => r.id === newEventResource);
	
	const data = {
		type: 'medical',
		status: 'active',
		create_by: userName,
		edit_by: userName,
		edit_date: new Date(),
		create_date: new Date(),
		edit_history: [{ employee: userName, date: new Date() }],
		title: selectedCustomer ? `${selectedCustomer.name} - Medical Appointment` : 'Medical Appointment',
		start_time: newEventStartDateTime,
		stop_time: newEventStartDateTime,
		color: newEventColor,
		confirmed: true,
		data: {
			customer: newEventCustomer,
			client_name: selectedCustomer?.name || '',
			resource: newEventResource,
			resource_name: selectedResource?.name || '',
			resource_phone: selectedResource?.phone || '',
			resource_address: selectedResource?.address || '',
			interpreter: newEventInterpreter,
			fasting: newEventFasting,
			need_id: newEventNeedId,
			new_patient: newEventNewPatient,
			disability: newEventDisability,
			trans_method: newEventTransMethod,
		}
	};
	
	EventsService.createNewEvent(data).then(() => {
		EventsService.getAllEvents({ from: EventsService.formatDate(fromDate), to: EventsService.formatDate(toDate) }).then((data) => {
			setAllEvents(data.data);
			handleClose();
		})
	});
}
  
  
  return (
    <>
      <div className="list row mb-4">
        <Breadcrumb>
          <Breadcrumb.Item href="/medical/index">Medical</Breadcrumb.Item>
          <Breadcrumb.Item active>
            Medical Event Calendar
          </Breadcrumb.Item>
        </Breadcrumb>
        <div className="col-md-12 text-primary">
           <h4>
            	Medical Event Calendar
           </h4> 
        </div>
      </div>

			<div className="app-main-content-list-container" style={{"min-width": "1500px"}}>
				<div className="app-main-content-list-func-container">
					<Tabs defaultActiveKey="medicalCalendar" id="events-calendar-tab">
						<Tab eventKey="medicalCalendar" title="Medical Appointments">
							
						</Tab>
					</Tabs>
					{ calendarView }
					<div className="list-func-panel">
						<Dropdown
							key={'event-calendar-filter'}
							id="event-calendar-filter"
							show={showFilterDropdown}
							onToggle={() => setShowFilterDropdown(!showFilterDropdown)}
							autoClose={false}
						> 
							<Dropdown.Toggle variant="primary">
								<Filter size={16} className="me-2"></Filter>Filter
							</Dropdown.Toggle>
							<Dropdown.Menu as={customMenu}/> 
						</Dropdown>
					</div>
					<Modal show={showCreationModal} onHide={handleClose} size="sm" centered dialogClassName="calendar-event-modal">
						<Modal.Header closeButton>
							<Modal.Title>New Medical Appointment</Modal.Title>
						</Modal.Header>
						<Modal.Body>
							<div className="mb-3">
								<div className="field-label">Customer<span className="required">*</span></div>
								<select className="form-control" value={newEventCustomer} onChange={(e) => setNewEventCustomer(e.target.value)}>
									<option value="">Select Customer</option>
									{customers.filter(item => item?.status === 'active' && item?.type !== 'discharged').map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
								</select>
							</div>
							<div className="mb-3">
								<div className="field-label">Provider<span className="required">*</span></div>
								<select className="form-control" value={newEventResource} onChange={(e) => setNewEventResource(e.target.value)}>
									<option value="">Select Provider</option>
									{resources.filter(item => item?.status === 'active').map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
								</select>
							</div>
							<div className="mb-3">
								<div className="field-label">Appointment Time<span className="required">*</span></div>
								<DatePicker
									className="form-control"
									selected={newEventStartDateTime}
									onChange={setNewEventStartDateTime}
									showTimeSelect
									timeFormat="HH:mm"
									timeIntervals={15}
									dateFormat="MM/dd/yyyy, HH:mm"
								/>
							</div>
							<div className="mb-3">
								<div className="field-label">Language Support</div>
								<select className="form-control" value={newEventInterpreter} onChange={(e) => setNewEventInterpreter(e.target.value)}>
									<option value="">Select</option>
									<option value="Checkin">Checkin</option>
									<option value="Center">Center</option>
									<option value="Family">Family</option>
									<option value="Office in person">Office in person</option>
									<option value="Office by phone">Office by phone</option>
									<option value="Nurse">Nurse</option>
								</select>
							</div>
							<div className="mb-3">
								<div className="field-label">Transportation Support</div>
								<select className="form-control" value={newEventTransMethod} onChange={(e) => setNewEventTransMethod(e.target.value)}>
									<option value="">Select</option>
									<option value="ByOwn">Self-Transport</option>
									<option value="By Center Transportation">By Center Transportation</option>
									<option value="DropOff Only">Drop-Off Only</option>
									<option value="Pickup Only">Pick-Up Only</option>
									<option value="Client Does Not need to Go">Medication Pickup Only</option>
								</select>
							</div>
							<div className="mb-3">
								<div className="field-label">Label</div>
								<select className="form-control" value={newEventColor} onChange={(e) => setNewEventColor(e.target.value)}>
									<option value="">Select</option>
									{EventsService.labelOptions?.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
								</select>
							</div>
						</Modal.Body>
						<Modal.Footer>
							<Button variant="secondary" size="sm" onClick={handleClose}>
								Cancel
							</Button>
							<Button variant="primary" size="sm" onClick={handleSave} disabled={
								!newEventCustomer || !newEventResource || !newEventStartDateTime
							}>
								Save
							</Button>
						</Modal.Footer>
					</Modal>
				</div>
			</div>
    </>
  )
};

export default EventsCalendar;
