import { CameraView, useCameraPermissions } from 'expo-camera';
import { useEffect, useRef, useState } from 'react';
import {
    ActivityIndicator,
    Alert,
    Dimensions,
    Pressable,
    ScrollView,
    StyleSheet,
    Text,
    Vibration,
    View
} from 'react-native';
import ChooseCarForChargingRow from '../../../../component/global/chooseCarForChargingRow';
import { CrossLogoWhiteSvg, QuestionSvg } from '../../../../component/global/SVG';
import { router } from 'expo-router';
import { chargeStationService } from '../../../../service/chargeStationService';
import { authenticationService } from '../../../../service/authService';
import { walletService } from '../../../../service/walletService';
import useUserInfoStore from '../../../../providers/userinfo_store';
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');

const ChooseCar = ({ carData, loading, selectedCar, setSelectedCar }) => {
    const isLargeScreen = screenHeight >= 800;
    const defaultImageUrl = require('../../../../assets/car1.png');

    return (
        <View
            style={{
                ...(isLargeScreen
                    ? {
                          marginTop: '10%',
                          marginBottom: '12%',
                          paddingBottom: 12
                      }
                    : {
                          flex: 1,
                          alignItems: 'center',
                          justifyContent: 'center'
                      })
            }}
        >
            <View className="justify-center items-center flex-1 ">
                <View
                    style={{
                        ...(isLargeScreen
                            ? {}
                            : {
                                  backgroundColor: 'rgba(0,0,0,0.7)'
                              })
                    }}
                >
                    {loading ? (
                        <View className="w-full">
                            <ActivityIndicator color="#34657b" />
                        </View>
                    ) : (
                        <View className="w-screen  bg-[#000000B3]">
                            <View className="flex-row items-center justify-between mx-[5%] ">
                                <Pressable
                                    className="pt-4 "
                                    onPress={() => {
                                        if (router.canGoBack()) {
                                            router.back();
                                        } else {
                                            router.replace('mainPage');
                                        }
                                    }}
                                >
                                    <CrossLogoWhiteSvg />
                                </Pressable>

                                <Text className="text-base text-white pt-2">選擇充電車輛</Text>
                                <Text className="text-xl text-white pt-2"></Text>
                            </View>

                            <ScrollView
                                horizontal={true}
                                showsHorizontalScrollIndicator={false}
                                contentContainerStyle={{
                                    alignItems: 'center',
                                    flexDirection: 'row',
                                    marginVertical: 12
                                }}
                                className="space-x-2 mx-[5%]"
                            >
                                {carData.map((car, index) => (
                                    <ChooseCarForChargingRow
                                        key={`${car.name}+${index}`}
                                        image={car.image}
                                        onPress={() => {
                                            setSelectedCar(car.id);
                                            console.log(car.id);
                                        }}
                                        isSelected={selectedCar === car.id}
                                        // imageUrl={image}
                                        VehicleName={car.name}
                                        isDefault={car.isDefault}
                                    />
                                ))}
                            </ScrollView>
                        </View>
                    )}
                </View>
            </View>
        </View>
    );
};

//reminder: scan qr code page, ic call should be false
const ScanQrPage = () => {
    const { userID, setUserID } = useUserInfoStore();
    // State declarations
    const [permission, requestPermission] = useCameraPermissions();
    const [scanned, setScanned] = useState(false);
    const viewRef = useRef(null);
    const [scannedResult, setScannedResult] = useState('');
    const [selectedCar, setSelectedCar] = useState('');

    const now = new Date();
    const [loading, setLoading] = useState(true);
    const [loading2, setLoading2] = useState(false);
    const [loading3, setLoading3] = useState(false);
    const [carData, setCarData] = useState([]);

    // Effect for requesting camera permissions
    useEffect(() => {
        (async () => {
            const { status } = await requestPermission();
            if (status !== 'granted') {
                alert(
                    '我們需要相機權限來掃描機器上的二維碼，以便識別並啟動充電機器。我們不會儲存或共享任何掃描到的資訊。 請前往設定開啟相機權限'
                );
            }
        })();
    }, []);

    // Effect for fetching user's cars
    useEffect(() => {
        const fetchAllCars = async () => {
            try {
                const response = await chargeStationService.getUserCars();
                if (response) {
                    // console.log(response.data);
                    const carTypes = response.data.map((item: any) => ({
                        id: item.id,
                        name: item.car_type.name,
                        image: item.car_type.type_image_url
                    }));
                    console.log('carTypes', carTypes);
                    // console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', carTypes);
                    let updatedCarTypes = [...carTypes];
                    for (let i = 0; i < carTypes.length; i++) {
                        const car = updatedCarTypes[i];
                        const imageUrl = await chargeStationService.getProcessedImageUrl(car.image);
                        updatedCarTypes[i] = {
                            ...car,
                            image: imageUrl
                        };
                    }
                    setCarData(updatedCarTypes);
                    console.log('updatedCarTypes', updatedCarTypes);
                    return true;
                }
            } catch (error) {
                console.log(error);
            } finally {
                setLoading(false);
            }
        };
        fetchAllCars();
    }, []);

    if (!permission) {
        return <View />;
    }

    if (!permission.granted) {
        return (
            <View className="flex-1 justify-center items-center">
                <Text style={{ textAlign: 'center' }}>
                    我們需要相機權限來掃描機器上的二維碼，以便識別並啟動充電機器。我們不會儲存或共享任何掃描到的資訊。
                    請前往設定開啟相機權限
                </Text>
            </View>
        );
    }

    // Function to handle barcode scanning
    const handleBarCodeScanned = async ({ bounds, data, type }: { bounds?: any; data: any; type: any }) => {
        // Check if bounds exists and has the expected properties
        if (
            !bounds ||
            typeof bounds.origin?.x !== 'number' ||
            typeof bounds.origin?.y !== 'number' ||
            typeof bounds.size?.width !== 'number' ||
            typeof bounds.size?.height !== 'number'
        ) {
            console.log('Invalid or missing bounds data:', bounds);
            // Proceed with scanning logic without bounds checking
            setScanned(true);
            setScannedResult(data);
            Vibration.vibrate(100);
            console.log(`type: ${type}   data: ${data}  typeofData ${typeof data}`);

            // Continue with the rest of your scanning logic...
            try {
                const response = await chargeStationService.getTodayReservation();
                if (response) {
                    const now = new Date();

                    const onlyThisConnector = response.filter(
                        (reservation: any) => reservation.connector.ConnectorID === data
                    );

                    onlyThisConnector.sort((a: any, b: any) => {
                        const timeA = new Date(a.book_time).getTime();
                        const timeB = new Date(b.book_time).getTime();
                        return timeA - timeB;
                    });

                    let previousReservation = null;
                    let upcomingReservation = null;

                    for (let i = 0; i < onlyThisConnector.length; i++) {
                        const reservationTime = new Date(onlyThisConnector[i].book_time).getTime();
                        if (reservationTime <= now.getTime()) {
                            previousReservation = onlyThisConnector[i];
                        } else {
                            upcomingReservation = onlyThisConnector[i];
                            break;
                        }
                    }

                    const relevantReservations = [previousReservation || null, upcomingReservation || null];

                    //this find the one res before and one res after current time.
                    console.log('Relevant reservations:', relevantReservations);

                    const getNearestSlot = (date: Date) => {
                        const minutes = date.getMinutes();
                        const nearestSlot = new Date(date);
                        nearestSlot.setMinutes(minutes < 30 ? 0 : 30);
                        nearestSlot.setSeconds(0);
                        nearestSlot.setMilliseconds(0);
                        return nearestSlot;
                    };

                    const currentSlot = getNearestSlot(now);
                    const nextSlot = new Date(currentSlot.getTime() + 30 * 60 * 1000);

                    const AreOrdersAdjacentToNow = relevantReservations.map((reservation, index) => {
                        if (!reservation) return false;

                        const reservationTime = new Date(reservation.book_time);
                        return index === 0
                            ? reservationTime.getTime() === currentSlot.getTime()
                            : reservationTime.getTime() === nextSlot.getTime();
                    });

                    console.log('AreOrdersAdjacentToNow:', AreOrdersAdjacentToNow);

                    if (!AreOrdersAdjacentToNow[0] && !AreOrdersAdjacentToNow[1]) {
                        console.log('Charging machine is available. Starting charging process...');
                        startCharging(data);
                    } else if (AreOrdersAdjacentToNow[0]) {
                        const previousReservation = relevantReservations[0];
                        if (previousReservation && previousReservation.user.id === userID) {
                            const reservationTime = new Date(previousReservation.book_time);
                            const timeDifference = now.getTime() - reservationTime.getTime();
                            const minutesDifference = timeDifference / (1000 * 60);

                            if (minutesDifference <= 15) {
                                console.log('User arrived within 15 minutes of their reservation.');
                                startCharging(data);
                            } else {
                                console.log('User arrived more than 15 minutes late for their reservation.');
                                if (!AreOrdersAdjacentToNow[1]) {
                                    console.log('Next slot is available. Allowing charging despite late arrival.');
                                    startCharging(data);
                                } else {
                                    Alert.alert(
                                        '預約已過期',
                                        '您的預約時間已經過期，且下一個時段已被預約。請重新預約。'
                                    );
                                    console.log('Next slot is not available. Charging not allowed.');
                                }
                            }
                        } else {
                            Alert.alert('無法使用', '此充電槍已經被預約，請選擇其他位置');
                        }
                    } else if (AreOrdersAdjacentToNow[1]) {
                        const upcomingReservation = relevantReservations[1];
                        if (upcomingReservation && upcomingReservation.user.id === userID) {
                            const minutesUntilReservation =
                                (new Date(upcomingReservation.book_time).getTime() - now.getTime()) / (1000 * 60);
                            if (minutesUntilReservation <= 5) {
                                console.log('User arrived slightly early for their upcoming reservation.');
                                startCharging(data);
                            } else {
                                Alert.alert(
                                    '預約時間未到',
                                    `您的預約時間還有 ${Math.round(minutesUntilReservation)} 分鐘開始。請稍後再試。`
                                );
                            }
                        } else {
                            Alert.alert('已被預約', '此充電槍已被其他用戶預約。請選擇其他位置。');
                        }
                    } else {
                        Alert.alert('無法使用', '此充電槍目前無法使用。請選擇其他位置或稍後再試。');
                    }
                } else {
                    console.log('No response from getTodayReservation');
                    Alert.alert('系統錯誤', '無法獲取預約信息。請稍後再試。');
                }
            } catch (error) {
                console.error("Error fetching today's reservations:", error);
                Alert.alert('系統錯誤', '發生未知錯誤。請稍後再試。');
            }

            setTimeout(() => {
                setScanned(false);
            }, 2000);
            return;
        }

        const { origin, size } = bounds;

        // Calculate the size of the square transparent area
        const transparentAreaSize = Math.min(screenWidth * 0.6, screenHeight * 0.3);
        const transparentAreaX = (screenWidth - transparentAreaSize) / 2;
        const transparentAreaY = (screenHeight - transparentAreaSize) / 2;

        // Check if the barcode is within the transparent area
        if (
            origin.x >= transparentAreaX &&
            origin.y >= transparentAreaY &&
            origin.x + size.width <= transparentAreaX + transparentAreaSize &&
            origin.y + size.height <= transparentAreaY + transparentAreaSize
        ) {
            setScanned(true);
            setScannedResult(data);
            Vibration.vibrate(100);
            console.log(` type: ${type}   data: ${data}  typeofData ${typeof data}`);

            try {
                const response = await chargeStationService.getTodayReservation();
                if (response) {
                    const now = new Date();

                    const onlyThisConnector = response.filter(
                        (reservation: any) => reservation.connector.ConnectorID === data
                    );

                    onlyThisConnector.sort((a: any, b: any) => {
                        const timeA = new Date(a.book_time).getTime();
                        const timeB = new Date(b.book_time).getTime();
                        return timeA - timeB;
                    });

                    let previousReservation = null;
                    let upcomingReservation = null;

                    for (let i = 0; i < onlyThisConnector.length; i++) {
                        const reservationTime = new Date(onlyThisConnector[i].book_time).getTime();
                        if (reservationTime <= now.getTime()) {
                            previousReservation = onlyThisConnector[i];
                        } else {
                            upcomingReservation = onlyThisConnector[i];
                            break;
                        }
                    }

                    const relevantReservations = [previousReservation || null, upcomingReservation || null];

                    console.log('Relevant reservations:', relevantReservations);

                    const getNearestSlot = (date: Date) => {
                        const minutes = date.getMinutes();
                        const nearestSlot = new Date(date);
                        nearestSlot.setMinutes(minutes < 30 ? 0 : 30);
                        nearestSlot.setSeconds(0);
                        nearestSlot.setMilliseconds(0);
                        return nearestSlot;
                    };

                    const currentSlot = getNearestSlot(now);
                    const nextSlot = new Date(currentSlot.getTime() + 30 * 60 * 1000);

                    const AreOrdersAdjacentToNow = relevantReservations.map((reservation, index) => {
                        if (!reservation) return false;

                        const reservationTime = new Date(reservation.book_time);
                        return index === 0
                            ? reservationTime.getTime() === currentSlot.getTime()
                            : reservationTime.getTime() === nextSlot.getTime();
                    });

                    console.log('AreOrdersAdjacentToNow:', AreOrdersAdjacentToNow);

                    if (!AreOrdersAdjacentToNow[0] && !AreOrdersAdjacentToNow[1]) {
                        console.log('Charging machine is available. Starting charging process...');
                        startCharging(data);
                    } else if (AreOrdersAdjacentToNow[0]) {
                        const previousReservation = relevantReservations[0];
                        if (previousReservation && previousReservation.user.id === userID) {
                            const reservationTime = new Date(previousReservation.book_time);
                            const timeDifference = now.getTime() - reservationTime.getTime();
                            const minutesDifference = timeDifference / (1000 * 60);

                            if (minutesDifference <= 15) {
                                console.log('User arrived within 15 minutes of their reservation.');
                                startCharging(data);
                            } else {
                                console.log('User arrived more than 15 minutes late for their reservation.');
                                if (!AreOrdersAdjacentToNow[1]) {
                                    console.log('Next slot is available. Allowing charging despite late arrival.');
                                    startCharging(data);
                                } else {
                                    Alert.alert(
                                        '預約已過期',
                                        '您的預約時間已經過期，且下一個時段已被預約。請重新預約。'
                                    );
                                    console.log('Next slot is not available. Charging not allowed.');
                                }
                            }
                        } else {
                            Alert.alert('無法使用', '此充電槍已經被預約，請選擇其他位置');
                        }
                    } else if (AreOrdersAdjacentToNow[1]) {
                        const upcomingReservation = relevantReservations[1];
                        if (upcomingReservation && upcomingReservation.user.id === userID) {
                            const minutesUntilReservation =
                                (new Date(upcomingReservation.book_time).getTime() - now.getTime()) / (1000 * 60);
                            if (minutesUntilReservation <= 5) {
                                console.log('User arrived slightly early for their upcoming reservation.');
                                startCharging(data);
                            } else {
                                Alert.alert(
                                    '預約時間未到',
                                    `您的預約時間還有 ${Math.round(minutesUntilReservation)} 分鐘開始。請稍後再試。`
                                );
                            }
                        } else {
                            Alert.alert('已被預約', '此充電槍已被其他用戶預約。請選擇其他位置。');
                        }
                    } else {
                        Alert.alert('無法使用', '此充電槍目前無法使用。請選擇其他位置或稍後再試。');
                    }
                } else {
                    console.log('No response from getTodayReservation');
                    Alert.alert('系統錯誤', '無法獲取預約信息。請稍後再試。');
                }
            } catch (error) {
                console.error("Error fetching today's reservations:", error);
                Alert.alert('系統錯誤', '發生未知錯誤。請稍後再試。');
            }

            setTimeout(() => {
                setScanned(false);
            }, 2000);
        }
    };

    //prepare data for submission
    const dataForSubmission = {
        stationID: '2405311022116801000',
        connector: scannedResult,
        user: userID,
        book_time: now,
        end_time: now,
        total_power: 0,
        total_fee: 0,
        promotion_code: '',
        car: selectedCar,
        type: 'walking',
        is_ic_call: false
    };

    const startCharging = async (scanResult: string) => {
        try {
            if (selectedCar === '') {
                Alert.alert('請選擇車輛');
                return;
            }

            const response = await walletService.submitPayment(
                dataForSubmission.stationID,
                scanResult,
                dataForSubmission.user,
                dataForSubmission.book_time,
                dataForSubmission.end_time,
                dataForSubmission.total_power,
                dataForSubmission.total_fee,
                dataForSubmission.promotion_code,
                dataForSubmission.car,
                dataForSubmission.type,
                dataForSubmission.is_ic_call
            );

            if (response) {
                console.log('Charging started from startCharging', response);
                router.push('(auth)/(tabs)/(charging)/chargingPage');
            } else {
                console.log('Failed to start chargi12312312ng:', response);
                Alert.alert('掃描失敗 請稍後再試。', response);
            }
        } catch (error) {
            console.log('Failed to start charging:', error);
        }
    };

    return (
        <View style={styles.container} ref={viewRef}>
            {loading ? (
                <View className="flex-1 items-center justify-center">
                    <ActivityIndicator />
                </View>
            ) : (
                <CameraView
                    style={styles.camera}
                    facing="back"
                    barcodeScannerSettings={{
                        barcodeTypes: ['qr']
                    }}
                    onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
                    responsiveOrientationWhenOrientationLocked={true}
                >
                    <View style={styles.overlay}>
                        <View style={styles.topOverlay}>
                            <ChooseCar
                                carData={carData}
                                loading={loading}
                                selectedCar={selectedCar}
                                setSelectedCar={setSelectedCar}
                            />
                        </View>
                        <View style={styles.centerRow}>
                            <View style={styles.leftOverlay}></View>
                            <View style={styles.transparentArea}></View>
                            <View style={styles.rightOverlay} />
                        </View>
                        <View className="items-center justify-between" style={styles.bottomOverlay}>
                            <View>
                                <Text className="text-white text-lg font-bold mt-2 text-center">
                                    請選擇充電車輛{'\n'}及掃瞄充電座上的二維碼
                                </Text>
                            </View>
                            <View className="flex-row space-x-2 items-center ">
                                <QuestionSvg />

                                <Pressable onPress={() => router.push('assistancePage')}>
                                    <Text className="text-white text-base">需要協助?</Text>
                                </Pressable>
                            </View>
                            <View />
                        </View>
                    </View>
                </CameraView>
            )}
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    camera: {
        flex: 1
    },
    overlay: {
        flex: 1
    },
    topOverlay: {
        flex: 35,
        alignItems: 'center',
        backgroundColor: 'rgba(0,0,0,0.5)'
    },
    centerRow: {
        flex: 30,
        flexDirection: 'row'
    },
    leftOverlay: {
        flex: 20,
        backgroundColor: 'rgba(0,0,0,0.5)'
    },
    transparentArea: {
        flex: 60,
        aspectRatio: 1,
        position: 'relative'
    },

    rightOverlay: {
        flex: 20,
        backgroundColor: 'rgba(0,0,0,0.5)'
    },
    bottomOverlay: {
        flex: 35,
        backgroundColor: 'rgba(0,0,0,0.5)'
    }
});

export default ScanQrPage;
