'use client';

import { useCallback, useMemo, useRef, useState } from 'react';
import { IMapState } from 'yandex-maps';

import Camera from '@/components/Camera';
import CameraGrid from '@/components/CameraGrid';
import Map from '@/components/Map';
import { Container } from '@/components/UI/Container';
import Vehicle from '@/components/Map/Vehicle';
import { useVehicleList } from '@/queries/map';
import type { ICameraItem } from '@/interfaces/camera';
import { useGetUserVehicleExForIndex } from '@/queries/records';
import { StandardVehicle } from '@/classes/StandardVehicle';
import FullWindowComponentContextProvider from '@/contexts/FullWindowComponentContext';
import type { IVehicle } from '@/types/IVehicle';
import MonitoringCard from './components/MonitoringCard';

import TablesCard from './components/TablesCard';

export const DashboardOnline = () => {
  const [selectedVehicles, setSelectedVehicles] = useState<IVehicle['id'][]>([]);
  const [stateMap, setStateMap] = useState<IMapState>();
  const mapRef = useRef<HTMLDivElement>(null);
  const [cameras, setCameras] = useState<Array<ICameraItem | undefined>>([]);
  const list = useVehicleList();

  const userVehicleEx = useGetUserVehicleExForIndex();

  const AllVehicles = useMemo(() => {
    return userVehicleEx.data?.vehicles.map((info) => new StandardVehicle(info as any));
  }, [userVehicleEx.data?.vehicles]);

  const selectedVehiclesList = useMemo(() => {
    return AllVehicles?.filter((el) => selectedVehicles.includes(el.getID())) || [];
  }, [AllVehicles, selectedVehicles]);

  const vehicles = useMemo((): IVehicle[] => {
    return list.data?.vehicles?.filter((vehicle) => selectedVehicles.includes(vehicle.id)) || [];
  }, [list.data, selectedVehicles]);

  const handleOpenCamera = useCallback((data: any) => {
    setCameras((prev) => {
      const includes = prev.some(
        (el) => el?.Channel === data.chnName && el?.DevIDNO === data.vehID,
      );
      if (includes) {
        const index = prev.findIndex(
          (el) => el?.Channel === data.chnName && el?.DevIDNO === data.vehID,
        );

        const next = [...prev];
        next[index] = undefined;
        return next;
      } else {
        const emptyIndex = prev.findIndex((el) => !el);
        const newIndex = emptyIndex === -1 ? prev.length : emptyIndex;

        const next = [...prev];
        next[newIndex] = {
          DevIDNO: data.vehID,
          Channel: data.chnName,
        };
        return next;
      }
    });
  }, []);

  return (
    <Container as='section'>
      <FullWindowComponentContextProvider>
        <div className='w-full gap-6 grid grid-cols-[430px,calc(100%-454px)]'>
          <MonitoringCard
            selectedVehicles={selectedVehicles}
            setSelectedVehicles={setSelectedVehicles}
            handleOpenCamera={handleOpenCamera}
            cameras={cameras.filter((el) => !!el) as ICameraItem[]}
          />

          <div className='flex flex-col gap-6 w-full'>
            <div className='grid grid-cols-[2fr,1fr] gap-6'>
              <div className='h-[604px]'>
                <CameraGrid size={3} handleOpenCamera={handleOpenCamera}>
                  {cameras.map((cam, index) =>
                    !cam ? (
                      <div key={index} />
                    ) : (
                      <Camera key={index} deviceID={cam.DevIDNO} chnID={cam.Channel} />
                    ),
                  )}
                </CameraGrid>
              </div>

              <Map
                state={stateMap}
                ref={mapRef}
                className='h-full w-full overflow-hidden rounded-lg'
              >
                {vehicles.map((el) => (
                  <Vehicle key={el.id} data={el} mapRef={mapRef} setStateMap={setStateMap} />
                ))}
              </Map>
            </div>

            <TablesCard companies={list.data?.companys || []} vehicles={selectedVehiclesList} />
          </div>
        </div>
      </FullWindowComponentContextProvider>
    </Container>
  );
};
