import React, { useState, useEffect } from 'react';
import { Breadcrumb, BreadcrumbItem, Card, Row, Col, Dropdown, Spinner } from 'react-bootstrap';
import { AuthService, EventsService, CustomerService, TransRoutesService, ResourceService } from '../../services';
import DashboardCustomersList from './DashboardCustomersList';
import { CUSTOMER_TYPE, PERSONAL_ROUTE_STATUS } from '../../shared';
import moment from 'moment';
import './Dashboard.css';

const Dashboard = () => {
  const [todayAttendance, setTodayAttendance] = useState(0);
  const [todayMedicalAppointments, setTodayMedicalAppointments] = useState(0);
  const [membersCount, setMembersCount] = useState(0);
  const [visitorsCount, setVisitorsCount] = useState(0);
  const [medicalPercentage, setMedicalPercentage] = useState(0);
  const [medicalTrend, setMedicalTrend] = useState(''); // 'increase' or 'decrease'
  const [events, setEvents] = useState([]);
  const [allEvents, setAllEvents] = useState([]);
  const [groupedEvents, setGroupedEvents] = useState(new Map());
  const [selectedEventType, setSelectedEventType] = useState('medical');
  const [customers, setCustomers] = useState([]);
  const [resources, setResources] = useState([]);
  const [showSpinner, setShowSpinner] = useState(false);

  const eventTypes = [
    { value: 'medical', label: 'Medical Appointments' },
    { value: 'activity', label: 'Activities' },
    { value: 'incident', label: 'Attendance' },
    { value: 'meal_plan', label: 'Meal Plan' },
    { value: 'reminder', label: 'Important Dates' }
  ];

  // Fetch today's events for the calendar list
  const fetchTodayEvents = async () => {
    try {
      const today = new Date();
      const fromDate = new Date(today.getFullYear(), today.getMonth(), 1);
      const toDate = new Date(today.getFullYear(), today.getMonth() + 1, 0);
      
      const eventsData = await EventsService.getAllEvents({ 
        from: EventsService.formatDate(fromDate), 
        to: EventsService.formatDate(toDate) 
      });
      setAllEvents(eventsData.data);
      
      let processedEvents = [];
      
      // Filter and map events based on selected type
      if (selectedEventType === 'medical') {
        if (customers?.length > 0 && resources.length > 0) {
          const originalEvents = [...eventsData.data];
          processedEvents = originalEvents
            ?.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 = `${customerField}, provider: ${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')}`);
              item.color = item?.color;
              item._options = { additionalClasses: [`event-${item?.color || 'primary'}`]};
              return item;
            })
            ?.filter(item => item.status === 'active');
        }
      } else {
        const originalEvents = [...eventsData.data];
        processedEvents = originalEvents
          ?.filter(item => item.type === selectedEventType)
          ?.map(item => ({
            ...item,
            title: item?.title,
            start: item?.start_time? `${moment(new Date(item?.start_time)).format('YYYY-MM-DD HH:mm')}` : `${moment().format('YYYY-MM-DD HH:mm')}`,
            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')}`),
            _options: { additionalClasses: [`event-${item?.color || 'primary'}`]}
          }))
          ?.filter(item => item.status === 'active');
      }
      
      const sortedEvents = [...(processedEvents || [])].sort((a, b) => {
        const aTime = moment(a?.start_time).valueOf();
        const bTime = moment(b?.start_time).valueOf();
        return aTime - bTime;
      });

      setEvents(sortedEvents);
      
      // Group events by date
      const eventsDateMap = new Map();
      sortedEvents?.forEach(eventItem => {
        const dateString = moment(eventItem.start_time).format('MMM Do, YYYY');
        if (eventsDateMap.has(dateString)) {
          eventsDateMap.set(dateString, [...eventsDateMap.get(dateString), eventItem]);
        } else {
          eventsDateMap.set(dateString, [eventItem]);
        }
      });

      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);
      });

      setGroupedEvents(eventsDateMap);
    } catch (error) {
      console.error('Error fetching events:', error);
    }
  };

  // Fetch today's attendance data
  const fetchTodayAttendance = async () => {
    try {
      const today = EventsService.formatDate(new Date());
      const routesData = await TransRoutesService.getAll(today);
      const inboundRoutes = routesData.data.filter(route => route.type === 'inbound');
      
      let totalAttendance = 0;
      let members = 0;
      let visitors = 0;
      
      // Get all customers from inbound routes who are not absent
      const allCustomers = TransRoutesService.getAllCustomersFromRoutes(inboundRoutes, []);
      
      allCustomers.forEach(customer => {
        // Check if customer is not Unexpected Absent or Scheduled Absent
        if (customer.customer_route_status !== PERSONAL_ROUTE_STATUS.UNEXPECTED_ABSENT && 
            customer.customer_route_status !== PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT) {
          totalAttendance++;
          
          // Count by customer type
          if (customer.customer_type === CUSTOMER_TYPE.MEMBER || customer.customer_type === CUSTOMER_TYPE.SELF_PAY) {
            members++;
          } else if (customer.customer_type === CUSTOMER_TYPE.VISITOR) {
            visitors++;
          }
        }
      });
      
      setTodayAttendance(totalAttendance);
      setMembersCount(members);
      setVisitorsCount(visitors);
    } catch (error) {
      console.error('Error fetching attendance:', error);
    }
  };

  // Fetch today's and yesterday's medical appointments
  const fetchMedicalAppointments = async () => {
    try {
      const today = EventsService.formatDate(new Date());
      const yesterday = EventsService.formatDate(new Date(Date.now() - 24 * 60 * 60 * 1000));
      
      // Get today's medical events
      const todayEventsData = await EventsService.getAllEvents({ date: today });
      const todayMedicalEvents = todayEventsData.data.filter(event => event.type === 'medical');
      
      // Get yesterday's medical events
      const yesterdayEventsData = await EventsService.getAllEvents({ date: yesterday });
      const yesterdayMedicalEvents = yesterdayEventsData.data.filter(event => event.type === 'medical');
      
      setTodayMedicalAppointments(todayMedicalEvents.length);
      
      // Calculate percentage change
      if (yesterdayMedicalEvents.length > 0) {
        const percentageChange = ((todayMedicalEvents.length - yesterdayMedicalEvents.length) / yesterdayMedicalEvents.length) * 100;
        setMedicalPercentage(Math.abs(percentageChange));
        setMedicalTrend(percentageChange >= 0 ? 'increase' : 'decrease');
      } else if (todayMedicalEvents.length > 0) {
        setMedicalPercentage(100);
        setMedicalTrend('increase');
      } else {
        setMedicalPercentage(0);
        setMedicalTrend('');
      }
    } catch (error) {
      console.error('Error fetching medical appointments:', error);
    }
  };

  useEffect(() => {
    setShowSpinner(true);
    Promise.all([
      fetchTodayAttendance(),
      fetchMedicalAppointments(),
      CustomerService.getAllCustomers().then((data) => {
        setCustomers(data.data);
      }),
      ResourceService.getAll().then((data) => {
        setResources(data.data);
      })
    ]).finally(() => {
      setShowSpinner(false);
    });
  }, []);

  // Separate useEffect for events that depends on selectedEventType, customers, and resources
  useEffect(() => {
    if (customers?.length > 0 && resources?.length > 0) {
      fetchTodayEvents();
    }
  }, [selectedEventType, customers, resources]);

  return (
    <>
      {showSpinner && <div className="spinner-overlay">
        <Spinner animation="border" role="status">
          <span className="visually-hidden">Loading...</span>
        </Spinner>
      </div>}
      <div className="list row mb-4">
        <Breadcrumb>
          <Breadcrumb.Item>Dashboard</Breadcrumb.Item>
          <Breadcrumb.Item active>
            Dashboard
          </Breadcrumb.Item>
        </Breadcrumb>
        <div className="col-md-12 text-primary">
          <h4>Dashboard</h4>
        </div>
      </div>

      <div className="app-main-content-list-container">
        <div className="row">
          {/* Main Section - 3/4 width */}
          <div className="col-md-9">
            {/* Top Cards */}
            <div className="row mb-4 dashboard-top-cards">
              <div className="col-md-6">
                <Card className="h-100 dashboard-card">
                  <Card.Body>
                    <Card.Title className="dashboard-card-title">Today's Attendance</Card.Title>
                    <Card.Text className="h2 text-primary">
                      {todayAttendance}
                    </Card.Text>
                    <Card.Text className="text-muted">
                      {membersCount} Members • {visitorsCount} Visitors
                    </Card.Text>
                  </Card.Body>
                </Card>
              </div>
              <div className="col-md-6">
                <Card className="h-100 dashboard-card">
                  <Card.Body>
                    <Card.Title className="dashboard-card-title">Today's Medical Appointments</Card.Title>
                    <Card.Text className="h2 text-primary">
                      {todayMedicalAppointments}
                    </Card.Text>
                    <Card.Text className="text-muted">
                      {medicalTrend && (
                        <span className={medicalTrend === 'increase' ? 'text-success' : 'text-danger'}>
                          {medicalTrend === 'increase' ? '↗' : '↘'} {medicalPercentage.toFixed(1)}% {medicalTrend === 'increase' ? 'increase' : 'decrease'} from yesterday
                        </span>
                      )}
                      {!medicalTrend && 'No change from yesterday'}
                    </Card.Text>
                  </Card.Body>
                </Card>
              </div>
            </div>

            {/* Customer List Section */}
            <div className="row">
              <div className="col-12">
                <DashboardCustomersList />
              </div>
            </div>
          </div>

          {/* Right Side Bar - 1/4 width */}
          <div className="col-md-3 dashboard-right-sidebar">
            <div className="column-container dashboard-column-container">
              <div className="column-card">
                <div className="d-flex justify-content-between align-items-center mb-3">
                  <h6 className="text-primary mb-0">List</h6>
                  <select 
                    value={selectedEventType} 
                    onChange={(e) => setSelectedEventType(e.target.value)}
                    className="form-select form-select-sm dashboard-event-selector"
                  >
                    {eventTypes.map((eventType) => (
                      <option key={eventType.value} value={eventType.value}>
                        {eventType.label}
                      </option>
                    ))}
                  </select>
                </div>
                <div>
                  {Array.from(groupedEvents?.keys())?.map((key) => {
                    return (
                      <div key={key}>
                        <h6 className="text-primary me-2 dashboard-event-date">{key}</h6>
                        {groupedEvents.get(key).map((eventItem, index) => (
                          <div key={index} className={`event-${eventItem.color || 'primary'} mb-3 event-list-item-container dashboard-event-item`}>
                            <div className="event-item-flex">
                              <div className="sx__month-agenda-event__title dashboard-event-title">
                                {selectedEventType === 'medical' ? eventItem.customer || eventItem.title : eventItem.title}
                              </div>
                              <div className="sx__event-modal__time dashboard-event-time">
                                {`${moment(eventItem?.start_time).format('hh:mm A')} ${eventItem?.end_time ? `- ${moment(eventItem?.end_time).format('hh:mm A')}` : ''}`}
                              </div>
                            </div>
                            <div className="sx__event-modal__time with-padding dashboard-event-description">
                              {selectedEventType === 'medical' ? `Provider: ${eventItem?.doctor || 'N/A'}` : eventItem?.description || 'No description'}
                            </div>
                          </div>
                        ))}
                      </div>
                    );
                  })}
                  {groupedEvents.size === 0 && (
                    <div className="text-muted text-center py-3">
                      {selectedEventType === 'incident' ? 'No attendance notes available' : `No ${(eventTypes.find(t => t.value === selectedEventType)?.label || selectedEventType).toLowerCase()} available`}
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Dashboard; 