import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Check, Copy, RotateCcw, X } from "lucide-react";
import {
  authInstance,
  devicesStore,
  Modal,
  snapshotStore,
  vehicleStore, // Not directly used in this component's rendering logic anymore
} from "@shared"; // Assuming @shared exports these
import { useEffect, useState } from "react";
import { observer } from "mobx-react-lite";
import { Button, Checkbox, Typography } from "@mui/material";
import { Vehicle } from "@shared";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";

export type ConnectedDevice = string;

interface Snapshot {
  ID: string; // Assuming ID is string based on usage
  Name: string;
  // Add other snapshot properties if needed
}

// --- HELPER FUNCTIONS ---
const formatDate = (dateString: string | null) => {
  if (!dateString) return "Нет данных";
  try {
    const date = new Date(dateString);
    return new Intl.DateTimeFormat("ru-RU", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit",
      hour12: false,
    }).format(date);
  } catch (error) {
    return "Некорректная дата";
  }
};

type TableRowData = {
  tail_number: number;
  online: boolean;
  lastUpdate: string | null;
  gps: boolean;
  media: boolean;
  connection: boolean;
  device_uuid: string | null;
};
function createData(
  tail_number: number,
  online: boolean,
  lastUpdate: string | null,
  gps: boolean,
  media: boolean,
  connection: boolean,
  device_uuid: string | null
): TableRowData {
  return {
    tail_number,
    online,
    lastUpdate,
    gps,
    media,
    connection,
    device_uuid,
  };
}

// This function transforms the raw device data (which includes vehicle and device_status)
// into the format expected by the table. It now filters for devices that have a UUID.
const transformDevicesToRows = (
  vehicles: Vehicle[]
  // devices: ConnectedDevice[]
): TableRowData[] => {
  return vehicles.map((vehicle) => {
    const uuid = vehicle.vehicle.uuid;
    if (!uuid)
      return {
        tail_number: vehicle.vehicle.tail_number,
        online: false,
        lastUpdate: null,
        gps: false,
        media: false,
        connection: false,
        device_uuid: null,
      };
    return createData(
      vehicle.vehicle.tail_number,
      vehicle.device_status?.online ?? false,
      vehicle.device_status?.last_update ?? null,
      vehicle.device_status?.gps_ok ?? false,
      vehicle.device_status?.media_service_ok ?? false,
      vehicle.device_status?.is_connected ?? false,
      uuid
    );
  });
};

export const DevicesTable = observer(() => {
  const {
    getDevices,
    setSelectedDevice,
    sendSnapshotModalOpen,
    toggleSendSnapshotModal,
  } = devicesStore;

  const { snapshots, getSnapshots } = snapshotStore;
  const { getVehicles, vehicles } = vehicleStore; // Removed as devicesStore.devices should be the source of truth
  const { devices } = devicesStore;
  const navigate = useNavigate();
  const [selectedDeviceUuids, setSelectedDeviceUuids] = useState<string[]>([]);

  // Transform the raw devices data into rows suitable for the table
  // This will also filter out devices without a UUID, as those cannot be acted upon.
  const currentTableRows = transformDevicesToRows(
    vehicles.data as Vehicle[]
    //  devices as ConnectedDevice[]
  );

  useEffect(() => {
    const fetchData = async () => {
      await getVehicles(); // Not strictly needed if devicesStore.devices is populated correctly by getDevices
      await getDevices(); // This should fetch the combined vehicle/device_status data
      await getSnapshots();
    };
    fetchData();
  }, [getDevices, getSnapshots]); // Added dependencies

  const isAllSelected =
    currentTableRows.length > 0 &&
    selectedDeviceUuids.length === currentTableRows.length;

  const handleSelectAllDevices = () => {
    if (isAllSelected) {
      setSelectedDeviceUuids([]);
    } else {
      // Select all device UUIDs from the *currently visible and selectable* rows
      setSelectedDeviceUuids(
        currentTableRows.map((row) => row.device_uuid ?? "")
      );
    }
  };

  const handleSelectDevice = (
    event: React.ChangeEvent<HTMLInputElement>,
    deviceUuid: string
  ) => {
    if (event.target.checked) {
      setSelectedDeviceUuids((prevSelected) => [...prevSelected, deviceUuid]);
    } else {
      setSelectedDeviceUuids((prevSelected) =>
        prevSelected.filter((uuid) => uuid !== deviceUuid)
      );
    }
  };

  const handleOpenSendSnapshotModal = () => {
    if (selectedDeviceUuids.length > 0) {
      toggleSendSnapshotModal();
    }
  };

  const handleReloadStatus = async (uuid: string) => {
    setSelectedDevice(uuid); // Sets the device in the store, useful for context elsewhere
    try {
      await authInstance.post(`/devices/${uuid}/request-status`);
      await getVehicles();
      await getDevices(); // Refresh devices to show updated status
    } catch (error) {
      console.error(`Error requesting status for device ${uuid}:`, error);
      // Optionally: show a user-facing error message
    }
  };

  const handleSendSnapshotAction = async (snapshotId: string) => {
    if (selectedDeviceUuids.length === 0) return;

    const send = async (deviceUuid: string) => {
      try {
        await authInstance.post(
          `/devices/${deviceUuid}/force-snapshot-update`,
          {
            snapshot_id: snapshotId,
          }
        );
        toast.success(`Снапшот отправлен на устройство `);
      } catch (error) {
        console.error(`Error sending snapshot to device ${deviceUuid}:`, error);
        toast.error(`Не удалось отправить снапшот на устройство`);
      }
    };
    try {
      // Create an array of promises for all snapshot requests
      const snapshotPromises = selectedDeviceUuids.map((deviceUuid) => {
        return send(deviceUuid);
      });

      // Wait for all promises to settle (either resolve or reject)
      await Promise.allSettled(snapshotPromises);

      // After all requests are attempted
      await getDevices(); // Refresh the device list
      setSelectedDeviceUuids([]); // Clear the selection
      toggleSendSnapshotModal(); // Close the modal
    } catch (error) {
      // This catch block might not be hit if Promise.allSettled is used,
      // as it doesn't reject on individual promise failures.
      // Individual errors should be handled if needed within the .map or by checking results.
      console.error("Error in snapshot sending process:", error);
    }
  };

  return (
    <>
      <TableContainer component={Paper} sx={{ mt: 2 }}>
        <div className="flex justify-end p-3 gap-2 ">
          <Button
            variant="contained"
            color="primary"
            size="small"
            onClick={() => navigate("/vehicle/create")}
          >
            Добавить устройство
          </Button>
        </div>
        <div className="flex justify-end p-3 gap-2">
          <Button
            variant="outlined" // Changed to outlined for distinction
            onClick={handleSelectAllDevices}
            size="small"
          >
            {isAllSelected ? "Снять выбор" : "Выбрать все"}
          </Button>
          <Button
            variant="contained"
            color="primary"
            disabled={selectedDeviceUuids.length === 0}
            onClick={handleOpenSendSnapshotModal}
            size="small"
          >
            Отправить снапшот ({selectedDeviceUuids.length})
          </Button>
        </div>
        <Table sx={{ minWidth: 650 }} aria-label="devices table" size="small">
          <TableHead>
            <TableRow>
              <TableCell padding="checkbox">
                <Checkbox
                  indeterminate={
                    selectedDeviceUuids.length > 0 &&
                    selectedDeviceUuids.length < currentTableRows.length
                  }
                  checked={isAllSelected}
                  onChange={handleSelectAllDevices}
                  inputProps={{ "aria-label": "select all devices" }}
                  size="small"
                />
              </TableCell>
              <TableCell align="center">Борт. номер</TableCell>
              <TableCell align="center">Онлайн</TableCell>
              <TableCell align="center">Обновлено</TableCell>
              <TableCell align="center">GPS</TableCell>
              <TableCell align="center">Медиа</TableCell>
              <TableCell align="center">Связь</TableCell>
              <TableCell align="center">Действия</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {currentTableRows.map((row) => (
              <TableRow
                key={row.tail_number}
                hover
                role="checkbox"
                aria-checked={selectedDeviceUuids.includes(
                  row.device_uuid ?? ""
                )}
                selected={selectedDeviceUuids.includes(row.device_uuid ?? "")}
                onClick={(event) => {
                  // Allow clicking row to toggle checkbox, if not clicking on button
                  if (
                    (event.target as HTMLElement).closest("button") === null &&
                    (event.target as HTMLElement).closest(
                      'input[type="checkbox"]'
                    ) === null
                  ) {
                    if (event.shiftKey) {
                      if (row.device_uuid) {
                        navigator.clipboard
                          .writeText(row.device_uuid)
                          .then(() => {
                            toast.success(`UUID скопирован`);
                          })
                          .catch(() => {
                            toast.error("Не удалось скопировать UUID");
                          });
                      } else {
                        toast.warning("Устройство не имеет UUID");
                      }
                    }

                    // Only toggle checkbox if Shift key is not pressed
                    if (!event.shiftKey) {
                      handleSelectDevice(
                        {
                          target: {
                            checked: !selectedDeviceUuids.includes(
                              row.device_uuid ?? ""
                            ),
                          },
                        } as React.ChangeEvent<HTMLInputElement>, // Simulate event
                        row.device_uuid ?? ""
                      );
                    }
                  }
                }}
                sx={{
                  cursor: "pointer",
                  "&:last-child td, &:last-child th": { border: 0 },
                }}
              >
                <TableCell padding="checkbox">
                  <Checkbox
                    checked={selectedDeviceUuids.includes(
                      row.device_uuid ?? ""
                    )}
                    onChange={(event) =>
                      handleSelectDevice(event, row.device_uuid ?? "")
                    }
                    size="small"
                  />
                </TableCell>
                <TableCell
                  align="center"
                  component="th"
                  scope="row"
                  id={`device-label-${row.device_uuid}`}
                >
                  {row.tail_number}
                </TableCell>
                <TableCell align="center">
                  <div className="flex items-center justify-center">
                    {row.online ? (
                      <Check size={18} className="text-green-600" />
                    ) : (
                      <X size={18} className="text-red-600" />
                    )}
                  </div>
                </TableCell>
                <TableCell align="center">
                  <div className="flex items-center justify-center">
                    {formatDate(row.lastUpdate)}
                  </div>
                </TableCell>
                <TableCell align="center">
                  <div className="flex items-center justify-center">
                    {row.gps ? (
                      <Check size={18} className="text-green-600" />
                    ) : (
                      <X size={18} className="text-red-600" />
                    )}
                  </div>
                </TableCell>
                <TableCell align="center">
                  <div className="flex items-center justify-center">
                    {row.media ? (
                      <Check size={18} className="text-green-600" />
                    ) : (
                      <X size={18} className="text-red-600" />
                    )}
                  </div>
                </TableCell>
                <TableCell align="center">
                  <div className="flex items-center justify-center">
                    {row.connection ? (
                      <Check size={18} className="text-green-600" />
                    ) : (
                      <X size={18} className="text-red-600" />
                    )}
                  </div>
                </TableCell>
                <TableCell align="center">
                  <Button
                    onClick={async (e) => {
                      e.stopPropagation();
                      try {
                        if (
                          row.device_uuid &&
                          devices.find((device) => device === row.device_uuid)
                        ) {
                          await handleReloadStatus(row.device_uuid);
                          toast.success("Статус устройства обновлен");
                        } else {
                          toast.error("Нет связи с устройством");
                        }
                      } catch (error) {
                        toast.error("Ошибка сервера");
                      }
                    }}
                    title="Перезапросить статус"
                    size="small"
                    variant="text"
                  >
                    <RotateCcw size={16} />
                  </Button>
                  <Button
                    onClick={() => {
                      navigator.clipboard.writeText(row.device_uuid ?? "");
                      toast.success("UUID скопирован");
                    }}
                  >
                    <Copy size={16} />
                  </Button>
                </TableCell>
              </TableRow>
            ))}
            {currentTableRows.length === 0 && (
              <TableRow>
                <TableCell colSpan={8} align="center">
                  Нет устройств для отображения.
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </TableContainer>

      <Modal open={sendSnapshotModalOpen} onClose={toggleSendSnapshotModal}>
        <Typography variant="h6" component="h2" sx={{ mb: 1 }}>
          Отправить снапшот
        </Typography>
        <Typography variant="body1" sx={{ mb: 2 }}>
          Выбрано устройств:{" "}
          <strong className="text-blue-600">
            {selectedDeviceUuids.length}
          </strong>
        </Typography>
        <div className="mt-2 flex flex-col gap-2 max-h-[300px] overflow-y-auto pr-2">
          {snapshots && (snapshots as Snapshot[]).length > 0 ? ( // Cast snapshots
            (snapshots as Snapshot[]).map((snapshot) => (
              <Button
                variant="outlined"
                fullWidth
                onClick={() => handleSendSnapshotAction(snapshot.ID)}
                key={snapshot.ID}
                sx={{ justifyContent: "flex-start" }}
              >
                {snapshot.Name}
              </Button>
            ))
          ) : (
            <Typography variant="body2" color="textSecondary">
              Нет доступных снапшотов.
            </Typography>
          )}
        </div>
        <Button
          onClick={toggleSendSnapshotModal}
          color="inherit"
          variant="outlined"
          sx={{ mt: 3 }}
          fullWidth
        >
          Отмена
        </Button>
      </Modal>
    </>
  );
});
