'use client';

import { useMemo, useState, useEffect, useCallback } from 'react';
import { Box, Stack, Typography, Autocomplete, TextField } from '@mui/material';
import { Person as PersonIcon, DirectionsCar as CarIcon, LocationOn as LocationIcon } from '@mui/icons-material';
import TableControlBar from '@/shared/components/table/table-control-bar';
import { type TableConfig, useTableManager } from '@/hooks/use-table-manager';
import { type TabConfig, useTabsManager } from '@/hooks/use-tabs-manager';
import { TableType, TypeImport } from '@/shared/types/common';
import TabsCustom from '@/shared/components/tabs/tabs-custom';
import TableManager from '@/shared/components/table/table-manager';
import dynamic from 'next/dynamic';
import MapsControlBar from '@/shared/components/table/maps-control-bar';
import CustomDrawer from '@/shared/components/drawer/custom-drawer';
import {
  departements,
  _mockGeolocData,
  INITIAL_GEOLOC_DATA,
  DEFAULT_GEOLOC_TABLE_HEAD,
  vehiculeIds,
  vehicules,
} from '@/shared/_mock/_geolocData';
import { CircuitMap, MapType } from '@/shared/types/Maps';
import GeolocTableRow from './geoloc-table-row';
import { useBoolean } from '@/hooks';
import MassUploadFile from '@/shared/components/mass-import/mass-upload-file';
import GeolocDetailDialog from '../components/geoloc-detail-dialog';
import { IGeolocItem } from '@/shared/types/geoloc';
import { autoCompleteStyles, iconStyles, inputLabelProps, rootStyles, textFieldStyles, titleStyles } from '../styles';

const MapView = dynamic(() => import('@/shared/components/google-maps/maps'), {
  ssr: false,
});

const DRAWER_WIDTH = 680;

const geolocConfig: TableConfig<IGeolocItem> = {
  initialData: _mockGeolocData,
  defaultTableHead: DEFAULT_GEOLOC_TABLE_HEAD,
};

interface VehiclePositionsMap {
  [key: string]: {
    vehicleType: string;
    position: { lat: number; lng: number };
    rotation: number;
  };
}

export default function GeolocListView() {
  const uploadFile = useBoolean(false);
  const [vehiclePositions, setVehiclePositions] = useState<VehiclePositionsMap>({});
  const [directionsResponses, setDirectionsResponses] = useState<Record<string, google.maps.DirectionsResult>>({});
  const [isMapLoaded, setIsMapLoaded] = useState(false);
  const [selectedVehicule, setSelectedVehicule] = useState('');
  const [selectedChauffeur, setSelectedChauffeur] = useState('');
  const [selectedDepartement, setSelectedDepartement] = useState<string>('');
  const [isDrawerOpen, setIsDrawerOpen] = useState(false);
  const [isList, setIsList] = useState(true);
  const [isGeoloc] = useState(true);
  const [selectedGeolocItem, setSelectedGeolocItem] = useState<IGeolocItem | null>(null);
  const [isDetailDialogOpen, setIsDetailDialogOpen] = useState(false);

  const geolocTabsConfig: TabConfig<IGeolocItem> = {
    type: TableType.GEOLOC,
    listTitle: 'Suivi des véhicules',
    newItemTitle: 'Détail itinéraire',
    initialData: INITIAL_GEOLOC_DATA,
    getItemCode: (geoloc) => `${geoloc.prenomChauffeur} ${geoloc.nomChauffeur}`,
  };

  const {
    tabs,
    activeTab,
    handleTabClose,
    handleTabChange,
    handleTabAdd,
    handleEdit,
    handleView,
    handleCancel,
    handleCopy,
  } = useTabsManager<IGeolocItem>(geolocTabsConfig);

  const {
    table,
    filteredData,
    filters,
    tableHead,
    notFound,
    handleFilterChange,
    handleResetFilters,
    handleResetColumns,
    handleColumnsChange,
    handleSave,
  } = useTableManager<IGeolocItem>(geolocConfig);

  const chauffeurs = useMemo(() => 
    Array.from(new Set(_mockGeolocData
      .map(data => data.prenomChauffeur && data.nomChauffeur ? 
        `${data.prenomChauffeur} ${data.nomChauffeur}` : '')
      .filter(Boolean)
    )).sort()
  , []);

  const filteredRoutes = useMemo(() => {
    const routes = _mockGeolocData
      .filter((item) => item.routes && item.routes.length > 0)
      .flatMap((item) =>
        item.routes?.map((route) => ({
          ...route,
          departureDate: item.dateDepart,
          arrivalDate: item.dateArrivee,
          tolls: item.tolls || route.tolls,
          vehicule: item.vehicule,
          vehiculeId: item.vehiculeId,
          status: item.status,
          departement: item.departement,
          prenomChauffeur: item.prenomChauffeur,
          nomChauffeur: item.nomChauffeur,
          id: route.id || `route-${item.id}-${item.routes?.indexOf(route) || 0}`,
        }))
      );
    return routes;
  }, []);

  const handleMapLoaded = useCallback(() => {
    setIsMapLoaded(true);
  }, []);

  const handleVehiclePositionsUpdate = useCallback((positions: VehiclePositionsMap) => {
    setVehiclePositions(positions);
  }, []);

  const handleDirectionsUpdate = useCallback((responses: Record<string, google.maps.DirectionsResult>) => {
    setDirectionsResponses(responses);
  }, []);

  const handleViewList = useCallback(() => {
    setIsDrawerOpen(prev => !prev);
  }, []);

  const handleViewDetails = useCallback((item: IGeolocItem) => {
    setSelectedGeolocItem(item);
    setIsDetailDialogOpen(true);
  }, []);

  const handleCloseDetailDialog = useCallback(() => {
    setIsDetailDialogOpen(false);
    setSelectedGeolocItem(null);
  }, []);

  const applyAllFilters = useCallback((departement: string, vehicule: string, chauffeur: string) => {
    handleResetFilters();

    if (departement) {
      const deptCode = departement.split(' ')[0];
      handleFilterChange('departement', deptCode, 'equals');
    }

    if (vehicule) {
      if (vehicule.includes('VEH-')) {
        const vehicleId = vehicule.split(' - ')[0];
        handleFilterChange('vehiculeId', vehicleId, 'equals');
      } else {
        handleFilterChange('vehicule', vehicule, 'contains');
      }
    }

    if (chauffeur) {
      const parts = chauffeur.split(' ');
      if (parts.length >= 2) {
        const prenom = parts[0];
        const nom = parts.slice(1).join(' ');
        handleFilterChange('prenomChauffeur', prenom, 'equals');
        handleFilterChange('nomChauffeur', nom, 'equals');
      } else {
        handleFilterChange('prenomChauffeur', chauffeur, 'contains');
        handleFilterChange('nomChauffeur', chauffeur, 'contains');
      }
    }
  }, [handleResetFilters, handleFilterChange]);

  const handleDepartementChange = useCallback((dept: string | null) => {
    const deptCode = dept || '';
    setSelectedDepartement(deptCode);
    applyAllFilters(deptCode, selectedVehicule, selectedChauffeur);
  }, [selectedVehicule, selectedChauffeur, applyAllFilters]);

  const handleVehiculeChange = useCallback((vehiculeId: string) => {
    setSelectedVehicule(vehiculeId);
    applyAllFilters(selectedDepartement, vehiculeId, selectedChauffeur);
  }, [selectedDepartement, selectedChauffeur, applyAllFilters]);

  const handleChauffeurChange = useCallback((chauffeur: string) => {
    setSelectedChauffeur(chauffeur);
    applyAllFilters(selectedDepartement, selectedVehicule, chauffeur);
  }, [selectedDepartement, selectedVehicule, applyAllFilters]);

  useEffect(() => {
    if (!selectedDepartement && _mockGeolocData.length > 0) {
      const defaultDepartement = _mockGeolocData[0].departement || departements[0].code;
      setSelectedDepartement(defaultDepartement);
      handleDepartementChange(defaultDepartement);
    }
  }, [selectedDepartement, handleDepartementChange]);


  const renderRow = (row: IGeolocItem) => (
    <GeolocTableRow
      key={row.id}
      dense={table.dense}
      row={row}
      handleDetails={handleViewDetails}
      selected={table.selected.includes(row.id)}
      onSelectRow={() => table.onSelectRow(row.id)}
      columns={tableHead.slice(0, -1)}
      vehiclePositions={vehiclePositions}
    />
  );

  const renderFilters = useCallback(() => (
    <Stack
      direction={{ xs: 'column', sm: 'row' }}
      spacing={2}
      alignItems={{ xs: 'stretch', sm: 'center' }}
    >
      <Autocomplete
        freeSolo
        sx={autoCompleteStyles}
        options={chauffeurs}
        value={selectedChauffeur}
        onChange={(_, newValue) => handleChauffeurChange(newValue || '')}
        onInputChange={(_, newInputValue) => handleChauffeurChange(newInputValue || '')}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Chauffeur"
            size="small"
            InputLabelProps={inputLabelProps}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                <>
                  <PersonIcon sx={iconStyles} />
                  {params.InputProps.startAdornment}
                </>
              ),
            }}
            sx={textFieldStyles}
          />
        )}
      />

      <Autocomplete
        freeSolo
        sx={autoCompleteStyles}
        options={vehiculeIds.map((id, index) => `${id} - ${vehicules[index]}`)}
        value={
          selectedVehicule && vehiculeIds.includes(selectedVehicule)
            ? `${selectedVehicule} - ${vehicules[vehiculeIds.indexOf(selectedVehicule)]}`
            : selectedVehicule || ''
        }
        onChange={(_, newValue) => {
          const vehiculeId = newValue ? newValue.split(' - ')[0] : '';
          handleVehiculeChange(vehiculeId);
        }}
        onInputChange={(_, newInputValue) => {
          const vehiculeId = newInputValue ? newInputValue.split(' - ')[0] : '';
          handleVehiculeChange(vehiculeId);
        }}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Véhicule"
            size="small"
            InputLabelProps={inputLabelProps}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                <>
                  <CarIcon sx={iconStyles} />
                  {params.InputProps.startAdornment}
                </>
              ),
            }}
            sx={textFieldStyles}
          />
        )}
      />

      <Autocomplete
        freeSolo
        sx={autoCompleteStyles}
        options={departements.map((dept) => `${dept.code} - ${dept.nom}`)}
        value={
          selectedDepartement
            ? `${selectedDepartement} - ${
                departements.find((dept) => dept.code === selectedDepartement)?.nom || ''
              }`
            : ''
        }
        onChange={(_, newValue) => {
          const deptCode = newValue ? newValue.split(' - ')[0] : '';
          handleDepartementChange(deptCode);
        }}
        onInputChange={(_, newInputValue) => {
          const deptCode = newInputValue ? newInputValue.split(' - ')[0] : '';
          handleDepartementChange(deptCode);
        }}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Département"
            size="small"
            InputLabelProps={inputLabelProps}
            InputProps={{
              ...params.InputProps,
              startAdornment: (
                <>
                  <LocationIcon sx={iconStyles} />
                  {params.InputProps.startAdornment}
                </>
              ),
            }}
            sx={textFieldStyles}
          />
        )}
      />
    </Stack>
  ), [selectedChauffeur, selectedVehicule, selectedDepartement, handleChauffeurChange, handleVehiculeChange, handleDepartementChange, chauffeurs]);

  return (
    <Box sx={rootStyles(isDrawerOpen)}>
    
    <Stack
        flexGrow={0}
        direction="row"
        alignItems="center"
        justifyContent="flex-end"
        spacing={{ xs: 0.5, sm: 1 }}
      >

          <TableControlBar
            type={TableType.GEOLOC}
            activeTab={activeTab}
            onResetFilters={handleResetFilters}
            onResetColumns={handleResetColumns}
            onColumnsChange={handleColumnsChange}
            initialColumns={tableHead.slice(0, -1)}
            onFilters={(key, value) => handleFilterChange(key, value, 'contains')}
            filteredData={filteredData}
            withoutColumnSelector
            action={
              <MapsControlBar
                onImport={undefined}
                onAdd={undefined}
                onViewList={handleViewList}
                label={TableType.GEOLOC}
              />
            }
          />
        </Stack>

        {isList && (
          <Stack direction="row" justifyContent="space-between" >
            <Typography variant="h5" sx={titleStyles}>
              Suivi en temps réel des véhicules
            </Typography>
            {renderFilters()}
          </Stack>
        )}

        <TabsCustom
          type={TableType.GEOLOC}
          tabs={tabs}
          activeTab={activeTab}
          handleTabChange={handleTabChange}
          handleTabClose={handleTabClose}
        />

        {isList ? (
          <MapView
            sx={{ borderTopLeftRadius: 0 }}
            routes={filteredRoutes as CircuitMap[]}
            activeDepartement={selectedDepartement}
            onDepartementChange={handleDepartementChange}
            isGeoloc={isGeoloc}
            vehiclePositions={vehiclePositions}
            selectedVehicule={selectedVehicule}
            selectedChauffeur={selectedChauffeur}
            onVehiclePositionsUpdate={handleVehiclePositionsUpdate}
            onDirectionsUpdate={handleDirectionsUpdate}
            onMapLoaded={handleMapLoaded}
            Submodule={MapType.GEOLOC}
          />
        ) : (
          <div>Détail de l&apos;itinéraire</div>
        )}

        <CustomDrawer
          drawerWidth={DRAWER_WIDTH}
          open={isDrawerOpen}
          onClose={() => setIsDrawerOpen(false)}
        >
          <Typography variant="h5" sx={titleStyles}>
            Liste des véhicules en circulation
          </Typography>

          <TableManager
            filteredData={filteredData as IGeolocItem[]}
            table={table}
            tableHead={tableHead}
            notFound={notFound}
            filters={filters}
            onFilterChange={handleFilterChange}
            renderRow={renderRow}
            isDrawer
            sx={{ backgroundColor: 'primary.lighter', px: 0 }}
            fixedHeight="calc(100vh - 136px)"
          />
        </CustomDrawer>

        {selectedGeolocItem && (
          <GeolocDetailDialog
            open={isDetailDialogOpen}
            onClose={handleCloseDetailDialog}
            geolocItem={selectedGeolocItem}
          />
        )}

        {uploadFile.value && (
          <MassUploadFile
            open={uploadFile.value}
            onClose={uploadFile.onFalse}
            type={TypeImport.GEOLOC}
          />
        )}
  
    </Box>
  );
}
