import React, { useState, useEffect, useRef, useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { useNavigate, useSearchParams } from "react-router-dom";
import { selectInboundRoutes, selectTomorrowAllRoutes, selectTomorrowInboundRoutes, selectTomorrowOutboundRoutes, selectHistoryInboundRoutes, selectHistoryRoutes, selectHistoryOutboundRoutes, selectOutboundRoutes, selectAllRoutes, selectAllActiveVehicles, selectAllActiveDrivers, transRoutesSlice } from "./../../store";
import RoutesSection from "./RoutesSection";
import PersonnelSection from "./PersonnelSection";
import { AuthService, CustomerService, TransRoutesService, DriverService, EventsService, DailyRoutesTemplateService } from "../../services";
import { PERSONAL_ROUTE_STATUS, ROUTE_STATUS, reportRootUrl, CUSTOMER_TYPE_TEXT, PERSONAL_ROUTE_STATUS_TEXT, PICKUP_STATUS, PICKUP_STATUS_TEXT, REPORT_TYPE } from "../../shared";
import moment from 'moment';
import DatePicker from "react-datepicker";
import { CalendarWeek, ClockHistory, Copy, Download, Eraser, Plus, Clock, Filter, CalendarCheck, Check } from "react-bootstrap-icons";
import { Breadcrumb, Tabs, Tab, Dropdown, Spinner, Modal, Button, ProgressBar } from "react-bootstrap";
import RouteCustomerTable from "./RouteCustomerTable";


const RoutesDashboard = () => {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const { fetchAllRoutes, createRoute, fetchAllHistoryRoutes, fetchAllTomorrowRoutes, updateRoute }  = transRoutesSlice.actions;
  const inboundRoutes = useSelector(selectInboundRoutes);
  const outboundRoutes = useSelector(selectOutboundRoutes);
  const tmrInboundRoutes = useSelector(selectTomorrowInboundRoutes);
  const tmrOutboundRoutes = useSelector(selectTomorrowOutboundRoutes);
  const historyInboundRoutes = useSelector(selectHistoryInboundRoutes);
  const historyOutboundRoutes = useSelector(selectHistoryOutboundRoutes);
  const allRoutes = useSelector(selectAllRoutes);
  const allHistoryRoutes = useSelector(selectHistoryRoutes);
  const allTomorrowRoutes = useSelector(selectTomorrowAllRoutes);
  const drivers = useSelector(selectAllActiveDrivers);
  const vehicles = useSelector(selectAllActiveVehicles);
  const [showSyncCustomersLoading, setShowSyncCustomersLoading] = useState(false);
  const [keyword, setKeyword] = useState('');

  const [directorSignature, setDirectorSignature] = useState(undefined);
  const [selectedFile, setSelectedFile] = useState();
  const [selectedDriver, setSelectedDriver] = useState(undefined);
  const [driverList, setDriverList] = useState([]);
  const [customers, setCustomers] = useState([]);
  const [dateSelected, setDateSelected] = useState(new Date());
  const [routesForSignature, setRoutesForSignature] = useState(allRoutes);
  const [currentTab, setCurrentTab] = useState('allRoutesOverview');
  const [sorting, setSorting] = useState({key: '', order: ''});
  const [showFilterDropdown, setShowFilterDropdown] = useState(false);
  const [showDateDropdown, setShowDateDropdown] = useState(false);
  const [routesForShowing, setRoutesForShowing] = useState(allRoutes);
  const [routesInboundForShowing, setRoutesInboundForShowing] = useState(inboundRoutes);
  const [routesOutboundForShowing, setRoutesOutboundForShowing] = useState(outboundRoutes);

  const [isLoading, setIsLoading] = useState(false);
  const [errorMessage, setErrorMessage] = useState(undefined);
  const [successMessage, setSuccessMessage] = useState(undefined);
  const [showCopyTodayLoading, setShowCopyTodayLoading] = useState(false);
  const [showCopyDateLoading, setShowCopyDateLoading] = useState(false);
  const [showCopyDateTargetLoading, setShowCopyDateTargetLoading] = useState(false);
  const [copyDisabled, setCopyDisabled] = useState(false);
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [deleteRouteType, setDeleteRouteType] = useState('');
  const [targetedDateSelected, setTargetedDateSelected] = useState(undefined);
  const [originDateSelected, setOriginDateSelected] = useState(undefined);
  const [showOriginDateDropdown, setShowOriginDateDropdown] = useState(false);
  const [showTargetDateDropdown, setShowTargetDateDropdown] = useState(false);
  const [searchParams, setSearchParams] = useSearchParams();
  const [showFilterReportDropdown, setShowFilterReportDropdown]  = useState(false);

  const [statusFilter, setStatusFilter] = useState('');
  const [customerTypeFilter, setCustomerTypeFilter] = useState('');
  const [customerNameFilter, setCustomerNameFilter] = useState('');
  const [customerTableId, setCustomerTableId] = useState('');
  const [routeTypeFilter, setRouteTypeFilter] = useState('');
  
  // Save template modal state
  const [showSaveTemplateModal, setShowSaveTemplateModal] = useState(false);
  const [templateName, setTemplateName] = useState('');
  const [savingTemplate, setSavingTemplate] = useState(false);
  
  // Apply template state
  const [templates, setTemplates] = useState([]);
  const [selectedTemplateId, setSelectedTemplateId] = useState('');
  const [applyingTemplate, setApplyingTemplate] = useState(false);
  const [pageLoading, setPageLoading] = useState(false);
  const [showImportDateDropdown, setShowImportDateDropdown] = useState(false);
  const [showImportTemplateDropdown, setShowImportTemplateDropdown] = useState(false);
  const [importSourceDate, setImportSourceDate] = useState(undefined);
  const [importTemplateId, setImportTemplateId] = useState('');
  const [isScheduleImporting, setIsScheduleImporting] = useState(false);
  const [scheduleImportProgress, setScheduleImportProgress] = useState(0);
  const [scheduleImportLabel, setScheduleImportLabel] = useState('');
  const [showCheckRoutesModal, setShowCheckRoutesModal] = useState(false);
  const [checkRoutesResult, setCheckRoutesResult] = useState({ inbound: [], outbound: [], attendance: [], addressMismatch: [], customerTypeMismatch: [], customerSpecialNeedsMismatch: [], dischargedOnRoute: [] });
  const [customerTypeFixing, setCustomerTypeFixing] = useState({});
  const [customerSpecialNeedsFixing, setCustomerSpecialNeedsFixing] = useState({});
  const scheduleImportProgressTimerRef = useRef(null);


  const params = new URLSearchParams(window.location.search);
  const scheduleDate = params.get('dateSchedule');

  const getDateString = (date) => {
    return ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear()
  }

  const normalizeName = (name) => (name || '').toString().trim().toLowerCase();
  const normalizeAddress = (address) => {
    return (address || '')
      .toString()
      .toLowerCase()
      .replace(/\([^)]*\)/g, ' ')
      .replace(/[^a-z0-9]/g, ' ')
      .replace(/\s+/g, ' ')
      .trim();
  };

  // Match route addresses against stored structured addresses without state/zip sensitivity.
  const normalizeAddressForMismatchCheck = (address) => {
    return normalizeAddress(address)
      .replace(/\b\d{5}(?:\s*\d{4})?\b/g, ' ')
      .replace(/\b(maryland|md|virginia|va)\b/g, ' ')
      // Normalize unit identifiers like "Apt C-1" / "Apt C 1" to "Apt C1".
      .replace(/\b(apt|apartment|unit|suite|ste)\s+([a-z])\s+(\d+)\b/g, '$1 $2$3')
      .replace(/\s+/g, ' ')
      .trim();
  };

  const formatStructuredAddress = (line1, line2, city, state, zipCode, note) => {
    const cityState = [city, state].filter(Boolean).join(', ');
    const mainAddress = [line1, line2, cityState, zipCode]
      .filter((item) => item && String(item).trim() !== '')
      .join(' ')
      .trim();
    const addressNote = (note || '').trim();
    if (!mainAddress) return '';
    return addressNote ? `${mainAddress} (${addressNote})` : mainAddress;
  };

  const getStoredCustomerAddresses = (customerProfile) => {
    if (!customerProfile) return [];
    const structured = [
      formatStructuredAddress(customerProfile.address_line_1, customerProfile.address_line_2, customerProfile.city, customerProfile.state, customerProfile.zip_code, customerProfile.address_note),
      formatStructuredAddress(customerProfile.address2_line_1, customerProfile.address2_line_2, customerProfile.city2, customerProfile.state2, customerProfile.zip_code2, customerProfile.address2_note),
      formatStructuredAddress(customerProfile.address3_line_1, customerProfile.address3_line_2, customerProfile.city3, customerProfile.state3, customerProfile.zip_code3, customerProfile.address3_note),
      formatStructuredAddress(customerProfile.address4_line_1, customerProfile.address4_line_2, customerProfile.city4, customerProfile.state4, customerProfile.zip_code4, customerProfile.address4_note)
    ];
    return structured.filter((item) => (item || '').toString().trim() !== '');
  };

  const joinRouteNames = (routeNames = []) => {
    if (routeNames.length <= 1) return routeNames[0] || '';
    if (routeNames.length === 2) return `${routeNames[0]} and ${routeNames[1]}`;
    return `${routeNames.slice(0, -1).join(', ')}, and ${routeNames[routeNames.length - 1]}`;
  };

  const formatRouteAddressList = (routes = []) => {
    const parts = (routes || []).map((route) => `Route ${route.routeName}(address: ${route.customerAddress || 'N/A'})`);
    if (parts.length <= 1) return parts[0] || '';
    if (parts.length === 2) return `${parts[0]}, ${parts[1]}`;
    return `${parts.slice(0, -1).join(', ')}, and ${parts[parts.length - 1]}`;
  };

  const getCustomerTypeLabel = (type) => CUSTOMER_TYPE_TEXT[type] || type || 'N/A';
  const getCustomerKey = (customer) => {
    return customer?.customer_id || customer?.id || normalizeName(customer?.customer_name || customer?.name);
  };

  const getCustomerTimeKey = (route, customer) => {
    const candidates = [
      customer?.customer_estimated_pickup_time,
      customer?.customer_pickup_time,
      customer?.customer_estimated_dropoff_time,
      customer?.customer_dropoff_time,
      route?.estimated_start_time,
      route?.start_time
    ];
    for (const value of candidates) {
      if (!value) continue;
      const parsed = moment(value, [
        moment.ISO_8601,
        'MM/DD/YYYY HH:mm',
        'MM/DD/YYYY hh:mm A',
        'HH:mm',
        'hh:mm A'
      ], true);
      if (parsed.isValid()) {
        return parsed.format('HH:mm');
      }
      const fallback = moment(value);
      if (fallback.isValid()) {
        return fallback.format('HH:mm');
      }
    }
    return null;
  };

  const buildRouteConflictsByDirection = (routes = []) => {
    const byCustomer = new Map();
    (routes || []).forEach((route) => {
      (route?.route_customer_list || []).forEach((customer) => {
        const customerKey = customer?.customer_id || normalizeName(customer?.customer_name);
        if (!customerKey) return;
        const record = {
          customerKey,
          customerName: customer?.customer_name || 'Unknown',
          customerAddress: customer?.customer_address_override || customer?.customer_address || '',
          routeId: route?.id || route?._id || '',
          routeName: route?.name || 'Unnamed Route'
        };
        const existing = byCustomer.get(customerKey) || [];
        byCustomer.set(customerKey, [...existing, record]);
      });
    });

    const issues = [];
    byCustomer.forEach((records) => {
      const uniqueRoutes = Array.from(
        new Map(
          records.map((item) => [item.routeId, { routeId: item.routeId, routeName: item.routeName, customerAddress: item.customerAddress || '' }])
        ).values()
      );
      if (uniqueRoutes.length < 2) return;
      issues.push({
        customerName: records[0]?.customerName || 'Unknown',
        routes: uniqueRoutes
      });
    });
    return issues;
  };

  const recurRuleFallsOnDate = (rule, targetDate) => {
    const start = new Date(rule.start_repeat_date);
    const end = new Date(rule.end_repeat_date);
    const target = new Date(targetDate);
    start.setHours(0, 0, 0, 0);
    end.setHours(0, 0, 0, 0);
    target.setHours(0, 0, 0, 0);
    if (target < start || target > end) return false;

    const freq = rule.rrule;
    let current = new Date(start);
    let count = 0;
    while (current <= target && count < 5000) {
      if (current.getTime() === target.getTime()) return true;
      if (freq === 'FREQ=DAILY') {
        current = new Date(current.getTime() + 24 * 60 * 60 * 1000);
      } else if (freq === 'FREQ=WEEKLY') {
        current = new Date(current.getTime() + 7 * 24 * 60 * 60 * 1000);
      } else if (freq === 'FREQ=MONTHLY') {
        const next = new Date(current);
        next.setMonth(next.getMonth() + 1);
        current = next;
      } else if (freq === 'FREQ=YEARLY') {
        const next = new Date(current);
        next.setFullYear(next.getFullYear() + 1);
        current = next;
      } else {
        break;
      }
      count += 1;
    }
    return false;
  };

  const getRoutesByCustomerForCheck = (routes = []) => {
    const map = new Map();
    routes.forEach((route) => {
      (route?.route_customer_list || []).forEach((customer) => {
        const key = getCustomerKey(customer);
        if (!key) return;
        const existing = map.get(key) || {
          customerName: customer?.customer_name || customer?.name || 'Unknown',
          routeNames: new Set()
        };
        existing.routeNames.add(route?.name || 'Unnamed Route');
        map.set(key, existing);
      });
    });
    return map;
  };

  const buildAttendanceNoteRouteIssues = async () => {
    const dateText = moment(dateSelected).format('YYYY-MM-DD');
    const noteDateLabel = moment(dateSelected).format('MM/DD/YYYY');
    const [eventsRes, recurRes] = await Promise.all([
      EventsService.getAllEvents({ date: dateText, type: 'incident' }),
      EventsService.getAllEventRecurrences()
    ]);

    const notes = [];
    const singleNotes = (eventsRes?.data || []).filter(
      (event) => event?.type === 'incident' && event?.status === 'active' && event?.target_uuid
    );
    singleNotes.forEach((note) => {
      notes.push({
        customerKey: note.target_uuid,
        noteDate: note?.start_time ? moment(note.start_time).format('MM/DD/YYYY') : noteDateLabel
      });
    });

    const recurringNotes = (recurRes?.data || []).filter(
      (rule) => rule?.type === 'incident' && rule?.status === 'active' && rule?.target_uuid && rule?.rrule
    );
    recurringNotes.forEach((rule) => {
      if (recurRuleFallsOnDate(rule, dateSelected)) {
        notes.push({
          customerKey: rule.target_uuid,
          noteDate: noteDateLabel
        });
      }
    });

    const allFutureRoutes = [...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])];
    const routesByCustomer = getRoutesByCustomerForCheck(allFutureRoutes);
    const dedupe = new Set();
    const issues = [];
    notes.forEach((note) => {
      const routeInfo = routesByCustomer.get(note.customerKey);
      if (!routeInfo || routeInfo.routeNames.size === 0) return;
      const dedupeKey = `${note.customerKey}|${note.noteDate}|${Array.from(routeInfo.routeNames).sort().join('|')}`;
      if (dedupe.has(dedupeKey)) return;
      dedupe.add(dedupeKey);
      issues.push({
        customerName: routeInfo.customerName,
        noteDate: note.noteDate,
        routeNames: Array.from(routeInfo.routeNames)
      });
    });
    return issues;
  };

  const buildAddressMismatchIssues = (routes = []) => {
    const customerProfileById = new Map((customers || []).map((customer) => [customer.id, customer]));
    const mismatchMap = new Map();

    (routes || []).forEach((route) => {
      (route?.route_customer_list || []).forEach((customerInRoute) => {
        const customerId = customerInRoute?.customer_id;
        if (!customerId) return;
        const customerProfile = customerProfileById.get(customerId);
        if (!customerProfile) return;

        const routeAddress = customerInRoute?.customer_address_override || customerInRoute?.customer_address || '';
        const normalizedRouteAddress = normalizeAddressForMismatchCheck(routeAddress);
        if (!normalizedRouteAddress) return;

        const storedAddressSet = new Set(
          getStoredCustomerAddresses(customerProfile)
            .map((address) => normalizeAddressForMismatchCheck(address))
            .filter(Boolean)
        );
        if (storedAddressSet.size === 0) return;
        if (storedAddressSet.has(normalizedRouteAddress)) return;

        const key = `${customerId}|${normalizedRouteAddress}`;
        const existing = mismatchMap.get(key) || {
          customerName: customerInRoute?.customer_name || customerProfile?.name || 'Unknown',
          routeAddress,
          routeNames: new Set()
        };
        existing.routeNames.add(route?.name || 'Unnamed Route');
        mismatchMap.set(key, existing);
      });
    });

    return Array.from(mismatchMap.values()).map((item) => ({
      customerName: item.customerName,
      routeAddress: item.routeAddress,
      routeNames: Array.from(item.routeNames)
    }));
  };

  const buildCustomerTypeMismatchIssues = (routes = []) => {
    const customerProfileById = new Map((customers || []).map((customer) => [customer.id, customer]));
    const mismatchMap = new Map();
    (routes || []).forEach((route) => {
      (route?.route_customer_list || []).forEach((customerInRoute) => {
        const customerId = customerInRoute?.customer_id;
        if (!customerId) return;
        const customerProfile = customerProfileById.get(customerId);
        if (!customerProfile) return;

        const routeType = `${customerInRoute?.customer_type || ''}`.trim();
        const dbType = `${customerProfile?.type || ''}`.trim();
        if (!dbType) return;
        if (routeType.toLowerCase() === dbType.toLowerCase()) return;

        const existing = mismatchMap.get(customerId) || {
          customerId,
          customerName: customerInRoute?.customer_name || customerProfile?.name || 'Unknown',
          dbType,
          mismatchedRoutes: []
        };
        existing.mismatchedRoutes.push({
          routeId: route?.id,
          routeName: route?.name || 'Unnamed Route',
          routeType: routeType || 'N/A'
        });
        mismatchMap.set(customerId, existing);
      });
    });
    return Array.from(mismatchMap.values()).map((item) => ({
      ...item,
      mismatchedRoutes: item.mismatchedRoutes.filter((route, idx, arr) => arr.findIndex((r) => r.routeId === route.routeId) === idx)
    }));
  };

  const buildDischargedCustomerRouteIssues = (routes = []) => {
    const customerProfileById = new Map((customers || []).map((customer) => [customer.id, customer]));
    const issuesMap = new Map();
    (routes || []).forEach((route) => {
      (route?.route_customer_list || []).forEach((customerInRoute) => {
        const customerId = customerInRoute?.customer_id;
        if (!customerId) return;
        const customerProfile = customerProfileById.get(customerId);
        if (!customerProfile) return;
        if (`${customerProfile?.type || ''}` !== 'discharged') return;
        const existing = issuesMap.get(customerId) || {
          customerName: customerInRoute?.customer_name || customerProfile?.name || 'Unknown',
          routeNames: new Set()
        };
        existing.routeNames.add(route?.name || 'Unnamed Route');
        issuesMap.set(customerId, existing);
      });
    });
    return Array.from(issuesMap.values()).map((issue) => ({
      customerName: issue.customerName,
      routeNames: Array.from(issue.routeNames)
    }));
  };

  const buildCustomerSpecialNeedsMismatchIssues = (routes = []) => {
    const customerProfileById = new Map((customers || []).map((customer) => [customer.id, customer]));
    const mismatchMap = new Map();
    (routes || []).forEach((route) => {
      (route?.route_customer_list || []).forEach((customerInRoute) => {
        const customerId = customerInRoute?.customer_id;
        if (!customerId) return;
        const customerProfile = customerProfileById.get(customerId);
        if (!customerProfile) return;

        const routeNote = `${customerInRoute?.customer_special_needs || ''}`.trim();
        const dbNoteToDriver = `${customerProfile?.notes_for_driver || ''}`.trim();
        if (routeNote === dbNoteToDriver) return;

        const existing = mismatchMap.get(customerId) || {
          customerId,
          customerName: customerInRoute?.customer_name || customerProfile?.name || 'Unknown',
          dbNoteToDriver,
          mismatchedRoutes: []
        };
        existing.mismatchedRoutes.push({
          routeId: route?.id,
          routeName: route?.name || 'Unnamed Route',
          routeNote: routeNote || ''
        });
        mismatchMap.set(customerId, existing);
      });
    });
    return Array.from(mismatchMap.values()).map((item) => ({
      ...item,
      mismatchedRoutes: item.mismatchedRoutes.filter((route, idx, arr) => arr.findIndex((r) => r.routeId === route.routeId) === idx)
    }));
  };

  const syncCustomerTypeForMismatch = async (issue) => {
    if (!issue?.customerId || !issue?.dbType || !issue?.mismatchedRoutes?.length) return;
    setCustomerTypeFixing((prev) => Object.assign({}, prev, { [issue.customerId]: true }));
    try {
      const routeMap = new Map([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])].map((route) => [route.id, route]));
      const updatePromises = issue.mismatchedRoutes.map((routeMeta) => {
        const route = routeMap.get(routeMeta.routeId);
        if (!route) return Promise.resolve();
        const nextCustomerList = (route.route_customer_list || []).map((customer) => {
          if (customer?.customer_id !== issue.customerId) return customer;
          return Object.assign({}, customer, { customer_type: issue.dbType });
        });
        return TransRoutesService.updateRoute(route.id, Object.assign({}, route, { route_customer_list: nextCustomerList }));
      });
      await Promise.all(updatePromises);
      setSuccessMessage(`Synced member type for ${issue.customerName}.`);
      setTimeout(() => setSuccessMessage(undefined), 5000);
      dispatch(fetchAllTomorrowRoutes({dateText: moment(dateSelected).format('MM/DD/YYYY')}));
      await runCheckRoutes();
    } catch (error) {
      console.error('Error syncing customer type mismatch:', error);
      setErrorMessage(`Failed to sync member type for ${issue.customerName}.`);
      setTimeout(() => setErrorMessage(undefined), 5000);
    } finally {
      setCustomerTypeFixing((prev) => Object.assign({}, prev, { [issue.customerId]: false }));
    }
  };

  const syncCustomerSpecialNeedsForMismatch = async (issue) => {
    if (!issue?.customerId || !issue?.mismatchedRoutes?.length) return;
    setCustomerSpecialNeedsFixing((prev) => Object.assign({}, prev, { [issue.customerId]: true }));
    try {
      const routeMap = new Map([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])].map((route) => [route.id, route]));
      const updatePromises = issue.mismatchedRoutes.map((routeMeta) => {
        const route = routeMap.get(routeMeta.routeId);
        if (!route) return Promise.resolve();
        const nextCustomerList = (route.route_customer_list || []).map((customer) => {
          if (customer?.customer_id !== issue.customerId) return customer;
          return Object.assign({}, customer, { customer_special_needs: issue.dbNoteToDriver || '' });
        });
        return TransRoutesService.updateRoute(route.id, Object.assign({}, route, { route_customer_list: nextCustomerList }));
      });
      await Promise.all(updatePromises);
      setSuccessMessage(`Synced note to driver for ${issue.customerName}.`);
      setTimeout(() => setSuccessMessage(undefined), 5000);
      dispatch(fetchAllTomorrowRoutes({dateText: moment(dateSelected).format('MM/DD/YYYY')}));
      await runCheckRoutes();
    } catch (error) {
      console.error('Error syncing note to driver mismatch:', error);
      setErrorMessage(`Failed to sync note to driver for ${issue.customerName}.`);
      setTimeout(() => setErrorMessage(undefined), 5000);
    } finally {
      setCustomerSpecialNeedsFixing((prev) => Object.assign({}, prev, { [issue.customerId]: false }));
    }
  };

  const runCheckRoutes = async () => {
    const inboundIssues = buildRouteConflictsByDirection(tmrInboundRoutes || []);
    const outboundIssues = buildRouteConflictsByDirection(tmrOutboundRoutes || []);
    const addressMismatchIssues = buildAddressMismatchIssues([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])]);
    const customerTypeMismatchIssues = buildCustomerTypeMismatchIssues([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])]);
    const customerSpecialNeedsMismatchIssues = buildCustomerSpecialNeedsMismatchIssues([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])]);
    const dischargedOnRouteIssues = buildDischargedCustomerRouteIssues([...(tmrInboundRoutes || []), ...(tmrOutboundRoutes || [])]);
    let attendanceIssues = [];
    try {
      attendanceIssues = await buildAttendanceNoteRouteIssues();
    } catch (error) {
      console.error('Error checking attendance notes against routes:', error);
    }
    setCheckRoutesResult({ inbound: inboundIssues, outbound: outboundIssues, attendance: attendanceIssues, addressMismatch: addressMismatchIssues, customerTypeMismatch: customerTypeMismatchIssues, customerSpecialNeedsMismatch: customerSpecialNeedsMismatchIssues, dischargedOnRoute: dischargedOnRouteIssues });
    setShowCheckRoutesModal(true);
  };

  const processRoutesForAbsentCustomers = useCallback((inboundRoutes, outboundRoutes) => {
    // Get customers who are absent in inbound routes
    const absentCustomerIds = new Set();
    
    inboundRoutes.forEach(inboundRoute => {
      inboundRoute.route_customer_list?.forEach(customer => {
        if (customer.customer_route_status === PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT || 
            customer.customer_route_status === PERSONAL_ROUTE_STATUS.UNEXPECTED_ABSENT) {
          absentCustomerIds.add(customer.customer_id);
        }
      });
    });

    // Remove absent customers from outbound routes for display
    const processedOutboundRoutes = outboundRoutes.map(outboundRoute => ({
      ...outboundRoute,
      route_customer_list: outboundRoute.route_customer_list?.filter(customer => 
        !absentCustomerIds.has(customer.customer_id)
      ) || []
    }));

    return processedOutboundRoutes;
  }, [])

  useEffect(() => {
    setPageLoading(true);
    if (scheduleDate) {
      const [year, month, day] = scheduleDate?.split('-').map(Number);
      setDateSelected(new Date(year, month-1, day));
    } else {
      setDateSelected(new Date())
    }
    const site = EventsService.site;
    Promise.all([
      DriverService.getAllActiveDrivers('driver', 'active').then((data) => {
        setDriverList(data.data);
      }),
      CustomerService.getAllCustomers().then((data) => setCustomers(data?.data)),
      CustomerService.getAvatar(`center_director_signature_site_${site}`).then(data => {
        if (data?.data) {
          setDirectorSignature(data?.data)
        }
      }).catch(() => {}),
      DailyRoutesTemplateService.getAll().then((response) => {
        setTemplates(response.data || []);
      }).catch(err => {
        console.error('Error fetching templates:', err);
      })
    ]).finally(() => {
      setPageLoading(false);
    });
  }, []);

  useEffect(() => {
    TransRoutesService.getAll(moment(dateSelected)?.format('MM/DD/YYYY')).then(data => {
      const routesResults = data.data;
      const finalRoutes = routesResults.map(async (routeItem) => {
        const dateArr = moment(dateSelected)?.format('MM/DD/YYYY')?.split('/') || [];
        try {
          const result = await CustomerService.getAvatar(`${routeItem.id}_${routeItem.driver}_${dateArr[0]}_${dateArr[1]}`);
          return result?.data ? Object.assign({}, routeItem, {signature: result?.data}) : routeItem;
        } catch (ex) {
          return routeItem;
        }
      });
      Promise.all(finalRoutes).then(finalRoutesData => {
        setRoutesForSignature(finalRoutesData);
      })
    });
    const selectedDateString = getDateString(dateSelected);
    if (selectedDateString === getDateString(new Date())) {
      dispatch(fetchAllRoutes());
    } else {
      if (dateSelected > new Date()) {
        dispatch(fetchAllTomorrowRoutes({dateText: moment(dateSelected).format('MM/DD/YYYY')}));
      } else {
        dispatch(fetchAllHistoryRoutes({dateText: getDateString(dateSelected)}))
      }
    }
  }, [dateSelected]);

  useEffect(() => {
    const selectedDateString = getDateString(dateSelected);
    if (!dateSelected || selectedDateString === getDateString(new Date())) {
      setRoutesForShowing(allRoutes);
      setRoutesInboundForShowing(inboundRoutes);
      setRoutesOutboundForShowing(processRoutesForAbsentCustomers(inboundRoutes, outboundRoutes));
    } else {
      if (dateSelected > new Date()) {
        setRoutesForShowing(allTomorrowRoutes);
        setRoutesInboundForShowing(tmrInboundRoutes);
        setRoutesOutboundForShowing(processRoutesForAbsentCustomers(tmrInboundRoutes, tmrOutboundRoutes));
      } else {
        setRoutesForShowing(allHistoryRoutes);
        setRoutesOutboundForShowing(processRoutesForAbsentCustomers(historyInboundRoutes, historyOutboundRoutes));
        setRoutesInboundForShowing(historyInboundRoutes);
      }
    }
  }, [allRoutes, allHistoryRoutes, allTomorrowRoutes]);

  const now = new Date();
  const yesterday = new Date();
  const tomorrow = new Date();
  const isFutureScheduleSelected = moment(dateSelected).startOf('day').isAfter(moment().startOf('day'));

  const startScheduleImportProgress = (label) => {
    if (scheduleImportProgressTimerRef.current) {
      clearInterval(scheduleImportProgressTimerRef.current);
    }
    setScheduleImportLabel(label);
    setScheduleImportProgress(10);
    setIsScheduleImporting(true);
    scheduleImportProgressTimerRef.current = setInterval(() => {
      setScheduleImportProgress((prev) => (prev >= 90 ? 90 : prev + 5));
    }, 250);
  };

  const finishScheduleImportProgress = () => {
    if (scheduleImportProgressTimerRef.current) {
      clearInterval(scheduleImportProgressTimerRef.current);
      scheduleImportProgressTimerRef.current = null;
    }
    setScheduleImportProgress(100);
    setTimeout(() => {
      setIsScheduleImporting(false);
      setScheduleImportProgress(0);
      setScheduleImportLabel('');
    }, 400);
  };

  const refreshRoutesForCurrentDate = () => {
    const selectedDateString = getDateString(dateSelected);
    if (selectedDateString === getDateString(new Date())) {
      dispatch(fetchAllRoutes());
    } else if (dateSelected > new Date()) {
      dispatch(fetchAllTomorrowRoutes({dateText: moment(dateSelected).format('MM/DD/YYYY')}));
    } else {
      dispatch(fetchAllHistoryRoutes({dateText: getDateString(dateSelected)}));
    }
  };

  const buildImportedRouteData = (draftRoute, targetDateText) => {
    return {
      name: draftRoute?.name,
      vehicle: draftRoute?.vehicle,
      driver: draftRoute?.driver,
      type: draftRoute?.type,
      schedule_date: targetDateText,
      start_mileage: draftRoute?.start_mileage || vehicles.find((vehicle) => vehicle.id === draftRoute?.vehicle)?.mileage,
      end_mileage: draftRoute?.end_mileage,
      status: [],
      start_time: null,
      end_time: null,
      estimated_start_time: null,
      checklist_result: draftRoute?.checklist_result || [],
      route_customer_list: (draftRoute.route_customer_list || []).map((customer) => ({
        ...customer,
        customer_enter_center_time: null,
        customer_leave_center_time: null,
        customer_pickup_time: null,
        customer_dropoff_time: null,
        customer_estimated_pickup_time: null,
        customer_estimated_dropoff_time: null,
        customer_route_status: null,
        customer_address_override: null
      }))
    };
  };

  const importFromDate = async () => {
    if (!importSourceDate) {
      window.alert('Please select a source date.');
      return;
    }
    startScheduleImportProgress('Importing schedule from selected date...');
    try {
      const sourceDateText = getDateString(importSourceDate);
      const targetDateText = getDateString(dateSelected);
      const [{ data: sourceRoutes }, { data: existingRoutes }] = await Promise.all([
        TransRoutesService.getAll(sourceDateText),
        TransRoutesService.getAll(targetDateText)
      ]);

      let skippedCount = 0;
      const createPromises = [];
      for (const draftRoute of (sourceRoutes || [])) {
        const existed = (existingRoutes || []).find((r) => r.name === draftRoute.name && r.type === draftRoute.type);
        if (existed) {
          skippedCount++;
          continue;
        }
        const routeData = buildImportedRouteData(draftRoute, targetDateText);
        createPromises.push(TransRoutesService.createNewRoute(routeData));
      }
      await Promise.all(createPromises);
      refreshRoutesForCurrentDate();
      setShowImportDateDropdown(false);
      setSuccessMessage(`Imported ${createPromises.length} route(s) from ${sourceDateText}.`);
      setTimeout(() => setSuccessMessage(undefined), 5000);
      if (skippedCount > 0) {
        window.alert(`${skippedCount} route(s) already existed on target date and were skipped.`);
      }
    } catch (error) {
      console.error('Failed to import routes from date:', error);
      setErrorMessage(error?.message || 'Failed to import routes from date');
      setTimeout(() => setErrorMessage(undefined), 5000);
    } finally {
      finishScheduleImportProgress();
    }
  };

  const importFromTemplate = async () => {
    if (!importTemplateId) {
      window.alert('Please select a template.');
      return;
    }
    const selectedTemplate = templates.find((t) => t.id === importTemplateId);
    if (!selectedTemplate) {
      window.alert('Template not found.');
      return;
    }
    startScheduleImportProgress('Copying routes from template...');
    try {
      const targetDateText = getDateString(dateSelected);
      const { data: existingRoutes } = await TransRoutesService.getAll(targetDateText);
      let skippedCount = 0;
      const createPromises = [];
      for (const route of (selectedTemplate.routes || [])) {
        const existed = (existingRoutes || []).find((r) => r.name === route.name && r.type === route.type);
        if (existed) {
          skippedCount++;
          continue;
        }
        const routeData = buildImportedRouteData(route, targetDateText);
        createPromises.push(TransRoutesService.createNewRoute(routeData));
      }
      await Promise.all(createPromises);
      refreshRoutesForCurrentDate();
      setShowImportTemplateDropdown(false);
      setImportTemplateId('');
      setSuccessMessage(`Imported ${createPromises.length} route(s) from template "${selectedTemplate.name}".`);
      setTimeout(() => setSuccessMessage(undefined), 5000);
      if (skippedCount > 0) {
        window.alert(`${skippedCount} route(s) already existed on target date and were skipped.`);
      }
    } catch (error) {
      console.error('Failed to import routes from template:', error);
      setErrorMessage(error?.message || 'Failed to import routes from template');
      setTimeout(() => setErrorMessage(undefined), 5000);
    } finally {
      finishScheduleImportProgress();
    }
  };
  yesterday.setDate(now.getDate() - 1);
  tomorrow.setDate(now.getDate() + 1);
  
  const directToSchedule = () => {
    setDateSelected(tomorrow);
  }
  const generateRouteReport = () => {
    window.open(`${reportRootUrl}?token=${localStorage.getItem('token')}&date=${getDateString(now)}`, '_blank');
  }
  const goToHistoryPage = () => {
    navigate('/trans-routes/history');
  }
  const createVehicle = () => {
    navigate('/vehicles?redirect=schedule');
  }

  const createDriver = () => {
    navigate('/employees?redirect=schedule&type=driver');
  }
  // const goToSignature = () => {
  //   navigate('/trans-routes/route-signature');
  // }
  const createNewRoute = () => {
    navigate('/trans-routes/create')
  }
  const goToCreateRoute = (type) => {
    navigate(`/trans-routes/create?type=${type}&date=${dateSelected? moment(dateSelected).format('YYYY-MM-DD'): 'tomorrow'}`);
  }
  const goToRouteDetails = (routeId) => {
    if (!routeId) return;
    const selectedDateString = getDateString(dateSelected);
    if (selectedDateString === getDateString(new Date())) {
      navigate(`/trans-routes/${routeId}`);
      return;
    }
    navigate(`/trans-routes/${routeId}?dateSchedule=${moment(dateSelected).format('YYYY-MM-DD')}`);
  }
  const changeTab = (k) => {
    setCurrentTab(k);
    setKeyword('');
    setSorting({key: '', order: ''});
    setDateSelected(new Date());
    setOriginDateSelected(undefined);
    setTargetedDateSelected(undefined);
    // setSelectedDriver(undefined);
  }

  const cleanupSchedule = () => {
    const routesToDelete = deleteRouteType === 'inbound'
      ? (tmrInboundRoutes || [])
      : deleteRouteType === 'outbound'
        ? (tmrOutboundRoutes || [])
        : (allTomorrowRoutes || []);
    routesToDelete.forEach((route) => {
      TransRoutesService.deleteRoute(route.id);
    });
    setTimeout(() => {
      closeDeleteModal();
      window.location.reload();
    }, 1000)
  }

  const closeDeleteModal = () => {
    setShowDeleteModal(false);
    setDeleteRouteType('');
  }

  const triggerShowDeleteModal = (routeType = '') => {
    setDeleteRouteType(routeType);
    setShowDeleteModal(true);
  }

  const startToScheduleDate = (v) => {
    // setDateSchedule(v);
    setSearchParams({dateSchedule: moment(v).format('YYYY-MM-DD')});
    dispatch(fetchAllTomorrowRoutes({dateText: moment(v).format('MM/DD/YYYY')}));
  } 

  const validateSchedule = () => {
    const inboundCustomersRouteMap = {};
    let success = true;
    for (const inboundRoute of tmrInboundRoutes) {
      for (const inboundCustomer of inboundRoute.route_customer_list) {
        if (Object.keys(inboundCustomersRouteMap).includes(inboundCustomer.customer_id) && inboundCustomer.customer_route_status !== PERSONAL_ROUTE_STATUS.DISABLED) {
          setSuccessMessage(undefined);
          success = false;
          setErrorMessage(`Error: Customer ${inboundCustomer.customer_name} was scheduled in both inbound ${inboundRoute.name} and ${inboundCustomersRouteMap[inboundCustomer.customer_id].name}.`)
          break;
        } else {
          if (inboundCustomer.customer_route_status !== PERSONAL_ROUTE_STATUS.DISABLED) {
            inboundCustomersRouteMap[inboundCustomer.customer_id] = inboundRoute;
          }
          
        }
      }
    }
    const outboundCustomersRouteMap = {};
    for (const outboundRoute of tmrOutboundRoutes) {
      for (const outboundCustomer of outboundRoute.route_customer_list) {
        if (Object.keys(outboundCustomersRouteMap).includes(outboundCustomer.customer_id) && outboundCustomer.customer_route_status !== PERSONAL_ROUTE_STATUS.DISABLED) {
          setSuccessMessage(undefined);
          success = false;
          setErrorMessage(`Error: Customer ${outboundCustomer.customer_name} was scheduled in both outbound ${outboundRoute.name} and ${outboundCustomersRouteMap[outboundCustomer.customer_id].name}.`)
          break;
        } else {
          if (outboundCustomer.customer_route_status !== PERSONAL_ROUTE_STATUS.DISABLED) {
            outboundCustomersRouteMap[outboundCustomer.customer_id] = outboundRoute;
          }
          
        }
      }
    }
    if (success) {
      setErrorMessage(undefined);
      setSuccessMessage(`Routes Schedule Validate Successfully`);
    }
  }

  const copyTodayRoutesOver = () => {
    setShowCopyTodayLoading(true);
    setIsLoading(true);
    let count = 0;
    TransRoutesService.getAll(((now.getMonth() > 8) ? (now.getMonth() + 1) : ('0' + (now.getMonth() + 1))) + '/' + ((now.getDate() > 9) ? now.getDate() : ('0' + now.getDate())) + '/' + now.getFullYear()).then(existingRoutes => {
      for (const draftRoute of allRoutes) {
        const existed = existingRoutes?.data?.find(r => r.name === draftRoute.name);
        if (draftRoute && !existed) {
          const data = Object.assign({}, {
            name: draftRoute.name,
            schedule_date: ((now.getMonth() > 8) ? (now.getMonth() + 1) : ('0' + (now.getMonth() + 1))) + '/' + ((now.getDate() > 9) ? now.getDate() : ('0' + now.getDate())) + '/' + now.getFullYear(),
            vehicle: draftRoute.vehicle,
            driver: draftRoute.driver,
            type: draftRoute.type,
            start_mileage: vehicles.find((vehicle) => vehicle.id === draftRoute.vehicle)?.mileage,
            route_customer_list: draftRoute.route_customer_list?.map((customer) => {
              return Object.assign({}, customer, {
                customer_enter_center_time: null,
                customer_leave_center_time: null,
                customer_pickup_time: null,
                customer_dropoff_time: null,
                customer_estimated_pickup_time: null,
                customer_estimated_dropoff_time: null,
                customer_route_status: null,
                customer_address_override: null
              })
            })
          });
          dispatch(createRoute({ data }));
        } else {
          if (existed) {
            count++;
          }
        }
      }
      setTimeout(() => {
        dispatch(fetchAllTomorrowRoutes({}));
        setShowCopyTodayLoading(false);
        setCopyDisabled(true);
        setIsLoading(false);
        setSuccessMessage('Routes Copied Successfully, please do not click the button again!');
        if (count > 0) {
          window.alert(`${count} routes has existed in selected date and is not copied again!`)
        }
      }, 2000);
    })
  }

  const copyDateRoutesOver = (withTargetDate) => {
    const dateOrigin = new Date(originDateSelected);
    const newScheduleDate = withTargetDate ? new Date(targetedDateSelected) : now;
    if (withTargetDate) {
      setShowCopyDateTargetLoading(true);
    } else {
      setShowCopyDateLoading(true);
    }

    setIsLoading(true);
    let count = 0;
    TransRoutesService.getAll(getDateString(dateOrigin)).then(({data: allHistoryRoutes}) => {
      TransRoutesService.getAll(((newScheduleDate.getMonth() > 8) ? (newScheduleDate.getMonth() + 1) : ('0' + (newScheduleDate.getMonth() + 1))) + '/' + ((newScheduleDate.getDate() > 9) ? newScheduleDate.getDate() : ('0' + newScheduleDate.getDate())) + '/' + newScheduleDate.getFullYear()).then(existingRoutes => {
        for (const draftRoute of allHistoryRoutes) {
          const existed = existingRoutes?.data?.find((r) => r. name === draftRoute.name);
          if (draftRoute && !existed) {
            const data = Object.assign({}, {
              name: draftRoute.name,
              schedule_date: ((newScheduleDate.getMonth() > 8) ? (newScheduleDate.getMonth() + 1) : ('0' + (newScheduleDate.getMonth() + 1))) + '/' + ((newScheduleDate.getDate() > 9) ? newScheduleDate.getDate() : ('0' + newScheduleDate.getDate())) + '/' + newScheduleDate.getFullYear(),
              vehicle: draftRoute.vehicle,
              driver: draftRoute.driver,
              type: draftRoute.type,
              start_mileage: vehicles.find((vehicle) => vehicle.id === draftRoute.vehicle)?.mileage,
              route_customer_list: draftRoute.route_customer_list?.map((customer) => {
                return Object.assign({}, customer, {
                  customer_enter_center_time: null,
                  customer_leave_center_time: null,
                  customer_pickup_time: null,
                  customer_dropoff_time: null,
                  customer_estimated_pickup_time: null,
                  customer_estimated_dropoff_time: null,
                  customer_route_status: null,
                  customer_address_override: null
                })
              })
            });
            dispatch(createRoute({ data }));
          } else {
            if (existed) {
              count++;
            }
          }
        }
        setTimeout(() => {
          // dispatch(fetchAllTomorrowRoutes({}));
          startToScheduleDate(withTargetDate ? targetedDateSelected : now);
          if (withTargetDate) {
            setShowCopyDateTargetLoading(false);
          } else {
            setShowCopyDateLoading(false);
          }
          setIsLoading(false);
          // setCopyDateDisabled(true);
          setSuccessMessage('Routes Copied Successfully, please do not click the button again!');
          setDateSelected(targetedDateSelected);
          setOriginDateSelected(undefined);
          setTargetedDateSelected(undefined);
          if (count > 0) {
            window.alert(`${count} routes has existed on selected date and are not copied again.`)
          }
        }, 2000);
      });
    });
  }


  const uploadDirectorSignature = () => {
    const formData = new FormData();
    const site = EventsService.site;
  	formData.append("file", selectedFile);
    if (selectedFile) {
      if (directorSignature) {
        CustomerService.deleteFile({'name': `center_director_signature_site_${site}`}).then(() => {
          CustomerService.uploadAvatar(`center_director_signature_site_${site}`, formData).then(() => {
            CustomerService.getAvatar(`center_director_signature_site_${site}`).then(data => {
              if (data?.data) {
                setDirectorSignature(data?.data)
              }
            });
          })
        })
      } else {
        CustomerService.uploadAvatar(`center_director_signature_site_${site}`, formData).then(() => {
          CustomerService.getAvatar(`center_director_signature_site_${site}`).then(data => {
            if (data?.data) {
              setDirectorSignature(data?.data)
            }
          });
        })
      }
    }
  }

  const getAllUniqueCustomers = (routes) => {
    let result = [];
    for (const route of routes) {
      const customerList = route.route_customer_list.map(item => Object.assign({}, item, {routeType: route.type, routeId: route.id, route: route, customer_status_inbound: route.type === 'inbound' && item.customer_route_status, customer_status_outbound: route.type === 'outbound' && item.customer_route_status,  inbound: route.type === 'inbound' && route, outbound: route.type === 'outbound' && route}))
      for (const customer of customerList) {
        const existItem = result.find((item => (item.customer_id === customer.customer_id) || (item?.customer_name?.replaceAll(' ', '')?.toLowerCase() === customer?.customer_name?.replaceAll(' ', '')?.toLowerCase()) ));
        if (existItem) {
          result = result.filter(item => item !== existItem);
          const newItem = Object.assign({}, existItem, {
            customer_enter_center_time: existItem?.customer_enter_center_time || customer?.customer_enter_center_time,
            customer_leave_center_time: existItem?.customer_leave_center_time || customer?.customer_leave_center_time,
            customer_pickup_time: existItem?.customer_pickup_time || customer?.customer_pickup_time,
            customer_dropoff_time: existItem?.customer_dropoff_time || customer?.customer_dropoff_time,
            inbound: existItem?.inbound || customer?.inbound,
            outbound: existItem?.outbound || customer?.outbound,
            customer_status_inbound: existItem?.customer_status_inbound || customer?.customer_status_inbound,
            customer_status_outbound: existItem?.customer_status_outbound || customer?.customer_status_outbound
          })
          result.push(newItem);
        } else {
          result.push(customer);
        }
      }
    }
    return result.sort((a, b) => {
      if (a.customer_name < b.customer_name) {
        return -1;
      } else {
        return 1;
      }
    });
  }

  const copyYesterdayRoutes = () => {
    setShowCopyDateLoading(true);
    TransRoutesService.getAll(getDateString(yesterday)).then(({data: yesterdayRoutes}) => {
      for (const draftRoute of yesterdayRoutes) {
        if (draftRoute) {
          const data = Object.assign({}, {
            name: draftRoute.name,
            schedule_date: ((now.getMonth() > 8) ? (now.getMonth() + 1) : ('0' + (now.getMonth() + 1))) + '/' + ((now.getDate() > 9) ? now.getDate() : ('0' + now.getDate())) + '/' + now.getFullYear(),
            vehicle: draftRoute.vehicle,
            driver: draftRoute.driver,
            type: draftRoute.type,
            start_mileage: vehicles.find((vehicle) => vehicle.id === draftRoute.vehicle)?.mileage,
            route_customer_list: draftRoute.route_customer_list?.map((customer) => {
              return Object.assign({}, customer, {
                customer_enter_center_time: null,
                customer_leave_center_time: null,
                customer_pickup_time: null,
                customer_dropoff_time: null,
                customer_estimated_pickup_time: null,
                customer_estimated_dropoff_time: null,
                customer_route_status: null
              })
            })
          });
          dispatch(createRoute({ data }));
        }
      }
      setTimeout(() => {
        dispatch(fetchAllRoutes());
        setShowCopyDateLoading(false);
      }, 2000);
    });
  }

  const cleanAllRoutesStatus = () => {
    const updatePromises = allRoutes.map(route => {
      let cleanRoute = Object.assign({}, route, { status: [ROUTE_STATUS.NOT_STARTED] });
      let newCustomers = [];
      for (let i=0; i< cleanRoute.route_customer_list.length; i++) {
        const newCustomerListObject = {
          ...cleanRoute.route_customer_list[i],
          customer_enter_center_time: null,
          customer_leave_center_time: null,
          customer_pickup_time: null,
          customer_dropoff_time: null,
          customer_estimated_pickup_time: null,
          customer_estimated_dropoff_time: null,
          customer_route_status: cleanRoute.route_customer_list[i].customer_route_status === PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT ? PERSONAL_ROUTE_STATUS.SCHEDULED_ABSENT : PERSONAL_ROUTE_STATUS.NO_STATUS
        }
        newCustomers.push(newCustomerListObject);
      }
      cleanRoute = Object.assign({}, cleanRoute, {route_customer_list: newCustomers});
      return TransRoutesService.updateRoute(route.id, cleanRoute);
    });
    Promise.all(updatePromises)
      .then(() => {
        dispatch(fetchAllRoutes());
      })
      .catch(err => {
        console.error('Error cleaning route statuses:', err);
      });
  }

  const handleCleanAllRoutesStatus = () => {
    if (window.confirm('Are you sure you want to do this? This cannot be undone.')) {
      cleanAllRoutesStatus();
    }
  }
  const syncCustomersInfo = () => {
    setShowSyncCustomersLoading(true);
    CustomerService.getAllCustomers().then(data => {
      const customers = data.data;
      const customersMap = new Map();
      for (const customer of customers) {
        customersMap.set(customer.id, {
          customer_name: `${customer.name} ${customer.name_cn?.length > 0 ? `(${customer.name_cn})` : ``}`,
          customer_type: customer.type,
          customer_pickup_status: customer.pickup_status,
          customer_note: customer.note,
          customer_special_needs: customer.special_needs,
          customer_phone: customer.phone || customer.mobile_phone || customer.home_phone,
          customer_table_id: customer.table_id,
          customer_language: customer.language
        })
      };
      // Batch all route updates, then refetch once after all complete
      const updatePromises = allRoutes.map(route => {
        const customerList = route.route_customer_list;
        const newCustomerList = customerList.map((customerItem) => Object.assign({}, customerItem, customersMap.get(customerItem.customer_id)));
        const newRouteObject = Object.assign({}, route, {route_customer_list: newCustomerList});
        return TransRoutesService.updateRoute(route.id, newRouteObject);
      });
      Promise.all(updatePromises)
        .then(() => {
          dispatch(fetchAllRoutes());
        })
        .catch(err => {
          console.error('Error syncing customer info:', err);
        })
        .finally(() => {
          setShowSyncCustomersLoading(false);
        });
    })
  }

  const cleanFilterAndClose = () => {
    setSelectedDriver(null);
    // setDateSelected(new Date())
    setShowFilterDropdown(false);
    setShowDateDropdown(false);
    setCustomerTableId('');
    setStatusFilter('');
    setCustomerNameFilter('');
    setCustomerTypeFilter('');
    setKeyword('');
    setRouteTypeFilter('');
    setShowFilterReportDropdown(false);
  }

  const cleanDate = () => {
    setDateSelected(new Date());
    setShowDateDropdown(false);
  }

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

  const getSortingImg = (key) => {
    return sorting.key === key ? (sorting.order === 'asc' ? 'up_arrow' : 'down_arrow') : 'default';
  }

  const sortTableWithField = (key) => {
    let newSorting = {
      key,
      order: 'asc',
    }
    
    if (sorting.key === key && sorting.order === 'asc') {
      newSorting = {...newSorting, order: 'desc'};
    }
    setSorting(newSorting);
  }

  const pickOriginDateSelected = (v) => {
    setOriginDateSelected(v);
    setDateSelected(v);
  }

  const columns = [
    {
      key: 'name',
      label: 'Route Name'
    },
    {
      key: 'driver',
      label: 'Driver'
    },
    {
      key: 'end_time',
      label: 'Route End Time'
    },
    {
      key: 'type',
      label: 'Route Type'
    },
  ];

  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">Driver</div>
              <select value={selectedDriver} onChange={e => setSelectedDriver(e.target.value)}>
                <option value={null}></option>
                {driverList.map((driver) => <option value={driver?.id}>{driver?.name}</option>)}
              </select>
            </div>
          </div>
          <div className="list row">
            <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 customReportFilterMenu = 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">Participate Status</div>
              <select
                value={statusFilter}
                onChange={(e) => setStatusFilter(e.target.value)}
              >
                {
                  [['', {text: ''}], ...Object.entries(PERSONAL_ROUTE_STATUS_TEXT)].map(([key, {text}]) => (
                    <option key={key} value={key}>{text}</option>
                  ))
                }
              </select>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Participant Type</div>
              <select
                value={customerTypeFilter}
                onChange={(e) => setCustomerTypeFilter(e.target.value)}
              >
                {
                  [['', ''], ...Object.entries(CUSTOMER_TYPE_TEXT)].map(([key, text]) => (
                    <option key={key} value={key}>{text}</option>
                  ))
                }
              </select>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Routes Type</div>
              <select
                value={routeTypeFilter}
                onChange={(e) => setRouteTypeFilter(e.target.value)}
              >
                <option value=""></option>
                <option value="inbound">inbound</option>
                <option value="outbound">outbound</option>
              </select>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Participant Name</div>
              <input type="text" value={customerNameFilter} onChange={(e) => setCustomerNameFilter(e.target.value)} />
            </div>
            <div className="me-4">
              <div className="field-label">Table Id</div>
              <input type="text" value={customerTableId} onChange={(e) => setCustomerTableId(e.target.value)} />
            </div>
          </div>
          <div className="list row">
            <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 customMenuDate = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      const handleDateChange = (v) => {
        setDateSelected(v);
        setShowDateDropdown(false);
      };
      
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Select Date to View Report</div>
              <DatePicker selected={dateSelected} onChange={handleDateChange} />
            </div>
          </div>
        </div>
      );
    },
  );

  const customMenuOriginDate = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Select Date to Start</div>
              <DatePicker selected={originDateSelected} onChange={(v) => pickOriginDateSelected(v)} />
            </div>
          </div>
          <div className="list row">
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => setShowOriginDateDropdown(false)}> Close </button>
            </div>
          </div>
        </div>
      );
    },
  );

  const customMenuImportFromDate = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Select Source Date (Past 14 Days)</div>
              <DatePicker
                selected={importSourceDate}
                onChange={(v) => setImportSourceDate(v)}
                minDate={moment().subtract(14, 'days').toDate()}
                maxDate={new Date()}
              />
            </div>
          </div>
          <div className="list row">
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => setShowImportDateDropdown(false)}> Cancel </button>
              <button className="btn btn-primary btn-sm float-right" onClick={importFromDate}> Import </button>
            </div>
          </div>
        </div>
      );
    },
  );

  const customMenuImportFromTemplate = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Select Saved Template</div>
              <select
                className="form-select"
                value={importTemplateId}
                onChange={(e) => setImportTemplateId(e.target.value)}
              >
                <option value="">Choose a template</option>
                {templates.map((template) => (
                  <option key={template.id} value={template.id}>
                    {template.name} - {template.template_date}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <div className="list row">
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => setShowImportTemplateDropdown(false)}> Cancel </button>
              <button className="btn btn-primary btn-sm float-right" onClick={importFromTemplate}> Copy </button>
            </div>
          </div>
        </div>
      );
    },
  );

  const customMenuTargetDate = React.forwardRef(
    ({ children, style, className, 'aria-labelledby': labeledBy }, ref) => {
      return (
        <div
          ref={ref}
          style={style}
          className={className}
          aria-labelledby={labeledBy}
        >
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Select Date to Start</div>
              <DatePicker selected={targetedDateSelected} onChange={(v) => setTargetedDateSelected(v)} />
            </div>
          </div>
          <div className="list row">
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => {setTargetedDateSelected(undefined); setShowTargetDateDropdown(false)}}> Cancel </button>
              <button className="btn btn-primary btn-sm float-right" onClick={() => {copyDateRoutesOver(true); setShowTargetDateDropdown(false)}}> Start to Copy </button>
            </div>
          </div>
        </div>
      );
    },
  );

  

  // Save template modal handlers
  const openSaveTemplateModal = () => {
    setShowSaveTemplateModal(true);
    setTemplateName('');
  };

  const closeSaveTemplateModal = () => {
    setShowSaveTemplateModal(false);
    setTemplateName('');
  };

  const saveRoutesAsTemplate = () => {
    if (!templateName || templateName.trim() === '') {
      alert('Please enter a template name');
      return;
    }

    setSavingTemplate(true);

    // Get the current date string in MM/DD/YYYY format
    const templateDate = getDateString(dateSelected);

    // Get current user from localStorage
    const currentUser = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user'))?.name : '';

    // Clean the routes data - remove all date fields and status
    const cleanedRoutes = routesForShowing.map(route => {
      // Clean customer list - set all date fields to null and reset dynamic fields to undefined
      const cleanedCustomerList = route.route_customer_list?.map(customer => ({
        ...customer,
        customer_enter_center_time: null,
        customer_leave_center_time: null,
        customer_pickup_time: null,
        customer_dropoff_time: null,
        customer_route_status: null,
        // customer_estimated_pickup_time: undefined,
        // customer_estimated_dropoff_time: undefined,
        // customer_pickup_status: undefined,
        // customer_route_status: undefined,
        // customer_transfer_to_route: undefined,
        // customer_address_override: undefined
      })) || [];

      // Return cleaned route
      return {
        name: route.name,
        schedule_date: route.schedule_date,
        vehicle: route.vehicle,
        status: [], // Empty array
        driver: route.driver,
        type: route.type,
        start_mileage: route.start_mileage,
        end_mileage: route.end_mileage,
        start_time: null,
        end_time: null,
        estimated_start_time: null,
        route_customer_list: cleanedCustomerList,
        checklist_result: route.checklist_result || []
      };
    });

    // Create the template payload
    const templatePayload = {
      name: templateName,
      template_date: templateDate,
      routes: cleanedRoutes,
      create_by: currentUser
    };

    // Call the service to create the template
    DailyRoutesTemplateService.createNewDailyRoutesTemplate(templatePayload)
      .then(() => {
        setSavingTemplate(false);
        closeSaveTemplateModal();
        setSuccessMessage(`Template "${templateName}" saved successfully!`);
        setTimeout(() => setSuccessMessage(undefined), 5000);
        // Refresh templates list
        DailyRoutesTemplateService.getAll().then((response) => {
          setTemplates(response.data || []);
        });
      })
      .catch(err => {
        setSavingTemplate(false);
        setErrorMessage(err.message || 'Failed to save template');
        setTimeout(() => setErrorMessage(undefined), 5000);
      });
  };

  // Apply template handler
  const applyTemplate = () => {
    if (!selectedTemplateId) {
      alert('Please select a template');
      return;
    }

    setApplyingTemplate(true);

    // Find the selected template
    const selectedTemplate = templates.find(t => t.id === selectedTemplateId);
    if (!selectedTemplate) {
      alert('Template not found');
      setApplyingTemplate(false);
      return;
    }

    // Get the target date in MM/DD/YYYY format
    const targetDate = getDateString(dateSelected);

    // Create promises for all route creations
    const createPromises = selectedTemplate.routes.map(route => {
      const routeData = {
        ...route,
        schedule_date: targetDate,
        route_customer_list: (route.route_customer_list || []).map((customer) => ({
          ...customer,
          customer_route_status: null
        }))
      };
      return TransRoutesService.createNewRoute(routeData);
    });

    // Execute all route creations
    Promise.all(createPromises)
      .then(() => {
        setApplyingTemplate(false);
        setSelectedTemplateId('');
        setSuccessMessage(`Template "${selectedTemplate.name}" applied successfully to ${targetDate}!`);
        setTimeout(() => setSuccessMessage(undefined), 5000);
        
        // Refresh the routes based on current date selection
        const selectedDateString = getDateString(dateSelected);
        if (selectedDateString === getDateString(new Date())) {
          dispatch(fetchAllRoutes());
        } else {
          if (dateSelected > new Date()) {
            dispatch(fetchAllTomorrowRoutes({dateText: moment(dateSelected).format('MM/DD/YYYY')}));
          } else {
            dispatch(fetchAllHistoryRoutes({dateText: getDateString(dateSelected)}));
          }
        }
      })
      .catch(err => {
        setApplyingTemplate(false);
        setErrorMessage(err.message || 'Failed to apply template');
        setTimeout(() => setErrorMessage(undefined), 5000);
      });
  };

  useEffect(() => {
    return () => {
      if (scheduleImportProgressTimerRef.current) {
        clearInterval(scheduleImportProgressTimerRef.current);
      }
    };
  }, []);


  return (
    <>
      {pageLoading && <div className="spinner-overlay">
        <Spinner animation="border" role="status">
          <span className="visually-hidden">Loading...</span>
        </Spinner>
      </div>}
      {isScheduleImporting && <div className="spinner-overlay" style={{ flexDirection: 'column', gap: '12px', zIndex: 1060 }}>
        <div style={{ width: '360px', maxWidth: '80vw', textAlign: 'center' }}>
          <div style={{ marginBottom: '8px', color: '#333' }}>{scheduleImportLabel || 'Importing schedule...'}</div>
          <ProgressBar now={scheduleImportProgress} animated label={`${Math.round(scheduleImportProgress)}%`} />
        </div>
      </div>}
       <div className="list row mb-4">
        <Breadcrumb>
          <Breadcrumb.Item href="/trans-routes/dashboard">Transportation</Breadcrumb.Item>
          <Breadcrumb.Item active>
            Transportation Routes
          </Breadcrumb.Item>
        </Breadcrumb>
        <div className="col-md-12 text-primary">
           <h4>
             All Routes - {moment(dateSelected).format('MM/DD/YYYY (dddd)')}
           </h4> 
        </div>
      </div>
      <div className="app-main-content-list-container">
				<div className="app-main-content-list-func-container">
					<Tabs defaultActiveKey="allRoutesOverview" id="routes-tab" onSelect={k => changeTab(k)}>
						<Tab eventKey="allRoutesOverview" title="All Routes Overview">
              {(!dateSelected || getDateString(dateSelected) === getDateString(new Date())) && <div className="app-main-content-fields-section with-function">
                <button className="btn btn-primary me-2" onClick={() => directToSchedule()}><CalendarCheck size={16} className="me-2"></CalendarCheck> Schedule Tomorrow's Routes</button>
                {/* <button className="btn btn-primary me-2" onClick={() => syncCustomersInfo()}><Clock size={16} className="me-2"></Clock> {showSyncCustomersLoading? <Spinner size={12}></Spinner> : `Sync Customers Data`}</button> */}
                <button className="btn btn-primary me-2" onClick={()=> handleCleanAllRoutesStatus()}><Eraser size={16} className="me-2"></Eraser > Clean Route Status</button>
                {/* <button className="btn btn-primary me-2" onClick={() => goToHistoryPage()}><ClockHistory size={16} className="me-2"></ClockHistory> View History</button> */}
                <button className="btn btn-primary me-2" onClick={() => copyYesterdayRoutes()}><Copy size={16} className="me-2"></Copy>{showCopyDateLoading? <Spinner size={12}></Spinner> : `Copy Yesterday Routes`}</button>
                <button className="btn btn-primary" onClick={() => generateRouteReport()}><Download size={16} className="me-2"></Download>Export Route Report</button>
              </div>}
              {(dateSelected && dateSelected > new Date()) && <div className="app-main-content-fields-section with-function">
                {/* <button type="button" className="btn btn-primary btn-sm me-2" onClick={()=> validateSchedule()}><Check  size={16} className="me-2"></Check> Validate and Finish Planning</button> */}
              </div>}
              { (dateSelected <= new Date() || !dateSelected) && <div className="list row">
                {
                  showCopyDateTargetLoading ? <><Spinner></Spinner></> : <>
                    <div className="col-md-12 mb-4">
                      {(routesInboundForShowing && routesInboundForShowing.length > 0) || (routesOutboundForShowing && routesOutboundForShowing.length > 0) ? (
                        <div style={{display: 'flex', alignItems: 'center', gap: '10px'}}>
                          {/* <button className="btn btn-secondary btn-sm" onClick={() => navigate('/trans-routes/daily-templates/list')}>
                            View and Update Daily Route Templates
                          </button> */}
                        </div>
                      ) : (
                        <div style={{display: 'flex', alignItems: 'center', gap: '10px'}}>
                          <select 
                            className="form-select" 
                            style={{width: 'auto', display: 'inline-block'}}
                            value={selectedTemplateId}
                            onChange={(e) => setSelectedTemplateId(e.target.value)}
                            disabled={applyingTemplate}
                          >
                            <option value="">Choose a daily template to apply to this day</option>
                            {templates.map(template => (
                              <option key={template.id} value={template.id}>
                                {template.name} - {template.template_date}
                              </option>
                            ))}
                          </select>
                          <button 
                            className="btn btn-primary btn-sm" 
                            onClick={applyTemplate}
                            disabled={!selectedTemplateId || applyingTemplate}
                          >
                            {applyingTemplate ? <><Spinner size="sm" className="me-1" />Applying...</> : 'Submit'}
                          </button>
                          {/* <button className="btn btn-secondary btn-sm" onClick={() => navigate('/trans-routes/daily-templates/list')}>
                            View and Update Daily Route Templates
                          </button> */}
                        </div>
                      )}
                    </div>
                    <div className="col-md-12 mb-4">
                      <RoutesSection transRoutes={routesInboundForShowing} drivers={drivers} vehicles={vehicles} sectionName="Inbound Routes"/>
                    </div>
                    <div className="col-md-12 mb-4">
                      <RoutesSection transRoutes={routesOutboundForShowing} drivers={drivers} vehicles={vehicles} sectionName="Outbound Routes"/>
                    </div>
                  </>
                }
                
              </div>}
              {
                dateSelected > new Date() && <>
                  {errorMessage && <div className="alert alert-danger alert-dismissible fade show" role="alert">
                  {errorMessage}
                    <button onClick={() => setErrorMessage(undefined)} type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                  </div>}
                  {successMessage && <div className="alert alert-success alert-dismissible fade show" role="alert">
                    {successMessage}
                    <button onClick={() => setSuccessMessage(undefined)} type="button" className="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                  </div>}
                  <div className="list row">
                    {isLoading && <div className="col-md-12"><Spinner animation="border" role="status">
                      <span className="visually-hidden">Loading...</span>
                    </Spinner></div>}
                    {!isLoading && <>
                      <div className="col-md-12 mb-4">
                        {(tmrInboundRoutes && tmrInboundRoutes.length > 0) || (tmrOutboundRoutes && tmrOutboundRoutes.length > 0) ? (
                          <div style={{display: 'flex', alignItems: 'center', gap: '10px'}}>
                            {/* <button className="btn btn-secondary btn-sm" onClick={() => navigate('/trans-routes/daily-templates/list')}>
                              View and Update Daily Route Templates
                            </button> */}
                          </div>
                        ) : (
                          <div style={{display: 'flex', alignItems: 'center', gap: '10px'}}>
                            <select 
                              className="form-select" 
                              style={{width: 'auto', display: 'inline-block'}}
                              value={selectedTemplateId}
                              onChange={(e) => setSelectedTemplateId(e.target.value)}
                              disabled={applyingTemplate}
                            >
                              <option value="">Choose a daily template to apply to this day</option>
                              {templates.map(template => (
                                <option key={template.id} value={template.id}>
                                  {template.name} - {template.template_date}
                                </option>
                              ))}
                            </select>
                            <button 
                              className="btn btn-primary btn-sm" 
                              onClick={applyTemplate}
                              disabled={!selectedTemplateId || applyingTemplate}
                            >
                              {applyingTemplate ? <><Spinner size="sm" className="me-1" />Applying...</> : 'Submit'}
                            </button>
                            {/* <button className="btn btn-secondary btn-sm" onClick={() => navigate('/trans-routes/daily-templates/list')}>
                              View and Update Daily Route Templates
                            </button> */}
                          </div>
                        )}
                      </div>
                      <div className="col-md-12 mb-4">
                        <RoutesSection transRoutes={tmrInboundRoutes} copyList={tmrOutboundRoutes} addText="Add New Route" copyText="Import Outbound Routes" canAddNew={true} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="inbound" sectionName="Inbound Routes" showCheckedInText={false} showRouteHeaderButtons={true} clearAllRoutesAction={() => triggerShowDeleteModal('inbound')}/>
                      </div>
                      <hr />
                      <div className="col-md-12 mb-4">
                        <RoutesSection transRoutes={tmrOutboundRoutes} copyList={tmrInboundRoutes} addText="Add New Route" copyText="Import Inbound Routes" canAddNew={true} drivers={drivers} vehicles={vehicles} redirect={goToCreateRoute} routeType="outbound" sectionName="Outbound Routes" showRouteHeaderButtons={true} clearAllRoutesAction={() => triggerShowDeleteModal('outbound')}/>
                      </div>
                      <hr />
                    </>}
                  </div>
                </>
              }
						</Tab>
						{!isFutureScheduleSelected && <Tab eventKey="allRoutesSignature" title="All Routes Signature">
            <input className="me-2 mb-2 with-search-icon" type="text" placeholder="Search" value={keyword}  onChange={(e) => setKeyword(e.currentTarget.value)} />
              <table className="personnel-info-table me-4">
                <thead>
                  <tr>
						        <th className="th-index">No.</th>
                    {
                      columns.map((column, index) => <th className="sortable-header" key={index}>
                        {column.label}  <span className="float-right" onClick={() => sortTableWithField(column.key)}><img src={`/images/${getSortingImg(column.key)}.png`}></img></span>
                      </th>)
                    }
                    <th>Signature</th>
                  </tr>
                </thead>
                <tbody>
                  {
                    routesForSignature && routesForSignature.filter((route) => {
                      if (!selectedDriver) {
                        return route;
                      } else {
                        return route?.driver === selectedDriver;
                      }
                    }).filter((route) => route.name?.toLowerCase().includes(keyword?.toLowerCase()) || drivers.find((d) => d.id === route?.driver)?.name?.toLowerCase().includes(keyword?.toLowerCase()))?.map(({id, name, end_time, driver, type, signature}, index) => {
                      return (<tr key={index}>
                        <td className="td-index">{index + 1}</td>
                        <td>
                          <button
                            type="button"
                            className="btn btn-link p-0"
                            style={{ fontSize: 'inherit', verticalAlign: 'baseline' }}
                            onClick={() => goToRouteDetails(id)}
                          >
                            {name}
                          </button>
                        </td>
                        <td>{drivers.find((d) => d.id === driver)?.name}</td>
                        <td>{end_time? moment(end_time).format('HH:mm'): ''}</td>
                        <td>{type}</td>
                        <td>
                          {/* {images.find((img) => img.id === id)?.image && <img width="100px" src={`data:image/jpg;base64, ${images.find((img) => img.id === id)?.image}`}/>} */}
                          {signature && <img width="100px" src={`data:image/jpg;base64, ${signature}`}/>}
                        </td>
                      </tr>)
                    })
                  }
                </tbody>
              </table>
						</Tab>}
            {!isFutureScheduleSelected && <Tab eventKey="allRoutesStatus" title="All Routes Status">
              <div className="list row">
                <div className="col-md-12 mb-4">
                  <PersonnelSection transRoutes={routesForShowing} showCompletedInfo={false} 
                    showGroupInfo={false} allowForceEdit={AuthService.canAddOrEditRoutes()} 
                    showFilter={true} sectionName="Personnel Status (click on each user to edit)" 
                    vehicles={vehicles} keyword={keyword}
                    statusFilter={statusFilter}
                    customerTypeFilter={customerTypeFilter}
                    customerNameFilter={customerNameFilter}
                    customerTableId={customerTableId}
                    routeTypeFilter={routeTypeFilter}
                  />
                </div>
              </div>
						</Tab>}
					</Tabs>
					<div className="list-func-panel">
            {
              currentTab === 'allRoutesOverview' &&  <> {
                !showCopyDateTargetLoading && <>
                  <Dropdown
                    key={'signature-date'}
                    id="signature-date"
                    className="me-2"
                    show={showOriginDateDropdown}
                    disabled
                    onToggle={() => setShowOriginDateDropdown(!showOriginDateDropdown)}
                    autoClose={false}
                  > 
                    <Dropdown.Toggle variant="outline-secondary">
                      <CalendarWeek size={16} className="me-2"></CalendarWeek>View By Date
                    </Dropdown.Toggle>
                    <Dropdown.Menu as={customMenuOriginDate}/> 
                  </Dropdown>
                  {isFutureScheduleSelected && <>
                    <Dropdown
                      key={'import-from-date'}
                      id="import-from-date"
                      className="me-2"
                      show={showImportDateDropdown}
                      onToggle={() => setShowImportDateDropdown(!showImportDateDropdown)}
                      autoClose={false}
                    >
                      <Dropdown.Toggle variant="outline-secondary" disabled={isScheduleImporting}>
                        <Copy size={16} className="me-2"></Copy>Import From Date
                      </Dropdown.Toggle>
                      <Dropdown.Menu as={customMenuImportFromDate}/>
                    </Dropdown>
                    <Dropdown
                      key={'import-from-template'}
                      id="import-from-template"
                      className="me-2"
                      show={showImportTemplateDropdown}
                      onToggle={() => setShowImportTemplateDropdown(!showImportTemplateDropdown)}
                      autoClose={false}
                    >
                      <Dropdown.Toggle variant="outline-secondary" disabled={isScheduleImporting}>
                        <Copy size={16} className="me-2"></Copy>Import From Template
                      </Dropdown.Toggle>
                      <Dropdown.Menu as={customMenuImportFromTemplate}/>
                    </Dropdown>
                    <button className="btn btn-outline-secondary me-2" onClick={() => createVehicle()} disabled={isScheduleImporting}>
                      <Plus size={16} className="me-2"></Plus>Add New Vehicle
                    </button>
                    <button className="btn btn-outline-secondary me-2" onClick={runCheckRoutes} disabled={isScheduleImporting}>
                      <Check size={16} className="me-2"></Check>Check Routes
                    </button>
                  </>}
                  </>
                }
                {!isFutureScheduleSelected && <button className="btn btn-primary me-2" onClick={() => goToCreateRoute()}><Plus size={16}></Plus>Add New Route</button>}
              </>
            }

            { currentTab === 'allRoutesSignature' && <>
             
              <Dropdown
                key={'signature-date'}
                id="signature-date"
                className="me-2"
                show={showDateDropdown}
                onToggle={() => setShowDateDropdown(!showDateDropdown)}
                autoClose={false}
              > 
                <Dropdown.Toggle variant="primary">
                  <CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
                </Dropdown.Toggle>
                <Dropdown.Menu as={customMenuDate}/> 
              </Dropdown>
              <Dropdown
                key={'filter-signature'}
                id="filter-signature"
                className="me-2"
                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>
            </> }

            { currentTab === 'allRoutesStatus' && <>
              {/* <input className="me-2 with-search-icon" type="text" placeholder="Search" value={keyword}  onChange={(e) => setKeyword(e.currentTarget.value)} /> */}
              <Dropdown
                key={'status-date'}
                id="status-date"
                className="me-2"
                show={showDateDropdown}
                onToggle={() => setShowDateDropdown(!showDateDropdown)}
                autoClose="outside"
              > 
                <Dropdown.Toggle variant="primary">
                  <CalendarWeek size={16} className="me-2"></CalendarWeek>Select Date to View Report
                </Dropdown.Toggle>
                <Dropdown.Menu as={customMenuDate}/> 
              </Dropdown>
              <Dropdown
                key={'filter-report'}
                id="filter-report"
                className="me-2"
                show={showFilterReportDropdown}
                onToggle={() => setShowFilterReportDropdown(!showFilterReportDropdown)}
                autoClose="outside"
              > 
                <Dropdown.Toggle variant="primary">
                  <Filter size={16} className="me-2"></Filter>Filter
                </Dropdown.Toggle>
                <Dropdown.Menu as={customReportFilterMenu}/> 
              </Dropdown>
              <button className="btn btn-primary"><Download size={16} className="me-2"></Download>Export</button>
            </> }
            
					</div>
          <Modal show={showDeleteModal} onHide={() => closeDeleteModal()}>
            <Modal.Header closeButton>
              <Modal.Title>Delete Schedule</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              <div>
                {deleteRouteType === 'inbound'
                  ? 'Are you sure you want to delete all inbound routes for this date?'
                  : deleteRouteType === 'outbound'
                    ? 'Are you sure you want to delete all outbound routes for this date?'
                    : 'Are you sure you want to delete all the schedule?'}
              </div>
            </Modal.Body>
            <Modal.Footer>
              <Button variant="secondary" onClick={() => closeDeleteModal()}>
                No
              </Button>
              <Button variant="primary" onClick={() => cleanupSchedule()}>
                Yes
              </Button>
            </Modal.Footer>
          </Modal>

          <Modal show={showSaveTemplateModal} onHide={closeSaveTemplateModal}>
            <Modal.Header closeButton>
              <Modal.Title>Save Routes as Template</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              <div className="mb-3">
                <label className="form-label">Template Name</label>
                <input 
                  type="text" 
                  className="form-control" 
                  placeholder="Enter template name"
                  value={templateName}
                  onChange={(e) => setTemplateName(e.target.value)}
                  disabled={savingTemplate}
                />
              </div>
              <div className="text-muted">
                <small>This will save all routes from {getDateString(dateSelected)} as a reusable template.</small>
              </div>
            </Modal.Body>
            <Modal.Footer>
              <Button variant="secondary" onClick={closeSaveTemplateModal} disabled={savingTemplate}>
                Cancel
              </Button>
              <Button variant="primary" onClick={saveRoutesAsTemplate} disabled={savingTemplate}>
                {savingTemplate ? <><Spinner size="sm" className="me-2" />Saving...</> : 'Submit'}
              </Button>
            </Modal.Footer>
          </Modal>
          <Modal show={showCheckRoutesModal} onHide={() => setShowCheckRoutesModal(false)}>
            <Modal.Header closeButton>
              <Modal.Title>Check Routes Result</Modal.Title>
            </Modal.Header>
            <Modal.Body>
              {(checkRoutesResult.inbound.length === 0 && checkRoutesResult.outbound.length === 0 && checkRoutesResult.attendance.length === 0 && checkRoutesResult.addressMismatch.length === 0 && checkRoutesResult.customerTypeMismatch.length === 0 && checkRoutesResult.customerSpecialNeedsMismatch.length === 0 && checkRoutesResult.dischargedOnRoute.length === 0) ? (
                <div className="text-success d-flex align-items-center">
                  <Check size={18} className="me-2"></Check>
                  <span>No issue found.</span>
                </div>
              ) : (
                <>
                  {checkRoutesResult.inbound.length > 0 && (
                    <div className="mb-3">
                      <div className="fw-bold mb-2">Inbound Issues</div>
                      {checkRoutesResult.inbound.map((issue, idx) => (
                        <div key={`inbound-issue-${idx}`} className="mb-2">
                          {issue.customerName} appears on multiple routes: {formatRouteAddressList(issue.routes)}
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.outbound.length > 0 && (
                    <div>
                      <div className="fw-bold mb-2">Outbound Issues</div>
                      {checkRoutesResult.outbound.map((issue, idx) => (
                        <div key={`outbound-issue-${idx}`} className="mb-2">
                          {issue.customerName} appears on multiple routes: {formatRouteAddressList(issue.routes)}
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.attendance.length > 0 && (
                    <div className="mt-3">
                      <div className="fw-bold mb-2">Attendance Note Issues</div>
                      {checkRoutesResult.attendance.map((issue, idx) => (
                        <div key={`attendance-issue-${idx}`} className="mb-2">
                          {issue.customerName} is scheduled absent on {issue.noteDate} but still appears on Route {joinRouteNames(issue.routeNames)}.
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.addressMismatch.length > 0 && (
                    <div className="mt-3">
                      <div className="fw-bold mb-2">Address Mismatch Issues</div>
                      {checkRoutesResult.addressMismatch.map((issue, idx) => (
                        <div key={`address-mismatch-issue-${idx}`} className="mb-2">
                          Customer {issue.customerName}&apos;s address: {issue.routeAddress || 'N/A'} is not matching his existing addresses stored in system, on route {joinRouteNames(issue.routeNames)}.
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.customerTypeMismatch.length > 0 && (
                    <div className="mt-3">
                      <div className="fw-bold mb-2">Member Type Mismatch Issues</div>
                      {checkRoutesResult.customerTypeMismatch.map((issue, idx) => (
                        <div key={`customer-type-mismatch-issue-${idx}`} className="mb-2 d-flex align-items-center justify-content-between" style={{ gap: '12px' }}>
                          <div>
                            Customer {issue.customerName}&apos;s member type is mismatched on route {joinRouteNames(issue.mismatchedRoutes.map((route) => route.routeName))}. Latest type in system is {getCustomerTypeLabel(issue.dbType)}.
                          </div>
                          <Button
                            variant="outline-primary"
                            size="sm"
                            disabled={!!customerTypeFixing[issue.customerId]}
                            onClick={() => syncCustomerTypeForMismatch(issue)}
                          >
                            {customerTypeFixing[issue.customerId] ? 'Fixing...' : 'Fix'}
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.customerSpecialNeedsMismatch.length > 0 && (
                    <div className="mt-3">
                      <div className="fw-bold mb-2">Note to Driver Mismatch Issues</div>
                      {checkRoutesResult.customerSpecialNeedsMismatch.map((issue, idx) => (
                        <div key={`customer-special-needs-mismatch-issue-${idx}`} className="mb-2 d-flex align-items-center justify-content-between" style={{ gap: '12px' }}>
                          <div>
                            Customer {issue.customerName}&apos;s note to driver is mismatched on route {joinRouteNames(issue.mismatchedRoutes.map((route) => route.routeName))}. Latest note in system is {issue.dbNoteToDriver || 'empty'}.
                          </div>
                          <Button
                            variant="outline-primary"
                            size="sm"
                            disabled={!!customerSpecialNeedsFixing[issue.customerId]}
                            onClick={() => syncCustomerSpecialNeedsForMismatch(issue)}
                          >
                            {customerSpecialNeedsFixing[issue.customerId] ? 'Fixing...' : 'Fix'}
                          </Button>
                        </div>
                      ))}
                    </div>
                  )}
                  {checkRoutesResult.dischargedOnRoute.length > 0 && (
                    <div className="mt-3">
                      <div className="fw-bold mb-2">Discharged Customer Issues</div>
                      {checkRoutesResult.dischargedOnRoute.map((issue, idx) => (
                        <div key={`discharged-route-issue-${idx}`} className="mb-2">
                          Customer {issue.customerName} has been discharged and he is still on route {joinRouteNames(issue.routeNames)}.
                        </div>
                      ))}
                    </div>
                  )}
                </>
              )}
            </Modal.Body>
            <Modal.Footer>
              <Button variant="primary" onClick={() => setShowCheckRoutesModal(false)}>
                Close
              </Button>
            </Modal.Footer>
          </Modal>
				</div>
      </div>


      {/* <div className="list row mb-4">
        <div className=" text-primary mb-2">
          Today's Date: { new Date().toLocaleDateString() }
        </div>
        <div className="text-primary mb-2">
          <button type="button" className="btn btn-primary btn-sm me-1 mb-2" onClick={()=> syncCustomersInfo()}>{showSyncCustomersLoading? 'Loading...' : `Sync Customers Data`}</button>
          <button type="button" className="btn btn-primary btn-sm me-1 mb-2" onClick={()=> generateRouteReport()}>Generate Route Report</button>
          {AuthService.canAddOrEditRoutes() &&
            <button type="button" className="btn btn-primary btn-sm me-1 mb-2" onClick={() => directToSchedule()}>Plan Tomorrow's Route Schedule</button>
          }
          <button type="button" className="btn btn-primary btn-sm me-1 mb-2" onClick={()=> createNewRoute()}>Create New Route</button>
          <button type="button" className="btn btn-primary btn-sm me-1 mb-2" onClick={()=> copyYesterdayRoutes()}>{showCopyDateLoading? 'Loading...' : `Copy Yesterday Routes`}</button>
          <button type="button" className="btn btn-secondary btn-sm me-1 mb-2" onClick={()=> goToHistoryPage()}>View History</button>
          <button type="button" className="btn btn-danger btn-sm me-1 mb-2" onClick={()=> cleanAllRoutesStatus()}>Clean All Routes Status</button>
          <button type="button" className="btn btn-secondary btn-sm me-1 mb-2" onClick={()=> goToSignature()}>View Routes Signature</button>
        </div>
      </div> */}
    </>
    
  );
};

export default RoutesDashboard;