import { Grid, Divider, Typography, Box, makeStyles, Button, Popover } from '@material-ui/core'
import { useTranslation } from 'react-i18next'
import { IMapViewProps } from './MapView.types'
import GoogleMap, { Coords } from 'google-map-react'
import MapPin from '../../Common/MapPin/MapPin'
import ShowJobs from '../Jobs/ShowJobs/ShowJobs'
import { useDispatch, useSelector } from 'react-redux'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import useSuperCluster from 'use-supercluster'
import JobPin from '../../Common/JobPin/JobPin'
import { Job } from '../../../Api/Job/Job'
import { IJobFilters, IJobInfo } from '../../../../../Application/DTOs/JobsDto/JobsDto.types'
import { toast } from 'react-toastify'
import { setLoader } from '../../../Redux/Loader/actions'
import { setJobList } from '../../../Redux/Job/actions'
import { ALL, USER_ROLES } from '../../../Types/Constants'
import { AppState } from '../../../Redux'
import { getCurrentLocation } from '../../../Utilities/Geolocation'
import FilterListIcon from '@material-ui/icons/FilterList';
import FilterPopover from '../../Common/FilterPopover/FilterPopover'
import Legends from './legend'
import moment from 'moment'
import { Driver } from '../../../Api/Driver/Driver'
import { IN_PROGRESS, ASSIGNED } from '../Jobs/Jobs.constans'
import Marker from './Marker';
import { Wrapper } from '@googlemaps/react-wrapper';
import CustomTable from '../../Common/CustomTable/CustomTable';
import { GridRowParams } from '@material-ui/data-grid';
import { getShowJobsTableColumns } from './columns';
import { TShowTypes } from './Jobs.types';
import { useRouteMatch, useHistory } from 'react-router-dom';
import ViewEditJob from '../../Dialogs/ViewEditJob/ViewEditJob';

import {
    AVAILABLE,
    BIDS_TO_CONFIRM,
    JOBS_WILDCARDS_KEYS,
} from './Jobs.constans';
const useStyles = makeStyles(() => ({
    mapBox: {
        width: '100%',
        height: '40vh',
        display: 'flex',
        flexFlow: 'row nowrap',
        justifyContent: 'center',
        padding: 0
    }
}))

const jobsApi = new Job()
const driverApi = new Driver()

const {
    ADMIN_USER,
    SUPER_ADMIN
} = USER_ROLES



function MapViewV2(props: IMapViewProps) {
    const [t] = useTranslation('MapView')
    const dispatch = useDispatch()
    const classes = useStyles()
    const [mapJobs, setMapJobs] = useState<IJobInfo[]>([])
    const [bounds, setBounds] = useState<any>(null)
    const [zoom, setZoom] = useState(5)
    const [showMaps, setShowMaps] = useState(false)
    const [showData, setShowdata] = useState(false)
    const match = useRouteMatch();

    const params: any = match.params;

    const showType: TShowTypes | undefined = (params[JOBS_WILDCARDS_KEYS.SHOW_TYPE] as any) || AVAILABLE;
    const [isViewEditJobDialogOpen, setIsViewEditJobDialogOpen] = useState(false);
    const [selectedJob, setSelectedJob] = useState<IJobInfo | null>(null);


    const user = useSelector((state: AppState) => state.user)
    const columns = getShowJobsTableColumns(t, showType, user);

    const isAdminUser = user.response?.type === ADMIN_USER
    const isSuperAdmin = user.response?.type === SUPER_ADMIN
    const ownerId = user.response?.company?.id
    const [center, setCenter] = useState<Coords | undefined>(undefined)
    const [mapZoom, setMapZoom] = useState<number | undefined>(undefined)
    const [popOverAnchorEl, setPopOverAnchorEl] = useState(null)
    const [carMarkers, setCarMarkers] = useState<any>(null)
    const [filters, setFilters] = useState<IJobFilters>({
        country: 'australia',
        jobType: ALL,
        vehicleType: ALL,
        status: ALL
    })

    const handlePopOverOpen = useCallback(
        (e) => {
            setPopOverAnchorEl(e.currentTarget)
        },
        [],
    )

    const handlePopOverClose = useCallback(
        () => {
            setPopOverAnchorEl(null)
        },
        [],
    )

    // useEffect(() => {
    //     if(user && showMaps) {
    //         setCenter({
    //             lat: user.response?.company?.latitude != 0 ? user.response?.company?.latitude || -34.0207477547681 :   -34.0207477547681,
    //             lng: user.response?.company?.longitude != 0 ? user.response?.company?.longitude ||  151.04825829174933  :  151.04825829174933
    //         })
    //         setMapZoom(5)
    //     }
    // }, [user, showMaps])


    const getAvailableJobs = useCallback(
        (filters?: IJobFilters) => {
            jobsApi.get(props.type, 'maps_data', isAdminUser ? user.response?.country : undefined, filters)
                .then(async (response) => {
                    const jobs: IJobInfo[] = response.data

                    setTimeout(() => {
                        setShowMaps(true)

                    }, 1000);
                    await setMapJobs(jobs)
                    setMapZoom(5)
                    await dispatch(setLoader(false))
                    await dispatch(setJobList(jobs))
                    //search me
                })
                .catch((err) => {
                    console.log('err', err)
                    toast.error(t('error_getting_jobs'))
                })
        },
        [dispatch, t, props.type, user.response?.country, isAdminUser],
    )

    useEffect(() => {

        getAvailableJobs(filters)
        getAllDriverLocation(user.response?.company?.id)

    }, [filters])



    useEffect(() => {
        let isMounted = true;

        const getAvailableJobs = async (filters?: IJobFilters) => {
            try {
                dispatch(setLoader(true));
                const response = await jobsApi.get(props.type, 'maps_data', isAdminUser ? user.response?.country : undefined, filters);
                const jobs: IJobInfo[] = response.data;
                if (isMounted) {
                    setShowMaps(true);
                    setMapJobs(jobs);
                    setMapZoom(5);
                    dispatch(setJobList(jobs));
                }
            } catch (error) {
                console.error('Error getting jobs:', error);
                toast.error(t('error_getting_jobs'));
            } finally {
                if (isMounted) {
                    dispatch(setLoader(false));
                }
            }
        };

        getAvailableJobs(filters);

        return () => {
            isMounted = false;
        };
    }, [dispatch, t, props.type, user.response?.country, isAdminUser, filters]);


    const getAllDriverLocation = async (companyId?: string | number) => {
        await driverApi.getAllDriverLocation(companyId)
            .then((response) => {
                const data = response.data
                setCarMarkers(data)
            })
            .catch((err) => {
                console.log('err', err)
                // toast.error(t('error_getting_drivers_waiting_for_approval'))
            })
    }


    useEffect(() => {
        setTimeout(() => {
            setShowdata(true)

        }, 2000);


    }, [showMaps, showData])

    const points: any = useMemo(() => mapJobs.filter((job) => job.pick_up_address).map((job) => ({
        type: "Feature",
        properties: {
            cluster: false, jobId: job.id,
            isSeaFreight: job.pick_up_address?.is_sea_freight,
            status: (job.status == 'in_progress' && job.assignedUser) ? 'assigned' : job.status,
            reference: job.reference
        },
        geometry: {
            type: "Point",
            coordinates: [
                parseFloat(job.pick_up_address?.longitude || '0'),
                parseFloat(job.pick_up_address?.latitude || '0')
            ],

        },

    })), [mapJobs])


    const { clusters, supercluster } = useSuperCluster({
        points,
        bounds,
        zoom,
        options: {
            radius: 75,
            maxZoom: 20
        }
    })

    const handleOnClusterClick = useCallback(
        (pointsInCluster: any[]) => {
            const jobIds: any[] = pointsInCluster.map((point: any) => point.properties.jobId)

            dispatch(setJobList(mapJobs.filter((mapJob) => jobIds.includes(mapJob.id))))
        },
        [dispatch, mapJobs],
    )
    const handleOnMapPinClick = useCallback(
        (jobId: number) => {

            dispatch(setJobList(mapJobs.filter((mapJob) => jobId == mapJob.id)))
        },
        [dispatch, mapJobs],
    )

    const clusterComponents = useMemo(() => clusters.map(cluster => {

        const [longitude, latitude] = cluster.geometry.coordinates
        const {
            cluster: isCluster,
            point_count: pointCount,
            jobId,
            isSeaFreight,
            status,
            reference
        } = cluster.properties;

        if (isCluster) {
            return <MapPin onClick={() => { if (supercluster) handleOnClusterClick(supercluster.getLeaves(cluster.id as any, Infinity)) }}
                key={`cluster-${cluster.id}`}
                text={pointCount}
                lat={latitude}
                lng={longitude}
            />
        }
        else {
            return <JobPin onClick={() => { handleOnMapPinClick(jobId) }} isSeaFreight={isSeaFreight} key={`job-${jobId}`} lat={latitude} lng={longitude} status={status} reference={reference} />
        }
    }), [clusters, handleOnClusterClick, supercluster, points])

    const handleFilterChange = useCallback(
        (filter: IJobFilters) => {
            setFilters(filter)
        },
        [],
    )
    const handleOnViewEditJobDialogClose = useCallback(() => {
        setIsViewEditJobDialogOpen(false);
        setSelectedJob(null);
    }, []);

    const onRowClick = useCallback((params: GridRowParams) => {
        const job: IJobInfo = params.row as IJobInfo;

        setSelectedJob(job);
        setIsViewEditJobDialogOpen(true);
    }, []);


    return (
        <>
            <Grid
                direction="column"
                container
                justifyContent="space-between"
                alignItems="stretch"
                spacing={2}
            >

                <Grid item md={3}>
                    <Typography>
                        {t('map_view')}
                    </Typography>
                </Grid>
               
                <Grid item md>
                    <Grid
                        container
                        spacing={2}
                        justifyContent="flex-end"
                    >
                        <Legends />
                        <Grid item md={3}>
                            <Button onClick={handlePopOverOpen} fullWidth startIcon={<FilterListIcon />} variant="contained" color="primary">
                                {t('filter')}
                            </Button>
                            <Popover
                                open={Boolean(popOverAnchorEl)}
                                anchorEl={popOverAnchorEl}
                                onClose={handlePopOverClose}
                                anchorOrigin={{
                                    horizontal: 'right',
                                    vertical: 'top'
                                }}

                            >
                                <FilterPopover hideCompletedDateSelector filters={filters} onFilterChange={handleFilterChange} onClose={handlePopOverClose} />
                            </Popover>
                        </Grid>
                        <Grid item lg={12} style={{
                            width: "100%",
                            marginLeft: 0
                        }}>
                            <div style={{
                                height: 350,
                                width: '100%',
                                display: 'flex',
                                flexFlow: 'row nowrap',
                                justifyContent: 'center',
                                padding: 0
                            }}>
                                {
                                    showMaps
                                        ? <GoogleMap
                                            defaultCenter={{ lat: -34.0207477547681, lng: 151.04825829174933 }}
                                            // defaultCenter={{ lat: 0, lng: 0}}
                                            defaultZoom={5}
                                            center={center}
                                            zoom={mapZoom}
                                            bootstrapURLKeys={{ key: process.env.REACT_APP_GOOGLE_MAP_API_KEY || '' }}
                                            yesIWantToUseGoogleMapApiInternals
                                            onChange={({ zoom, bounds }) => {
                                                setZoom(zoom);
                                                setBounds([
                                                    bounds.nw.lng,
                                                    bounds.se.lat,
                                                    bounds.se.lng,
                                                    bounds.nw.lat
                                                ]);
                                            }}
                                        >

                                            {clusters ? clusterComponents : null}
                                            {carMarkers ? carMarkers.map((marker: any) =>
                                            ((marker.latitude != 0 && marker.longitude != 0) ?
                                                <Marker
                                                    key={marker.id}
                                                    lat={marker.latitude}
                                                    lng={marker.longitude}
                                                    id={marker.id}
                                                    text={marker.assigned_user.first_name + " " + marker.assigned_user.last_name}
                                                    reference={marker.reference}
                                                    selectedJob={marker}
                                                /> : null)
                                            )
                                                : null}

                                        </GoogleMap>

                                        : null
                                }
                            </div>
                        </Grid>
                        <Grid item md>
                                <Grid item md={12}>
                                    <CustomTable
                                        columns={columns}
                                        rows={mapJobs}
                                        onRowClick={onRowClick}
                                    />
                                </Grid>
                                {/* <Grid item md={12}>
                                    <CustomTable
                                        columns={columns}
                                        rows={mapJobs}
                                        onRowClick={onRowClick}
                                    />
                                </Grid> */}
                        </Grid>
                    </Grid>
                </Grid>
                <ViewEditJob
                    key={(selectedJob?.id || 0) + 1}
                    selectedJob={selectedJob}
                    type={'transport'}
                    open={isViewEditJobDialogOpen}
                    handleClose={handleOnViewEditJobDialogClose}
                    isInProgress={selectedJob?.status === IN_PROGRESS}
                    mode={'edit'}
                />
            </Grid>
        </>
    )
}

export default MapViewV2