import React, {useState, useEffect, useCallback, useLayoutEffect} from 'react';
import {
TouchableOpacity,
Text,
View,
FlatList,
Alert,
ActivityIndicator,
Image,
TextInput,
} from 'react-native';
import {useUser} from '../../context/UserContext';
import ApiManager from '../../services/ApiManager';
import ScheduleScreenStyle from '../../styles/ScheduleScreenStyle';
import {useMqtt} from '../../context/MqttContext';
import {useFocusEffect} from '@react-navigation/native';
import moment from 'moment';
import {COLORS} from '../../styles/colors';
import {fontSize, fontWeight} from '../../styles/fontstyle';
import {ADD, ARROW, CALENDER, SEARCH, TIME} from '../../assets';
import HomeScreenStyles from '../../styles/HomeScreenStyles';
import AddItemModal from '../../services/AddItemModal';
import uiStyle from '../../styles/uiStyle';
const ScheduleScreen = ({navigation}) => {
const [items, setItems] = useState([]);
const [filteredItems, setFilteredItems] = useState([]);
const [isFetching, setIsFetching] = useState(false);
const [search, setSearch] = useState('');
const [scheduleId, setScheduleId] = useState('');
const [scheduleName, setScheduleName] = useState('');
const [deletePoup, setDeletePopup] = useState(false);
const {userDetails} = useUser();
const {connectionState, subscribe, unsubscribe, publish} = useMqtt();
const [sceneStatuses, setSceneStatuses] = useState({});
const MQTT_SUBSCRIBE_TOPIC =
'advaint/deletesceneschedule/cus_' + userDetails.customer_id + '/feedback';
const MQTT_PUBLISH_TOPIC = `advaint/deletesceneschedule/cus_${userDetails.customer_id}`;
useEffect(() => {
if (userDetails?.customer_id) {
getScheduleDetails();
} else {
setItems([]);
}
}, [userDetails?.customer_id]);
useEffect(() => {
const filtered = items.filter(item =>
`${item.schedule_name} ${item.scene_name}`
.toLowerCase()
.includes(search.toLowerCase()),
);
setFilteredItems(filtered);
}, [search, items]);
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={{
backgroundColor: uiStyle.blue_color,
borderRadius: 100,
marginRight: 20,
padding: 5,
}}
onPress={() => {}}>
<Image
source={ADD}
style={{height: 20, width: 20, tintColor: COLORS.white_color}}
/>
</TouchableOpacity>
),
});
}, [navigation, userDetails]);
useFocusEffect(
useCallback(() => {
const callback = (data, topic) => {
try {
const payload = JSON.parse(data);
console.log('payload', payload);
if (payload) {
handleRefresh();
}
} catch (e) {
console.warn('MQTT message data is not JSON:', data);
}
};
subscribe(MQTT_SUBSCRIBE_TOPIC, callback);
return () => {
unsubscribe(MQTT_SUBSCRIBE_TOPIC, callback);
};
}, [subscribe, unsubscribe, userDetails?.flat]),
);
const getScheduleDetails = async (isManualRefresh = false) => {
if (!userDetails?.customer_id) {
setIsFetching(false);
return;
}
setIsFetching(true);
const customer_id = userDetails.customer_id;
try {
const listResponse = await ApiManager.getScheduleScene(customer_id);
if (listResponse?.Data) {
setItems(listResponse.Data);
} else {
setItems([]);
if (isManualRefresh) {
Alert.alert('Error', 'Invalid data format received.');
}
}
} catch (error) {
if (isManualRefresh) {
Alert.alert(
'Fetch Failed',
error.message || 'Unexpected error occurred.',
);
}
setItems([]);
} finally {
setIsFetching(false);
}
};
const handleRefresh = () => {
getScheduleDetails(true);
};
const deleteSchedule = () => {
const deleteJson = {
customer_id: userDetails?.customer_id,
schedule_id: scheduleId,
};
console.log('Publishing MQTT message:', deleteJson);
publish(MQTT_PUBLISH_TOPIC, deleteJson);
};
const renderItem = ({item}) => {
const totalDays = item.day_of_week;
const selectedDaysList = totalDays.split(',').map(Number);
const dayAbbreviations = ['Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa'];
const abbreviatedDays = selectedDaysList.map(
dayNumber => dayAbbreviations[dayNumber],
);
const abbreviatedDaysText = abbreviatedDays.join(', ');
return (
<TouchableOpacity
style={ScheduleScreenStyle.ScheduleListView}
onPress={() => {
setScheduleId(item.schedule_id);
setScheduleName(item.schedule_name);
setDeletePopup(true);
}}>
<View>
<Text style={ScheduleScreenStyle.schedule_header_style}>
{item.schedule_name}
</Text>
<Text
style={{
color: COLORS.label_color,
fontSize: fontSize.sub_heading,
fontWeight: fontWeight.label_weight,
marginBottom: 5,
}}>
Scene:{' '}
<Text style={ScheduleScreenStyle.contenView}>
{item.scene_name}
</Text>
</Text>
<View style={ScheduleScreenStyle.date_time_details_View}>
<Image source={CALENDER} style={{height: 20, width: 20}} />
<Text style={ScheduleScreenStyle.contenView}>
{moment(item.start_date).format('DD-MM-YYYY')} to{' '}
{moment(item.end_date).format('DD-MM-YYYY')}
{'\n'} ({abbreviatedDaysText})
</Text>
</View>
<View style={ScheduleScreenStyle.date_time_details_View}>
<Image source={TIME} style={{height: 20, width: 20}} />
<Text style={ScheduleScreenStyle.contenView}>
{moment(item.start_time, 'HH:mm').format('hh:mm a')} to{' '}
{moment(item.end_time, 'HH:mm').format('hh:mm a')}
</Text>
</View>
</View>
<Image source={ARROW} style={{height: 20, width: 20}} />
</TouchableOpacity>
);
};
const renderContent = () => {
if (isFetching && items.length === 0) {
return (
<View style={ScheduleScreenStyle.centeredMessageContainer}>
<ActivityIndicator size="large" color="#007bff" />
<Text style={ScheduleScreenStyle.messageText}>Loading items...</Text>
</View>
);
}
if (!isFetching && filteredItems.length === 0) {
return (
<View style={ScheduleScreenStyle.centeredMessageContainer}>
<Text style={ScheduleScreenStyle.messageText}>
No items found
</Text>
</View>
);
}
return (
<FlatList
data={filteredItems}
renderItem={renderItem}
keyExtractor={item => item.id}
contentContainerStyle={ScheduleScreenStyle.listContentContainer}
onRefresh={handleRefresh}
refreshing={isFetching}
/>
);
};
return (
<View style={ScheduleScreenStyle.safeArea}>
<View style={ScheduleScreenStyle.searchView}>
<Image
source={SEARCH}
style={{height: 20, width: 20, tintColor: COLORS.black_color}}
/>
<TextInput
value={search}
placeholder="Search"
onChangeText={text => setSearch(text)}
style={{flex: 1, marginLeft: 10}}
/>
</View>
{renderContent()}
{deletePoup && (
<AddItemModal
isVisible={deletePoup}
onClose={() => {
setDeletePopup(false);
}}
modalTitle={`Schedule: ${scheduleName}`}
fields={[]}
type="delete_schedule"
onDisableSchedule={() => {
deleteSchedule();
setDeletePopup(false);
}}>
<View style={HomeScreenStyles.modalDisplayContent}></View>
</AddItemModal>
)}
</View>
);
};
export default ScheduleScreen;
here i want to call handleRefresh even if filteredItems is empty i want to call it when i scroll down on screen