import React, { useEffect, useState, Fragment, useRef } from "react";
import { useNavigate } from 'react-router-dom';
import { CustomerService, TransRoutesService, AuthService, ReportService } from "../../services";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { CalendarWeek, ClockHistory, Copy, Download, Eraser, Plus, Clock, Send, Filter, CalendarCheck, Check } from "react-bootstrap-icons";
import { Breadcrumb, Tabs, Tab, Dropdown, Spinner, Modal, Button } from "react-bootstrap";
import DateTimePicker from "react-datetime-picker";
import { CSVLink } from "react-csv";
import { CUSTOMER_TYPE, PERSONAL_ROUTE_STATUS, PERSONAL_ROUTE_STATUS_TEXT, REPORT_TYPE } from "../../shared";
import { isEmpty, isEqual, xorWith } from 'lodash';

const CustomerReport = () => {
  const navigate = useNavigate();
	const [customers, setCustomers] = useState([]);
	const [datePicked, setDatePicked] = useState(new Date());
	const [routes, setRoutes] = useState([]);
	const [sampleMap, setSampleMap] = useState(new Map());
	const [routeCustomerMap, setRouteCustomerMap] = useState(new Map());
	const [customerCheckInTime, setCustomerCheckInTime] = useState(undefined);
  const [customerCheckOutTime, setCustomerCheckOutTime] = useState(undefined);
	const [customerPickupTime, setCustomerPickupTime] = useState(undefined);
  const [customerDropoffTime, setCustomerDropoffTime] = useState(undefined);
	const [customerRouteReportStatus, setCustomerRouteReportStatus] = useState('');
	const [keyInEdit, setKeyInEdit] = useState('');
	const [statusFilter, setStatusFilter] = useState('');
	const [show, setShow] = useState(false);
	const [nameFilter, setNameFilter] = useState('');
	const [callerFilter, setCallerFilter] = useState('');
	const [attendFilter, setAttendFilter] = useState(false);
	const [existedReports, setExistedReports] = useState([]);
	const [enableSave, setEnableSave] = useState(false);
	const [showFilterReportDropdown, setShowFilterReportDropdown]  = useState(false);
	const [showDateDropdown, setShowDateDropdown] = useState(false);
	const [csvData, setCsvData] = useState([]);
	const csvInstance = useRef(null);

	const openForceEditModal = (key, customer_enter_center_time, customer_leave_center_time, customer_pickup_time, customer_dropoff_time, customer_route_report_status) => {
		if (AuthService.canAddOrEditAttendance()) {
			setShow(true);
			setKeyInEdit(key);
			setCustomerCheckInTime(customer_enter_center_time ? new Date(customer_enter_center_time) : undefined);
			setCustomerCheckOutTime(customer_leave_center_time ? new Date(customer_leave_center_time) : undefined);
			setCustomerPickupTime(customer_pickup_time ? new Date(customer_pickup_time) : undefined);
			setCustomerDropoffTime(customer_dropoff_time ? new Date(customer_dropoff_time) : undefined);
			setCustomerRouteReportStatus(customer_route_report_status);
				// || getReportCustomerStatus({customer_enter_center_time, customer_leave_center_time, customer_pickup_time, customer_dropoff_time}));
		}
  }

  const closeModal = () => {
    setCustomerCheckInTime(undefined);
    setCustomerCheckOutTime(undefined);
    setCustomerPickupTime(undefined);
		setCustomerDropoffTime(undefined);
		setKeyInEdit('');
    setShow(false);
  }

	const saveReportInfo = () => {
		const currentItem = routeCustomerMap.get(keyInEdit);
		if (customerCheckInTime) {
			currentItem.customer_enter_center_time = customerCheckInTime;
		}
		if (customerCheckOutTime) {
			currentItem.customer_leave_center_time = customerCheckOutTime;
		}
		if (customerPickupTime) {
			currentItem.customer_pickup_time = customerPickupTime;
		}
		if (customerDropoffTime) {
			currentItem.customer_dropoff_time = customerDropoffTime;
		}
		if (customerRouteReportStatus) {
			currentItem.customer_route_report_status = customerRouteReportStatus;
		}
		routeCustomerMap.set(keyInEdit, currentItem);
		setRouteCustomerMap(new Map(routeCustomerMap));
		setShow(false);
		setKeyInEdit('')
	}

	const deleteItem = () => {
		routeCustomerMap.delete(keyInEdit);
		setKeyInEdit('');
    setShow(false);
	};

	const getRoutes = () => {
		let customerMap = new Map();
		for (const customer of customers) {
			customerMap.set(customer.id, { customer_name: `${customer.name} (${customer.name_cn})`, customer_type: `${customer.type}`, customer_caller: `${customer.caller}`, customer_seating: `${customer.seating}`, customer_vehicle: `${customer.vehicle_no}`});
		}
		setSampleMap(new Map(customerMap));
		const date = new Date(datePicked);
		const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
		TransRoutesService.getAll(dateText).then(data => {
			setRoutes(data.data);
			setShowDateDropdown(false)
		})
		ReportService.getReportsByDateAndType(dateText, REPORT_TYPE.ADMIN_CUSTOMER_REPORT).then(data => {
			setExistedReports(data.data);
			setShowDateDropdown(false);
		})
	}

	const isNotFullTime = (d1, d2) => {
		return d1 && d2 && Math.abs(new Date(d1) - new Date(d2)) / 36e5 < 4;
	}

	const getTimeString = (t) => {
		return t && new Date(t).toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute: '2-digit'}) || '';
	}

	const diff_hours = (dt2, dt1) => {
		let diff =(dt2?.getTime() - dt1?.getTime()) / 1000;
		diff /= (60 * 60);
		return Math.floor(Math.abs(diff));
	}

	const generateReportData = () => {
		const date = new Date(datePicked);
		const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
		const content = [];
		ReportService.getReportsByDateAndType(dateText, REPORT_TYPE.ADMIN_CUSTOMER_REPORT).then(data => {
			const latestExistedReports = data.data;
			if (latestExistedReports && latestExistedReports.length > 0) {
				for (const report of latestExistedReports[0]?.data) {
					const currentData = routeCustomerMap.get(report.customer_id);
					routeCustomerMap.set(report.customer_id, {
						customer_name: currentData.customer_name,
						customer_type: currentData.customer_type,
						customer_caller: currentData.customer_caller,
						customer_route_report_status: currentData.customer_route_report_status || report.customer_route_report_status,
						customer_pickup_time: currentData.customer_pickup_time || report.customer_pickup_time, 
						customer_enter_center_time: currentData.customer_enter_center_time || report.customer_enter_center_time, 
						customer_leave_center_time: currentData.customer_leave_center_time || report.customer_leave_center_time, 
						customer_dropoff_time: currentData.customer_dropoff_time || report.customer_dropoff_time,
						customer_vehicle: currentData.customer_vehicle || report.customer_vehicle,
						customer_seating: currentData.customer_seating || report.customer_seating
					})
					
				}
			}
			const head = ['No.', 'Name', 'Customer Route Status', 'Pick-Up', 'Arrival', 'Departure', 'Drop-Off', 'Full Time Attendence?', 'Hours Stayed', 'Customer Type', 'Caller', 'Seating', 'Vehicle Number'];
			const chineseHead=['序号', '姓名', '客户路线状态', '接到时间', '抵达中心', '离开中心', '送达时间', '是否全勤', '出勤时间（小时)', '用户类别', '联系人', '座位', '车号'];
			const customersList = Array.from(routeCustomerMap.values()).filter(item => [CUSTOMER_TYPE.MEMBER, CUSTOMER_TYPE.SELF_PAY].includes(item.customer_type)).filter(
				(item) => item?.customer_name?.toLowerCase()?.includes(nameFilter?.toLowerCase())
				// && (
				// 	!attendFilter ||
				// 	attendFilter && (item.customer_enter_center_time || item.customer_leave_center_time)
				// )
			);
			for (let i=0; i<customersList.length; i++) {
				content.push([
					i+1,
					customersList[i].customer_name,
					customersList[i].customer_route_report_status,
					// || getReportCustomerStatus(customersList[i]),
					getTimeString(customersList[i].customer_pickup_time),
					getTimeString(customersList[i].customer_enter_center_time),
					getTimeString(customersList[i].customer_leave_center_time),
					getTimeString(customersList[i].customer_dropoff_time), 
					isNotFullTime(customersList[i].customer_enter_center_time, customersList[i].customer_leave_center_time)? 'No': '', 
					customersList[i].customer_leave_center_time && customersList[i].customer_enter_center_time && diff_hours(new Date(customersList[i].customer_leave_center_time), new Date(customersList[i].customer_enter_center_time) ),
					customersList[i].customer_type,
					customersList[i].customer_caller,
					customersList[i].customer_seating,
					customersList[i].customer_vehicle
				]);
			}
			setCsvData([head, chineseHead, ...content]);
		});
	}

	// const generateReportData = () => {
  //   const head = ['No.', 'Name', 'Customer Route Status', 'Pick-Up', 'Arrival', 'Departure', 'Drop-Off', 'Full Time Attendence?', 'Hours Stayed', 'Customer Type', 'Caller', 'Seating'];
  //   const chineseHead=['序号', '姓名', '客户路线状态', '接到时间', '抵达中心', '离开中心', '送达时间', '是否全勤', '出勤时间（小时)', '用户类别', '联系人', '座位'];
	// 	const customersList = Array.from(routeCustomerMap.values()).filter(item => item.customer_type === CUSTOMER_TYPE.MEMBER).filter(
	// 		(item) => item?.customer_name?.includes(nameFilter)
	// 		// && (
	// 		// 	!attendFilter ||
	// 		// 	attendFilter && (item.customer_enter_center_time || item.customer_leave_center_time)
	// 		// )
	// 	).sort((a,b) => a.customer_name > b.customer_name ? 1: -1);
	// 	const content = []
	// 	for (let i=0; i<customersList.length; i++) {
	// 		content.push([
	// 			i+1,
	// 			customersList[i].customer_name,
	// 			customersList[i].customer_route_report_status,
	// 			// || getReportCustomerStatus(customersList[i]),
	// 			getTimeString(customersList[i].customer_pickup_time),
	// 			getTimeString(customersList[i].customer_enter_center_time),
	// 			getTimeString(customersList[i].customer_leave_center_time),
	// 			getTimeString(customersList[i].customer_dropoff_time), 
	// 			isNotFullTime(customersList[i].customer_enter_center_time, customersList[i].customer_leave_center_time)? 'No': '', 
	// 			customersList[i].customer_leave_center_time && customersList[i].customer_enter_center_time && diff_hours(new Date(customersList[i].customer_leave_center_time), new Date(customersList[i].customer_enter_center_time) ),
	// 			customersList[i].customer_type,
	// 			customersList[i].customer_caller
	// 		]);
	// 	}
	// 	return [head, chineseHead, ...content];
  // }

	const getReportCustomerStatus = (customer) => {
		if (customer.customer_dropoff_time) {
			return PERSONAL_ROUTE_STATUS_TEXT.droppedOff.text;
		} else {
			if (customer.customer_leave_center_time) {
				return PERSONAL_ROUTE_STATUS_TEXT.leftCenter.text;
			} else {
				if (customer.customer_enter_center_time) {
					return PERSONAL_ROUTE_STATUS_TEXT.inCenter.text;
				} else {
					if (customer.customer_pickup_time) {
						return PERSONAL_ROUTE_STATUS_TEXT.picked.text;
					} else {
						return ''
					}
				}
			}
		}
	}

	const generateCustomerReport = () => {
		const date = new Date(datePicked);
		const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
		const content = [];
		ReportService.getReportsByDateAndType(dateText, REPORT_TYPE.ADMIN_CUSTOMER_REPORT).then(data => {
			const latestExistedReports = data.data;
			if (latestExistedReports && latestExistedReports.length > 0) {
				for (const report of latestExistedReports[0]?.data) {
					const currentData = routeCustomerMap.get(report.customer_id);
					routeCustomerMap.set(report.customer_id, {
						customer_name: currentData.customer_name,
						customer_type: currentData.customer_type,
						customer_caller: currentData.customer_caller,
						customer_route_report_status: currentData.customer_route_report_status || report.customer_route_report_status,
						customer_pickup_time: currentData.customer_pickup_time || report.customer_pickup_time, 
						customer_enter_center_time: currentData.customer_enter_center_time || report.customer_enter_center_time, 
						customer_leave_center_time: currentData.customer_leave_center_time || report.customer_leave_center_time, 
						customer_dropoff_time: currentData.customer_dropoff_time || report.customer_dropoff_time,
						customer_seating: currentData.customer_seating,
						customer_vehicle: currentData.customer_vehicle
					})
					
				}
			}
			setRouteCustomerMap(new Map(routeCustomerMap));
			const customersList = Array.from(routeCustomerMap.entries()).filter(([customer_id, item]) => [CUSTOMER_TYPE.MEMBER, CUSTOMER_TYPE.SELF_PAY].includes(item.customer_type))
				.filter(
					([customer_id, item]) => item?.customer_name?.toLowerCase()?.includes(nameFilter?.toLowerCase()));
				// // && (
				// 		!attendFilter ||
				// 		attendFilter && (item.customer_enter_center_time || item.customer_leave_center_time)
				// 	)
				for (let i=0; i<customersList.length; i++) {
					content.push({
						customer_id: customersList[i][0],
						customer_name: customersList[i][1].customer_name,
						customer_type: customersList[i][1].customer_type,
						customer_caller: customersList[i][1].customer_caller,
						customer_route_report_status: customersList[i][1].customer_route_report_status,
						// || getReportCustomerStatus(customersList[i][1]),
						customer_pickup_time: customersList[i][1].customer_pickup_time, 
						customer_enter_center_time: customersList[i][1].customer_enter_center_time, 
						customer_leave_center_time: customersList[i][1].customer_leave_center_time, 
						customer_dropoff_time: customersList[i][1].customer_dropoff_time, 
						full_time_attendence: isNotFullTime(customersList[i][1].customer_enter_center_time, customersList[i][1].customer_leave_center_time)? 'No': '', 
						hours_stayed: customersList[i][1].customer_leave_center_time && customersList[i][1].customer_enter_center_time && diff_hours(new Date(customersList[i][1].customer_leave_center_time), new Date(customersList[i][1].customer_enter_center_time) ),
						customer_seating: customersList[i][1].customer_seating,
						customer_vehicle: customersList[i][1].customer_vehicle
					}	);
				}
				if (existedReports && existedReports.length > 0) {
					ReportService.updateReport(existedReports[0]?.id, {
						date: dateText,
						type: REPORT_TYPE.ADMIN_CUSTOMER_REPORT,
						head: ['No.', 'Name', 'Customer Route Status', 'Pick-Up', 'Arrival', 'Departure', 'Drop-Off', 'Full Time Attendence?', 'Hours Stayed', 'Customer Type', 'Caller', 'Seating', 'Vehicle Number'],
						chinese_head: ['序号', '姓名', '客户路线状态', '接到时间', '抵达中心', '离开中心', '送达时间', '是否全勤', '出勤时间（小时)', '用户类别', '联系人', '座位', '车号'],
						data: content.sort((a,b) => a.customer_name > b.customer_name ? 1: -1)
					}).then(() => {
						window.alert('The report is saved to Database. To get a PDF version, please run your PYTHON EXE Script.')
					})
				} else {
					ReportService.createReport({
						date: dateText,
						type: REPORT_TYPE.ADMIN_CUSTOMER_REPORT,
						head: ['No.', 'Name', 'Customer Route Status', 'Pick-Up', 'Arrival', 'Departure', 'Drop-Off', 'Full Time Attendence?', 'Hours Stayed', 'Customer Type', 'Caller', 'Seating', 'Vehicle Number'],
						chinese_head: ['序号', '姓名', '客户路线状态', '接到时间', '抵达中心', '离开中心', '送达时间', '是否全勤', '出勤时间（小时)', '用户类别', '联系人', '座位', '车号'],
						data: content.sort((a,b) => a.customer_name > b.customer_name ? 1: -1)
					}).then(() => {
						window.alert('The report is saved to Database. To get a PDF version, please run your PYTHON EXE Script.')
					})
				}
		})
		
	}


	const getRoutesCustomerMap = () => {
		const routeMap = new Map();
		for (const route of routes) {
			for (const customer of route.route_customer_list) {
				let current = routeMap.has(customer.customer_id)?routeMap.get(customer.customer_id) : {customer_name: customer.customer_name};
				
				if (customer.customer_enter_center_time && customer.customer_enter_center_time !== '' ) {
					current.customer_enter_center_time = customer.customer_enter_center_time;
				}
				if (customer.customer_leave_center_time && customer.customer_leave_center_time !=='' ) {
					current.customer_leave_center_time = customer.customer_leave_center_time;
				}
				if (customer.customer_pickup_time && customer.customer_pickup_time !== '' ) {
					current.customer_pickup_time = customer.customer_pickup_time;
				}
				if (customer.customer_dropoff_time && customer.customer_dropoff_time !== '' ) {
					current.customer_dropoff_time = customer.customer_dropoff_time;
				}
				if (customer.customer_type && customer.customer_type !== '') {
					current.customer_type = customer.customer_type;
				}
				if (customer.customer_route_status && customer.customer_route_status !== '') {
					current.customer_route_report_status = PERSONAL_ROUTE_STATUS_TEXT[customer.customer_route_status]?.text;
				}
				routeMap.set(customer.customer_id, Object.assign({}, sampleMap.get(customer.customer_id), current));
			}
		}
		setRouteCustomerMap(new Map([...sampleMap, ...routeMap]));
	}

	const getRoutesCustomerMapFromExistedReport = () => {
		const routeMap = new Map();
		if (existedReports && existedReports.length > 0) {
			for (const report of existedReports[0]?.data) {
				
				let current = routeMap.has(report.customer_id)?routeMap.get(report.customer_id) : {customer_name: report.customer_name};
				if (report.customer_enter_center_time && report.customer_enter_center_time !== '' ) {
					current.customer_enter_center_time = report.customer_enter_center_time;
				}
				if (report.customer_leave_center_time && report.customer_leave_center_time !=='' ) {
					current.customer_leave_center_time = report.customer_leave_center_time;
				}
				if (report.customer_pickup_time && report.customer_pickup_time !== '' ) {
					current.customer_pickup_time = report.customer_pickup_time;
				}
				if (report.customer_dropoff_time && report.customer_dropoff_time !== '' ) {
					current.customer_dropoff_time = report.customer_dropoff_time;
				}
				if (report.customer_type && report.customer_type !== '') {
					current.customer_type = report.customer_type;
				}
				if (report.customer_route_report_status && report.customer_route_report_status !== '') {
					current.customer_route_report_status = report.customer_route_report_status;
				}
				routeMap.set(report.customer_id, Object.assign({}, sampleMap.get(report.customer_id), current));
			}
			const inboundRoutes = routes.filter(route => route.type === 'inbound');
			const outboundRoutes = routes.filter(route => route.type === 'outbound');
			for (const route of inboundRoutes) {
				for (const customer of route.route_customer_list) {
					let current = routeMap.has(customer.customer_id)?routeMap.get(customer.customer_id) : {customer_name: customer.customer_name};
					
					if (customer.customer_enter_center_time && customer.customer_enter_center_time !== '' ) {
						current.customer_enter_center_time = customer.customer_enter_center_time;
					}
					if (customer.customer_leave_center_time && customer.customer_leave_center_time !=='' ) {
						current.customer_leave_center_time = customer.customer_leave_center_time;
					}
					if (customer.customer_pickup_time && customer.customer_pickup_time !== '' ) {
						current.customer_pickup_time = customer.customer_pickup_time;
					}
					if (customer.customer_dropoff_time && customer.customer_dropoff_time !== '' ) {
						current.customer_dropoff_time = customer.customer_dropoff_time;
					}
					if (customer.customer_type && customer.customer_type !== '') {
						current.customer_type = customer.customer_type;
					}
					if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status !== PERSONAL_ROUTE_STATUS.NO_STATUS) {
						current.customer_route_report_status = PERSONAL_ROUTE_STATUS_TEXT[customer.customer_route_status]?.text;
					}
					routeMap.set(customer.customer_id, Object.assign({}, sampleMap.get(customer.customer_id), current));
				}
			}
			for (const route of outboundRoutes) {
				for (const customer of route.route_customer_list) {
					let current = routeMap.has(customer.customer_id)?routeMap.get(customer.customer_id) : {customer_name: customer.customer_name};
					
					if (customer.customer_enter_center_time && customer.customer_enter_center_time !== '' ) {
						current.customer_enter_center_time = customer.customer_enter_center_time;
					}
					if (customer.customer_leave_center_time && customer.customer_leave_center_time !=='' ) {
						current.customer_leave_center_time = customer.customer_leave_center_time;
					}
					if (customer.customer_pickup_time && customer.customer_pickup_time !== '' ) {
						current.customer_pickup_time = customer.customer_pickup_time;
					}
					if (customer.customer_dropoff_time && customer.customer_dropoff_time !== '' ) {
						current.customer_dropoff_time = customer.customer_dropoff_time;
					}
					if (customer.customer_type && customer.customer_type !== '') {
						current.customer_type = customer.customer_type;
					}
					if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status !== PERSONAL_ROUTE_STATUS.NO_STATUS) {
						current.customer_route_report_status = PERSONAL_ROUTE_STATUS_TEXT[customer.customer_route_status]?.text;
					}
					routeMap.set(customer.customer_id, Object.assign({}, sampleMap.get(customer.customer_id), current));
				}
			}
			setRouteCustomerMap(new Map([...sampleMap, ...routeMap]));
		}
	}

	const syncLatestRouteStatus = () => {
		const routeMap = new Map(routeCustomerMap);
		const date = new Date(datePicked);
		const dateText = ((date.getMonth() > 8) ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))) + '/' + ((date.getDate() > 9) ? date.getDate() : ('0' + date.getDate())) + '/' + date.getFullYear();
		TransRoutesService.getAll(dateText).then(data => {
			const routes = data.data;
			const inboundRoutes = routes.filter(route => route.type === 'inbound');
			const outboundRoutes = routes.filter(route => route.type === 'outbound');
			for (const route of inboundRoutes) {
				for (const customer of route.route_customer_list) {
					if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status!== PERSONAL_ROUTE_STATUS.NO_STATUS) {
						let current = routeMap.has(customer.customer_id)?routeMap.get(customer.customer_id) : {customer_name: customer.customer_name};
					
						if (customer.customer_enter_center_time && customer.customer_enter_center_time !== '' ) {
							current.customer_enter_center_time = customer.customer_enter_center_time;
						}
						if (customer.customer_leave_center_time && customer.customer_leave_center_time !=='' ) {
							current.customer_leave_center_time = customer.customer_leave_center_time;
						}
						if (customer.customer_pickup_time && customer.customer_pickup_time !== '' ) {
							current.customer_pickup_time = customer.customer_pickup_time;
						}
						if (customer.customer_dropoff_time && customer.customer_dropoff_time !== '' ) {
							current.customer_dropoff_time = customer.customer_dropoff_time;
						}
						if (customer.customer_type && customer.customer_type !== '') {
							current.customer_type = customer.customer_type;
						}
						if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status !== PERSONAL_ROUTE_STATUS.NO_STATUS) {
							current.customer_route_report_status = PERSONAL_ROUTE_STATUS_TEXT[customer.customer_route_status]?.text;
						}
						routeMap.set(customer.customer_id, Object.assign({}, sampleMap.get(customer.customer_id), current));
					}
					
				}
			}
			for (const route of outboundRoutes) {
				for (const customer of route.route_customer_list) {
					if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status!== PERSONAL_ROUTE_STATUS.NO_STATUS) {
						let current = routeMap.has(customer.customer_id)?routeMap.get(customer.customer_id) : {customer_name: customer.customer_name};
					
						if (customer.customer_enter_center_time && customer.customer_enter_center_time !== '' ) {
							current.customer_enter_center_time = customer.customer_enter_center_time;
						}
						if (customer.customer_leave_center_time && customer.customer_leave_center_time !=='' ) {
							current.customer_leave_center_time = customer.customer_leave_center_time;
						}
						if (customer.customer_pickup_time && customer.customer_pickup_time !== '' ) {
							current.customer_pickup_time = customer.customer_pickup_time;
						}
						if (customer.customer_dropoff_time && customer.customer_dropoff_time !== '' ) {
							current.customer_dropoff_time = customer.customer_dropoff_time;
						}
						if (customer.customer_type && customer.customer_type !== '') {
							current.customer_type = customer.customer_type;
						}
						if (customer.customer_route_status && customer.customer_route_status !== '' && customer.customer_route_status !== PERSONAL_ROUTE_STATUS.NO_STATUS) {
							current.customer_route_report_status = PERSONAL_ROUTE_STATUS_TEXT[customer.customer_route_status]?.text;
						}
						routeMap.set(customer.customer_id, Object.assign({}, sampleMap.get(customer.customer_id), current));
					}
					
				}
			}
			setRouteCustomerMap(new Map([...sampleMap, ...routeMap]));
		})
	};

	const cleanFilterAndClose = () => {
    setCallerFilter('');
		setNameFilter('');
		setAttendFilter(false);
		setStatusFilter('')
    setShowFilterReportDropdown(false);
  }

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

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

	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">User Name</div>
              <input type="text" value={nameFilter} onChange={(e) => setNameFilter(e.currentTarget.value)}/>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Caller</div>
              <input type="text" value={callerFilter} onChange={(e) => setCallerFilter(e.currentTarget.value)}/>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Customer Route 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={text}>{text}</option>
									))
								}
							</select>
            </div>
          </div>
          <div className="app-main-content-fields-section margin-sm dropdown-container">
            <div className="me-4">
              <div className="field-label">Include All Customer Attending Today</div>
              <input type="checkbox" value={attendFilter} checked={attendFilter === true} onChange={() => setAttendFilter(!attendFilter)}/>
            </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) => {
      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 for Customer Report</div>
              <DatePicker selected={datePicked} onChange={(v) => setDatePicked(v)} />
            </div>
          </div>
          <div className="list row">
            <div className="col-md-12">
              <button className="btn btn-default btn-sm float-right" onClick={() => cleanDate()}> Cancel </button>
              <button className="btn btn-primary btn-sm float-right" onClick={() => getRoutes()}>Start</button>
            </div>
          </div>
        </div>
      );
    },
  );

	useEffect(() => {
		CustomerService.getAllActiveCustomers().then((data) => setCustomers(data.data));
	}, []);

	useEffect(() => {
		let customerMap = new Map();
		for (const customer of customers) {
			customerMap.set(customer.id, { customer_name: `${customer.name} (${customer.name_cn})`, customer_caller: customer.caller, customer_vehicle: customer.vehicle_no, customer_seating: customer.seating});
		}
		setSampleMap(new Map(customerMap));
	}, [customers]);

	useEffect(() => {
		if (existedReports && existedReports.length > 0) {
			getRoutesCustomerMapFromExistedReport();
		} else {
			getRoutesCustomerMap();
		}
		
	}, [routes, existedReports]);

	useEffect(() => {
    if (csvData && csvInstance && csvInstance.current && csvInstance.current.link) {
      setTimeout(() => {
        csvInstance.current.link.click();
        setCsvData([]);
      });
    }
  }, [csvData]);

	useEffect(() => {
		const content = [];
		const customersList = Array.from(routeCustomerMap.entries()).filter(([customer_id, item]) =>[CUSTOMER_TYPE.MEMBER, CUSTOMER_TYPE.SELF_PAY].includes( item.customer_type))
		.filter(
			([customer_id, item]) => item?.customer_name?.toLowerCase()?.includes(nameFilter?.toLowerCase()));
		for (let i=0; i<customersList.length; i++) {
			const currentObj = {
				customer_id: customersList[i][0],
				customer_name: customersList[i][1].customer_name,
				customer_type: customersList[i][1].customer_type,
				customer_caller: customersList[i][1].customer_caller,
				customer_seating: customersList[i][1]?.seating,
				customer_vehicle: customersList[i][1]?.vechile_no,
				full_time_attendence: isNotFullTime(customersList[i][1].customer_enter_center_time, customersList[i][1].customer_leave_center_time)? 'No': '', 
			}
			if (customersList[i][1].customer_route_report_status) {
				currentObj.customer_route_report_status = customersList[i][1].customer_route_report_status;
			}
			if (customersList[i][1].customer_pickup_time) {
				currentObj.customer_pickup_time = customersList[i][1].customer_pickup_time;
			}
			if (customersList[i][1].customer_enter_center_time) {
				currentObj.customer_enter_center_time = customersList[i][1].customer_enter_center_time;
			}
			if (customersList[i][1].customer_leave_center_time) {
				currentObj.customer_leave_center_time = customersList[i][1].customer_leave_center_time;
			}
			if (customersList[i][1].customer_dropoff_time) {
				currentObj.customer_dropoff_time = customersList[i][1].customer_dropoff_time;
			}
			if (customersList[i][1].customer_leave_center_time && customersList[i][1].customer_enter_center_time && diff_hours(new Date(customersList[i][1].customer_leave_center_time), new Date(customersList[i][1].customer_enter_center_time))!== undefined) {
				currentObj.hours_stayed = customersList[i][1].customer_leave_center_time && customersList[i][1].customer_enter_center_time && diff_hours(new Date(customersList[i][1].customer_leave_center_time), new Date(customersList[i][1].customer_enter_center_time));
			}
			content.push(currentObj);
		}
		if (content.length === 0) {
			setEnableSave(false);
		} else {
			if (existedReports && existedReports.length > 0) {
				const isArrayEqual = (x, y) => isEmpty(xorWith(x, y, isEqual));
				setEnableSave(!isArrayEqual(content.sort((a, b) => a.customer_name > b.customer_name ? 1: -1), existedReports[0]?.data.sort((a, b) => a.customer_name > b.customer_name ? 1: -1)));
			} else {
				setEnableSave(true);
			}
		}
	}, [routeCustomerMap]);

  return (
		<>
			{
				(AuthService.canAddOrEditAttendance() || AuthService.canViewAttendance() ) && (
					<>
						<div className="list row mb-4">
							<Breadcrumb>
								<Breadcrumb.Item href="/trans-routes/dashboard">Transportation</Breadcrumb.Item>
								<Breadcrumb.Item active>
									Customer Reports
								</Breadcrumb.Item>
							</Breadcrumb>
							<div className="col-md-12 text-primary">
								<h4>
									Customer Reports 
								</h4> 
							</div>
						</div>

						<div className="app-main-content-list-container">
							<div className="app-main-content-list-func-container">
								<Tabs defaultActiveKey="customerReport" id="reports-tab">
									<Tab eventKey="customerReport" title="Customer Report">
									<h6 className="text-primary">Report Details Table</h6>
									<div className="app-main-content-fields-section with-function">
										<button className="btn btn-primary me-2" disabled={!enableSave} onClick={() => generateCustomerReport()}>Save Customer Reports</button>
										<button className="btn btn-primary me-2" onClick={() => syncLatestRouteStatus()}>Sync Latest Route Status to Report</button>
										<button onClick={() => {
											generateReportData();
										}} className="btn btn-primary me-2">Generate Customer Reports</button>
										{	csvData.length > 0 &&
											<CSVLink
												className="btn btn-primary btn-sm btn-no-deco"
												data={csvData}
												ref={csvInstance}
												filename={`Customer Attendance Report - ${datePicked.toLocaleDateString()}`}
											/>
										}
										
									</div>
										<table className="personnel-info-table">
											<thead>
												<tr>
													<th className="th-index">No.</th>
													<th>Name</th>
													<th>Customer Route Status</th>
													<th>Pick Up Time</th>
													<th>Enter Center Time</th>
													<th>Leave Center Time</th>
													<th>Drop Off Time</th>
													<th>Hours Stayed</th>
													<th>Cutomer Type</th>
													<th>Caller</th>
													<th>Seating</th>
													<th>Vehicle Number</th>
												</tr>
											</thead>
											<tbody>
												{
													Array.from(routeCustomerMap.entries()).filter(
														(item) => item[1]?.customer_name?.toLowerCase()?.includes(nameFilter?.toLowerCase()) && (
															!attendFilter ||
															attendFilter && (item[1].customer_enter_center_time || item[1].customer_leave_center_time)
														))
														.filter(item => item[1]?.customer_caller?.toLowerCase()?.includes(callerFilter?.toLowerCase()))
														.filter(item => [CUSTOMER_TYPE.MEMBER, CUSTOMER_TYPE.SELF_PAY].includes(item[1].customer_type))
														.filter(item => statusFilter ? (statusFilter !== 'No Status' ? item[1].customer_route_report_status === statusFilter : (!item[1].customer_route_report_status || item[1].customer_route_report_status === statusFilter)):item)
														.sort((a, b) => a[1].customer_name > b[1].customer_name ? 1 : -1)
														.map(([key, {customer_name, customer_pickup_time, customer_dropoff_time, customer_enter_center_time, customer_leave_center_time, customer_type, customer_caller, customer_route_report_status, customer_vehicle, customer_seating}], index) => {
														return (<tr key={index} className={`${AuthService.canAddOrEditAttendance() ? 'clickable': ''} ${isNotFullTime(customer_enter_center_time, customer_leave_center_time)? 'red': ''}`} onClick={() => openForceEditModal(key, customer_enter_center_time, customer_leave_center_time, customer_pickup_time, customer_dropoff_time, customer_route_report_status)}>
															<td className="td-index">{index+1}</td>
															<td>{customer_name}</td>
															<td>{(customer_route_report_status)}</td> 
															<td>{customer_pickup_time && new Date(customer_pickup_time).toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute: '2-digit'})}</td>
															<td>{customer_enter_center_time && new Date(customer_enter_center_time).toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute: '2-digit'})}</td>
															<td>{customer_leave_center_time && new Date(customer_leave_center_time).toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute: '2-digit'})}</td>
															<td>{customer_dropoff_time && new Date(customer_dropoff_time).toLocaleTimeString('en-US', {hour12: false, hour: '2-digit', minute: '2-digit'})}</td>
															<td>{customer_enter_center_time && customer_leave_center_time && diff_hours(new Date(customer_enter_center_time), new Date(customer_leave_center_time))}</td>
															<td>{customer_type}</td>
															<td>{customer_caller}</td>
															<td>{customer_seating}</td>
															<td>{customer_vehicle}</td>
														</tr>)
													})
												}
											</tbody>
										</table>

									</Tab>
								</Tabs>
								<div className="list-func-panel">
									<Dropdown
										key={'report-date'}
										id="report-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-report'}
										id="filter-report"
										className="me-2"
										show={showFilterReportDropdown}
										onToggle={() => setShowFilterReportDropdown(!showFilterReportDropdown)}
										autoClose={false}
									> 
										<Dropdown.Toggle variant="primary">
											<Filter size={16} className="me-2"></Filter>Filter
										</Dropdown.Toggle>
										<Dropdown.Menu as={customReportFilterMenu}/> 
									</Dropdown>
								</div>
							</div>
						</div>
						<Modal show={show} onHide={() => closeModal()}>
							<Modal.Header closeButton>
								<Modal.Title>Special Change Request Client</Modal.Title>
							</Modal.Header>
							<Modal.Body>
								<>
									<div className="app-main-content-fields-section">
										<div className="me-4">
											<div className="field-label">Special Checkin
											</div>
											<DateTimePicker onFocus={() => {if (!customerCheckInTime || customerCheckInTime.length === 0) { setCustomerCheckInTime(new Date())}}} format={'MM/dd/y HH:mm'} value={customerCheckInTime} disableClock={true} onChange={setCustomerCheckInTime} />
										</div>
										<div className="me-4">
											<div className="field-label">Special Checkout
											</div>
											<DateTimePicker onFocus={() => {if (!customerCheckOutTime || customerCheckOutTime.length === 0) { setCustomerCheckOutTime(new Date())}}} format={'MM/dd/y HH:mm'} value={customerCheckOutTime} disableClock={true} onChange={setCustomerCheckOutTime} />
										</div>
									</div>
									<div className="app-main-content-fields-section">
										<div className="me-4">
											<div className="field-label">Pickip Time
											</div>
											<DateTimePicker onFocus={() => {if (!customerPickupTime || customerPickupTime.length === 0) { setCustomerPickupTime(new Date())}}} format={'MM/dd/y HH:mm'} value={customerPickupTime} disableClock={true} onChange={setCustomerPickupTime} />
										</div>
										<div className="me-4">
											<div className="field-label">Dropoff Time
											</div>
											<DateTimePicker onFocus={() => {if (!customerDropoffTime || customerDropoffTime.length === 0) { setCustomerDropoffTime(new Date())}}} format={'MM/dd/y HH:mm'} value={customerDropoffTime} disableClock={true} onChange={setCustomerDropoffTime} />
										</div>
									</div>
									<div className="app-main-content-fields-section">
										<div className="me-4">
											<div className="field-label">Special Change Customer Route status
											</div>
											<select value={customerRouteReportStatus} onChange={e=>setCustomerRouteReportStatus(e.target.value)}>
												<option value=''></option>
												{
													Object.values(PERSONAL_ROUTE_STATUS_TEXT).map((item) => item?.text).map(text => <option key={text} value={text}>{text}</option>)
												}
											</select>
										</div>
									</div>
								</>
							</Modal.Body>
							<Modal.Footer>
								<Button variant="link" size="sm" onClick={() => closeModal()}>
									Close
								</Button>
								<Button variant="danger" size="sm" onClick={() => deleteItem()}>
									Delete This Item
								</Button>
								<Button variant="primary" size="sm" onClick={() => saveReportInfo()}>
									Save Changes
								</Button>
							</Modal.Footer>
						</Modal>
					</>)}
		</>
    
  );
};

export default CustomerReport;