import "@mantine/core/styles.css";
import "@mantine/dates/styles.css";
import "@mantine/notifications/styles.css";
import "./App.css";
import classes from "./App.module.css";
import componentClasses from "./components/Component.module.css";

import {
  Suspense,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import {
  Tabs,
  Text,
  Container,
  Flex,
  MantineProvider,
  Grid,
  ScrollArea,
  LoadingOverlay,
  Loader,
  Box,
} from "@mantine/core";
import type {
  DataSummaryTested,
  FileInfo,
  IScenario,
  ReceivedFile,
  ResponseData,
  TBrands,
  TCategories,
  TLine,
  TStation,
  TUser,
} from "./untils/types";
import axios from "axios";
import CardLine from "./components/CardLine";
import { SocketProvider, useSocket } from "./context/SocketContext";
import // ButtonConnect,
// ButtonControlApc,
// ButtonCopy,
// ButtonDPELP,
// ButtonScenario,
// ButtonSelect,
"./components/ButtonAction";
import StationSetting from "./components/FormAddEdit";
// import DrawerScenario from "./components/DrawerScenario";
import { Notifications } from "@mantine/notifications";
import ModalTerminal from "./components/Modal/ModalTerminal";
import PageLogin from "./components/Authentication/LoginPage";
// import DrawerLogs from "./components/DrawerLogs";
import DraggableTabs from "./components/DragTabs";
import { isJsonString } from "./untils/helper";
import BottomToolBar from "./components/BottomToolBar";
import ModalConfirmSkipTestPort from "./components/Modal/ModalConfirmSkipTestPort";
import ModalConfirmRunPhysical from "./components/Modal/ModalConfirmRunPhysicalTest";
import ModalSummaryTested from "./components/Modal/ModalSummaryTested";
// import ModalConfirmRunScenario from "./components/Modal/ModalConfirmRunScenario";

const apiUrl = import.meta.env.VITE_BACKEND_URL;

// Helper: chia mảng thành các chunk theo size
const chunkArray = <T,>(array: T[], size: number): T[][] => {
  const result: T[][] = [];
  for (let i = 0; i < array.length; i += size) {
    result.push(array.slice(i, i + size));
  }
  return result;
};

/**
 * Main Component
 */
function App() {
  const user = useMemo(() => {
    return localStorage.getItem("user") &&
      isJsonString(localStorage.getItem("user"))
      ? JSON.parse(localStorage.getItem("user") || "")
      : null;
  }, []);

  if (!user) {
    localStorage.removeItem("user");
    window.location.href = "/";
  }

  document.title = "Automation Test";
  const { socket } = useSocket();
  const [stations, setStations] = useState<TStation[]>([]);
  const [selectedLines, setSelectedLines] = useState<TLine[]>([]);
  const [activeTab, setActiveTab] = useState("0");
  const [isDisable, setIsDisable] = useState(false);
  const [isOpenAddStation, setIsOpenAddStation] = useState(false);
  const [isEditStation, setIsEditStation] = useState(false);
  const [stationEdit, setStationEdit] = useState<TStation | undefined>();
  const [scenarios, setScenarios] = useState<IScenario[]>([]);
  const [openModalTerminal, setOpenModalTerminal] = useState(false);
  const [selectedLine, setSelectedLine] = useState<TLine | undefined>();
  const [loadingTerminal, setLoadingTerminal] = useState(false);
  const [usersConnecting, setUsersConnecting] = useState<TUser[]>([]);
  const [testLogContent, setTestLogContent] = useState("");
  const [isLogModalOpen, setIsLogModalOpen] = useState(false);
  const [expandedBottomBar, setExpandedBottomBar] = useState(true);
  const [activeTabBottom, setActiveTabBottom] = useState<string>("command");
  const lineBuffersRef = useRef(new Map<number, string>());
  const flushScheduledRef = useRef(false);
  const [listBrands, setListBrands] = useState<TBrands[]>([]);
  const [listCategories, setListCategories] = useState<TCategories[]>([]);
  const [listIos, setListIos] = useState<FileInfo[]>([]);
  const [listLicense, setListLicense] = useState<FileInfo[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [linesConfirmSkipPort, setLinesConfirmSkipPort] = useState<TLine[]>([]);
  const [linesConfirmRunPhysical, setLinesConfirmRunPhysical] = useState<
    TLine[]
  >([]);
  const [dataSummaryTested, setDataSummaryTested] =
    useState<DataSummaryTested | null>(null);

  const connectApcSwitch = (station: TStation) => {
    if (!station?.is_active) return;
    if (station?.apc_1_ip && station?.apc_1_port) {
      socket?.emit("connect_apc", {
        station: station,
        apcIp: station?.apc_1_ip,
        apcName: "apc_1",
      });
    }
    if (station?.apc_2_ip && station?.apc_2_port) {
      socket?.emit("connect_apc", {
        station: station,
        apcIp: station?.apc_2_ip,
        apcName: "apc_2",
      });
    }
    if (station?.switch_control_ip && station?.switch_control_port) {
      socket?.emit("connect_switch", {
        station: station,
        ip: station?.switch_control_ip,
      });
    }
  };

  // function get list station
  const getStation = async () => {
    try {
      const response = await axios.get(apiUrl + "api/stations");
      if (response.status) {
        if (Array.isArray(response.data)) {
          setStations(
            response.data.map((station) => {
              connectApcSwitch(station);
              const lines = (station?.lines || []).sort(
                (a: TLine, b: TLine) => a?.lineNumber - b?.lineNumber,
              );
              return { ...station, lines };
            }),
          );
        }
      }
    } catch (error) {
      console.log("Error get station", error);
    }
  };

  // function get list station
  const getScenarios = async () => {
    try {
      const response = await axios.get(apiUrl + "api/scenarios");
      if (response.data.status) {
        if (Array.isArray(response.data.data.data)) {
          setScenarios(response.data.data.data);
        }
      }
    } catch (error) {
      console.log("Error get station", error);
    }
  };

  // function get list brand
  const getBrands = async () => {
    try {
      const response = await axios.get(apiUrl + "api/brands");
      if (response.data) {
        if (response.data && Array.isArray(response.data)) {
          setListBrands(response.data);
        }
      }
    } catch (error) {
      console.log("Error get brand", error);
    }
  };

  // function get list brand
  const getCategories = async () => {
    try {
      const response = await axios.get(apiUrl + "api/categories");
      if (response.data && Array.isArray(response.data)) {
        setListCategories(response.data);
      }
    } catch (error) {
      console.log("Error get brand", error);
    }
  };

  // function get list ios
  const getListIos = async () => {
    try {
      const response = await axios.get(apiUrl + "api/ios");
      if (response.data && Array.isArray(response.data)) {
        setListIos(response.data);
      }
    } catch (error) {
      console.log("Error get ios", error);
    }
  };

  // function get list license
  const getListLicense = async () => {
    try {
      const response = await axios.get(apiUrl + "api/license");
      if (response.data && Array.isArray(response.data)) {
        setListLicense(response.data);
      }
    } catch (error) {
      console.log("Error get ios", error);
    }
  };

  useEffect(() => {
    if (!socket) return;
    getStation();
    getScenarios();
    getBrands();
    getCategories();
    getListIos();
    getListLicense();
  }, [socket]);

  useEffect(() => {
    setTimeout(() => {
      setIsLoading(false);
    }, 2000);
  }, []);

  useEffect(() => {
    if (!socket || !stations?.length) return;

    socket.on("line_connected", (data) =>
      updateValueLineStation(
        data?.lineId,
        { status: data.status, connecting: false },
        data?.stationId,
      ),
    );

    socket.on("line_disconnected", (data) =>
      updateValueLineStation(
        data?.lineId,
        {
          status: data.status,
          connecting: false,
          netOutput: "[CLEAR_TERMINAL_SCROLL_BACK]",
          output: "[CLEAR_TERMINAL_SCROLL_BACK]",
          listFeatureTested: [],
          latestScenario: undefined,
          isReady: false,
        },
        data?.stationId,
      ),
    );

    socket?.on("line_output", (data) => {
      const { lineId, data: text } = data;
      // updateValueLineStation(
      //   data?.lineId,
      //   { isReady: data.isReady },
      //   data?.stationId
      // );

      const buf = lineBuffersRef.current.get(lineId) || "";
      lineBuffersRef.current.set(lineId, buf + text);

      if (!flushScheduledRef.current) {
        flushScheduledRef.current = true;
        setTimeout(() => flushBuffers(), 50);
      }
    });

    socket?.on("update_status_ready", (data) => {
      const { isReady } = data;
      updateValueLineStation(
        data?.lineId,
        { isReady: isReady },
        data?.stationId,
      );
    });

    socket?.on("line_error", (data) => {
      updateValueLineStation(
        data?.lineId,
        { netOutput: data.error, connecting: false },
        data?.stationId,
      );
    });

    socket?.on("init", (data) => {
      if (Array.isArray(data)) {
        // console.log(data);
        setLoadingTerminal(true);
        data.forEach((value) => {
          updateValueLineStation(
            value?.id,
            { ...value, netOutput: value.output },
            value?.stationId,
          );
        });
      }
    });

    socket?.on("user_connecting", (data) => {
      if (Array.isArray(data)) {
        setUsersConnecting(data);
      }
    });

    socket?.on("user_open_cli", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data.lineId,
          {
            cliOpened: true,
            userEmailOpenCLI: data.userEmailOpenCLI,
            userOpenCLI: data.userOpenCLI,
          },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("user_close_cli", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data.lineId,
          {
            cliOpened: false,
            userEmailOpenCLI: undefined,
            userOpenCLI: undefined,
          },
          data?.stationId,
        );
      }, 100);
    });

    const receivedFiles: Record<string, ReceivedFile> = {};
    socket?.on("response_content_log", (data: ResponseData) => {
      if (!data.chunk) {
        const decoder = new TextDecoder("utf-8");
        const str = decoder.decode(data as unknown as ArrayBuffer);
        setTestLogContent(str);
        return;
      }

      const { fileId, chunkIndex, totalChunks, chunk } = data.chunk;

      if (!receivedFiles[fileId]) {
        receivedFiles[fileId] = {
          chunks: [],
          receivedChunks: 0,
          totalChunks,
        };
      }

      let bufferChunk: Buffer;

      if (chunk instanceof ArrayBuffer) {
        bufferChunk = Buffer.from(new Uint8Array(chunk)); // ✅ convert properly
      } else if (chunk instanceof Uint8Array) {
        bufferChunk = Buffer.from(chunk); // ✅ direct support
      } else {
        bufferChunk = chunk as Buffer; // fallback if server sends Buffer
      }

      receivedFiles[fileId].chunks[chunkIndex] = bufferChunk;
      receivedFiles[fileId].receivedChunks++;

      if (receivedFiles[fileId].receivedChunks === totalChunks) {
        const fileBuffer = Buffer.concat(receivedFiles[fileId].chunks);
        const decoder = new TextDecoder("utf-8");
        const str = decoder.decode(fileBuffer);

        setTestLogContent(str);
        delete receivedFiles[fileId]; // cleanup ✅
      }
    });

    socket?.on("data_textfsm", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data.lineId,
          {
            data: data.data,
            inventory: data.inventory,
            latestScenario: data.latestScenario,
          },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("update_ticket", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data.lineId,
          {
            tickets: data.data,
          },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("update_baud", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data.lineId,
          {
            baud: data.data,
          },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("line_connecting", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data?.lineId,
          { connecting: true },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("running_scenario", (data) => {
      setTimeout(() => {
        updateValueLineStation(
          data?.lineId,
          {
            runningScenario: data?.title || "",
            runningPhysical: data?.physical || false,
            ports: data?.ports || [],
            listPortsPhysical: [],
          },
          data?.stationId,
        );
      }, 100);
    });

    socket?.on("user_clear_terminal", (data) => {
      updateValueLineStation(
        data?.lineId,
        { netOutput: "", output: "", loadingClearTerminal: true },
        data?.stationId,
      );
    });

    socket?.on("test_port_physical", (data) => {
      if (data?.data && data?.data.length > 0)
        updateValueLineStation(
          data?.lineId,
          { listPortsPhysical: data?.data },
          data?.stationId,
        );
    });

    socket?.on("feature_tested", (data) => {
      if (data?.listFeatureTested) {
        updateValueLineStation(
          data?.lineId,
          {
            listFeatureTested: data?.listFeatureTested,
            isSkipPhysical: data?.isSkipPhysical,
            reasonSkipPhysical: data?.reasonSkipPhysical,
          },
          data?.stationId,
        );
        if (data?.isSkipPhysical && !data?.reasonSkipPhysical) {
          const valueLine = findLineByLineId(data?.lineId, data?.stationId);
          if (
            valueLine &&
            openModalTerminal &&
            selectedLine?.id === valueLine?.id &&
            (!valueLine?.listPortsPhysical ||
              valueLine?.listPortsPhysical?.length === 0)
          )
            setLinesConfirmSkipPort((pre) => [
              ...pre,
              {
                ...valueLine,
                inventory: {
                  ...valueLine.inventory,
                  pid: data?.pid,
                  sn: data?.sn,
                  vid: data?.vid,
                },
              },
            ]);
        }
        if (
          !data?.listFeatureTested?.includes("PHYSICAL") &&
          data?.listFeatureTested?.includes("DPELP")
        ) {
          const valueLine = findLineByLineId(data?.lineId, data?.stationId);
          if (
            valueLine &&
            openModalTerminal &&
            selectedLine?.id === valueLine?.id
          )
            setLinesConfirmRunPhysical((pre) => [
              ...pre,
              {
                ...valueLine,
                inventory: {
                  ...valueLine.inventory,
                  pid: data?.pid,
                  sn: data?.sn,
                  vid: data?.vid,
                },
              },
            ]);
        }
      }
    });

    socket?.on("summary_tested", (data) => {
      if (
        data?.body &&
        openModalTerminal &&
        selectedLine?.id === data?.lineId
      ) {
        setDataSummaryTested({
          body: data?.body || "",
          title: data?.title || "",
        });
      }
    });

    // ✅ cleanup on unmount or when socket changes
    return () => {
      socket.off("init");
      socket.off("line_output");
      socket.off("line_error");
      socket.off("line_connected");
      socket.off("line_disconnected");
      socket.off("user_connecting");
      socket.off("user_open_cli");
      socket.off("user_close_cli");
      socket.off("response_content_log");
      socket.off("data_textfsm");
      socket.off("update_ticket");
      socket.off("update_baud");
      socket.off("line_connecting");
      socket.off("running_scenario");
      socket.off("user_clear_terminal");
      socket.off("test_port_physical");
      socket.off("feature_tested");
      socket.off("summary_tested");
    };
  }, [socket, stations, selectedLine]);

  const flushBuffers = useCallback(() => {
    setStations((prev) =>
      prev.map((station) => ({
        ...station,
        lines: station.lines.map((line) => {
          const buffered = lineBuffersRef.current.get(line.id || 0);
          if (!buffered) return line; // không có update
          const data = {
            ...line,
            netOutput: (line.netOutput || "") + buffered,
            output: buffered,
            loadingOutput: line.loadingOutput ? false : true,
            loadingClearTerminal: false,
          };
          updateValueSelectedLine(line?.id || 0, data);
          return data;
        }),
      })),
    );
    // clear
    lineBuffersRef.current.clear();
    flushScheduledRef.current = false;
  }, []);

  const updateValueLineStation = useCallback(
    (lineId: number, updates: Partial<TLine>, stationId?: number) => {
      setStations((prevStations) =>
        prevStations?.map((station: TStation) =>
          station.id === stationId
            ? {
                ...station,
                lines: station.lines?.map((lineItem: TLine) => {
                  if (lineItem.id !== lineId) return lineItem;

                  const isNetOutput = typeof updates?.netOutput !== "undefined";

                  return {
                    ...lineItem,
                    ...updates,
                    lineNumber: lineItem.lineNumber,
                    line_number: lineItem.line_number,
                    ports:
                      updates?.ports && updates?.ports?.length > 0
                        ? updates?.ports
                        : lineItem.ports || [],
                    ...(isNetOutput && {
                      netOutput: updates?.loadingClearTerminal
                        ? ""
                        : (lineItem.netOutput || "") +
                          (updates.netOutput || ""),
                      output: updates.netOutput, // Nếu netOutput thì update luôn output
                      loadingOutput: lineItem.loadingOutput ? false : true,
                      loadingClearTerminal: updates?.loadingClearTerminal
                        ? updates?.loadingClearTerminal
                        : false,
                    }),
                  };
                }),
              }
            : station,
        ),
      );

      // Update selectedLine nếu nó đang được chọn
      setSelectedLine((prevSelected) => {
        if (!prevSelected || prevSelected.id !== lineId) return prevSelected;

        const isNetOutput = typeof updates?.netOutput !== "undefined";

        return {
          ...prevSelected,
          ...updates,
          ports:
            updates?.ports && updates?.ports?.length > 0
              ? updates?.ports
              : prevSelected.ports || [],
          ...(isNetOutput && {
            netOutput: updates?.loadingClearTerminal
              ? ""
              : (prevSelected.netOutput || "") + (updates.netOutput || ""),
            output: updates.netOutput,
            loadingOutput: prevSelected.loadingOutput ? false : true,
            loadingClearTerminal: updates?.loadingClearTerminal
              ? updates?.loadingClearTerminal
              : false,
          }),
        };
      });

      updateValueSelectedLines(lineId, updates);
    },
    [],
  );

  const updateValueSelectedLines = (
    lineId: number,
    updates: Partial<TLine>,
  ) => {
    // Update selectedLine nếu nó đang được chọn
    setSelectedLines((prevSelected) =>
      prevSelected?.map((line) => {
        if (line.id === lineId) {
          return { ...line, ...updates };
        }
        return line;
      }),
    );
  };

  const updateValueSelectedLine = (lineId: number, updates: Partial<TLine>) => {
    // Update selectedLine nếu nó đang được chọn
    setSelectedLine((prevSelected) => {
      if (!prevSelected || prevSelected.id !== lineId) return prevSelected;
      return {
        ...prevSelected,
        ...updates,
      };
    });
  };

  // const getLine = (lineId: number, stationId: number) => {
  //   const station = stations?.find((sta) => sta.id === stationId);
  //   if (station) {
  //     const line = station.lines?.find((li) => li.id === lineId);
  //     return line;
  //   } else return null;
  // };

  const openTerminal = (line: TLine) => {
    setOpenModalTerminal(true);
    const data = { ...line };
    if (!line.userOpenCLI) {
      data.cliOpened = true;
      data.userEmailOpenCLI = user?.email;
      data.userOpenCLI = user?.userName;
      socket?.emit("open_cli", {
        lineId: line.id,
        stationId: line.stationId || line.station_id,
        userEmail: user?.email,
        userName: user?.userName,
      });
    }
    setSelectedLine(data);
  };

  useEffect(() => {
    if (!expandedBottomBar) {
      setActiveTabBottom("command");
    }
  }, [expandedBottomBar]);

  const findLineByLineId = (lineId: number, stationId?: number) => {
    const valueStation = stations.find((el) => el.id === stationId);
    if (!valueStation || !stationId) return null;
    const valueLine = valueStation?.lines?.find((el) => el.id === lineId);
    return valueLine;
  };

  return (
    <Container w={"100%"} style={{ maxWidth: "100%" }}>
      <DraggableTabs
        socket={socket}
        usersConnecting={usersConnecting}
        setIsEditStation={setIsEditStation}
        setIsOpenAddStation={setIsOpenAddStation}
        setStationEdit={setStationEdit}
        tabsData={stations}
        scenarios={scenarios}
        setScenarios={setScenarios}
        panels={stations.map((station) => (
          <Tabs.Panel
            className={classes.content}
            key={station.id}
            value={station.id.toString()}
            pt="md"
          >
            <Flex className={classes.containerMain}>
              <Grid>
                <Grid.Col
                  span={12}
                  style={{
                    borderRadius: 8,
                  }}
                >
                  <ScrollArea
                    // h={expandedBottomBar ? "80vh" : "85vh"}
                    h={expandedBottomBar ? "73vh" : "83vh"}
                    type="scroll"
                    scrollbars="y"
                    style={{ overflowX: "hidden" }}
                    className={componentClasses.hideScrollBar}
                  >
                    {isLoading ? (
                      <Box
                        style={{
                          height: "15vh",
                          width: "100%",
                          display: "flex",
                          justifyContent: "center",
                          alignItems: "center",
                        }}
                      >
                        <Loader color="blue" />
                      </Box>
                    ) : station.lines.length > 0 ? (
                      station.lines.length < 9 ? (
                        <Grid
                          gutter="md"
                          style={{
                            margin: 0,
                            width: "100%",
                          }}
                        >
                          {station.lines.map((line, i) => (
                            <Grid.Col
                              key={line.id ?? i}
                              span={3}
                              style={{
                                display: "flex",
                                height: "100%",
                                maxWidth: "100%",
                                overflow: "hidden",
                              }}
                            >
                              <CardLine
                                socket={socket}
                                stationItem={station}
                                line={line}
                                selectedLines={selectedLines}
                                setSelectedLines={setSelectedLines}
                                openTerminal={openTerminal}
                                loadTerminal={
                                  loadingTerminal &&
                                  Number(station.id) === Number(activeTab)
                                }
                                scenarios={scenarios}
                              />
                            </Grid.Col>
                          ))}
                        </Grid>
                      ) : (
                        // >= 9 lines: chia làm 2 cột, mỗi cột chứa 1/2 số line,
                        // mỗi cột hiển thị 2 item trên một "hàng" như ví dụ yêu cầu
                        (() => {
                          // const total = station.lines.length;
                          const half = 8;
                          const leftLines = station.lines.slice(0, half);
                          const rightLines = station.lines.slice(half);

                          const leftChunks = chunkArray(leftLines, 2);
                          const rightChunks = chunkArray(rightLines, 2);
                          const numRows = Math.max(
                            leftChunks.length,
                            rightChunks.length,
                          );

                          return (
                            <>
                              {Array.from({ length: numRows }).map(
                                (_, rowIndex) => {
                                  const leftRow = leftChunks[rowIndex] || [];
                                  const rightRow = rightChunks[rowIndex] || [];

                                  return (
                                    <Grid
                                      key={rowIndex}
                                      gutter="md"
                                      style={{
                                        margin: 0,
                                        width: "100%",
                                      }}
                                    >
                                      {/* Cột A */}
                                      <Grid.Col span={6}>
                                        <Grid gutter="md">
                                          {leftRow.map((line, i) => (
                                            <Grid.Col
                                              key={
                                                line.id ?? `L-${rowIndex}-${i}`
                                              }
                                              span={6}
                                              style={{
                                                display: "flex",
                                                height: "100%",
                                                maxWidth: "100%",
                                                overflow: "hidden",
                                              }}
                                            >
                                              <CardLine
                                                socket={socket}
                                                stationItem={station}
                                                line={line}
                                                selectedLines={selectedLines}
                                                setSelectedLines={
                                                  setSelectedLines
                                                }
                                                openTerminal={openTerminal}
                                                loadTerminal={
                                                  loadingTerminal &&
                                                  Number(station.id) ===
                                                    Number(activeTab)
                                                }
                                                scenarios={scenarios}
                                              />
                                            </Grid.Col>
                                          ))}
                                        </Grid>
                                      </Grid.Col>

                                      {/* Cột B */}
                                      <Grid.Col span={6}>
                                        <Grid gutter="md">
                                          {rightRow.map((line, i) => (
                                            <Grid.Col
                                              key={
                                                line.id ?? `R-${rowIndex}-${i}`
                                              }
                                              span={6}
                                              style={{
                                                display: "flex",
                                                height: "100%",
                                                maxWidth: "100%",
                                                overflow: "hidden",
                                              }}
                                            >
                                              <CardLine
                                                socket={socket}
                                                stationItem={station}
                                                line={line}
                                                selectedLines={selectedLines}
                                                setSelectedLines={
                                                  setSelectedLines
                                                }
                                                openTerminal={openTerminal}
                                                loadTerminal={
                                                  loadingTerminal &&
                                                  Number(station.id) ===
                                                    Number(activeTab)
                                                }
                                                scenarios={scenarios}
                                              />
                                            </Grid.Col>
                                          ))}
                                        </Grid>
                                      </Grid.Col>
                                    </Grid>
                                  );
                                },
                              )}
                            </>
                          );
                        })()
                      )
                    ) : (
                      <Text ta="center" c="dimmed" mt="lg">
                        No lines configured
                      </Text>
                    )}
                  </ScrollArea>
                </Grid.Col>
              </Grid>
              <BottomToolBar
                selectedLines={selectedLines}
                socket={socket}
                setSelectedLines={setSelectedLines}
                isDisable={isDisable}
                setIsDisable={setIsDisable}
                station={station}
                stationId={Number(activeTab)}
                testLogContent={testLogContent}
                isLogModalOpen={isLogModalOpen}
                setIsLogModalOpen={setIsLogModalOpen}
                setTestLogContent={setTestLogContent}
                scenarios={scenarios}
                setScenarios={setScenarios}
                setExpanded={setExpandedBottomBar}
                activeTabBottom={activeTabBottom}
                setActiveTabBottom={setActiveTabBottom}
                isExpand={expandedBottomBar}
                listBrands={listBrands}
                listCategories={listCategories}
              />
            </Flex>
          </Tabs.Panel>
        ))}
        onChange={(id) => {
          const station = stations.find((el) => el.id === Number(activeTab));
          if (station) {
            (station?.lines || [])?.forEach((el) => {
              if (el?.userOpenCLI === user?.userName)
                socket?.emit("close_cli", {
                  lineId: el?.id,
                  stationId: Number(activeTab),
                });
            });
          }
          setActiveTab(id?.toString() || "0");
          setSelectedLines([]);
          setLoadingTerminal(false);
          setTimeout(() => {
            setLoadingTerminal(true);
          }, 500);
        }}
        setActive={setActiveTab}
        active={activeTab}
        onSendCommand={(value) => {
          const listLine = selectedLines.length
            ? selectedLines
            : stations.find((el) => el.id === Number(activeTab))?.lines;
          if (listLine?.length) {
            socket?.emit("write_command_line_from_web", {
              lineIds: listLine.map((line) => line.id),
              stationId: Number(activeTab),
              command: value + "\n",
            });
            setTimeout(() => {
              socket?.emit("write_command_line_from_web", {
                lineIds: listLine.map((line) => line.id),
                stationId: Number(activeTab),
                command: "     \n",
              });
            }, 1000);
          }
        }}
        listBrands={listBrands}
        listCategories={listCategories}
      />

      <StationSetting
        dataStation={stationEdit}
        isOpen={isOpenAddStation}
        onClose={() => {
          setIsOpenAddStation(false);
          setIsEditStation(false);
          setStationEdit(undefined);
        }}
        isEdit={isEditStation}
        setStations={setStations}
        setActiveTab={(id: string) => {
          setActiveTab(id);
          setLoadingTerminal(false);
          setTimeout(() => {
            setLoadingTerminal(true);
          }, 100);
        }}
        stations={stations}
        socket={socket}
      />

      <ModalTerminal
        selectedLines={selectedLines}
        opened={openModalTerminal}
        onClose={() => {
          setOpenModalTerminal(false);
          setSelectedLine(undefined);
        }}
        line={selectedLine}
        socket={socket}
        stationItem={stations.find((el) => el.id === Number(activeTab))}
        scenarios={scenarios}
        listIos={listIos}
        listLicense={listLicense}
        getListIos={getListIos}
        getListLicense={getListLicense}
        setScenarios={setScenarios}
        listBrands={listBrands}
        listCategories={listCategories}
        setLinesConfirmSkipPort={setLinesConfirmSkipPort}
        linesConfirmSkipPort={linesConfirmSkipPort}
        dataSummaryTested={dataSummaryTested}
      />

      {/* <ModalConfirmRunScenario
        socket={socket}
        station={stations.find((el) => el.id === Number(activeTab))}
        scenarios={scenarios}
      /> */}

      <ModalConfirmSkipTestPort
        listLines={linesConfirmSkipPort}
        setListLines={setLinesConfirmSkipPort}
        socket={socket}
        station={stations.find((el) => el.id === Number(activeTab))}
      />

      <ModalConfirmRunPhysical
        listLines={linesConfirmRunPhysical}
        setListLines={setLinesConfirmRunPhysical}
        socket={socket}
        station={stations.find((el) => el.id === Number(activeTab))}
      />

      <ModalSummaryTested
        data={dataSummaryTested}
        setData={setDataSummaryTested}
      />
    </Container>
  );
}

export default function Main() {
  const user = useMemo(() => {
    return localStorage.getItem("user") &&
      isJsonString(localStorage.getItem("user"))
      ? JSON.parse(localStorage.getItem("user") || "")
      : null;
  }, []);

  return (
    <MantineProvider>
      <SocketProvider>
        <Suspense
          fallback={
            <LoadingOverlay
              visible={true}
              zIndex={1000}
              overlayProps={{ radius: "sm", blur: 1 }}
            />
          }
        >
          <Notifications position="top-right" autoClose={5000} />
          {user ? (
            <App />
          ) : (
            <Container w={"100%"} style={{ maxWidth: "100%", padding: 0 }}>
              <PageLogin />
            </Container>
          )}
        </Suspense>
      </SocketProvider>
    </MantineProvider>
  );
}
