import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { ruRU } from "@mui/x-data-grid/locales";
import {
  authStore,
  languageStore,
  stationsStore,
  selectedCityStore,
  SearchInput,
} from "@shared";
import { useEffect, useState, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { Pencil, Trash2, Minus, Route, Check, X } from "lucide-react";
import { useNavigate } from "react-router-dom";
import {
  CreateButton,
  DeleteModal,
  LanguageSwitcher,
  EditStationTransfersModal,
} from "@widgets";
import { Box, CircularProgress, Tooltip } from "@mui/material";

export const StationListPage = observer(() => {
  const { stationLists, getStationList, deleteStation, sightCounts, sightCountsLoading, loadSightCounts } = stationsStore;
  const navigate = useNavigate();
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  const [isBulkDeleteModalOpen, setIsBulkDeleteModalOpen] = useState(false);
  const [isTransfersModalOpen, setIsTransfersModalOpen] = useState(false);
  const [rowId, setRowId] = useState<number | null>(null);
  const [selectedStationId, setSelectedStationId] = useState<number | null>(
    null
  );
  const [ids, setIds] = useState<number[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [paginationModel, setPaginationModel] = useState({
    page: 0,
    pageSize: 50,
  });
  const { language } = languageStore;
  const canWriteStations = authStore.canWrite("stations");
  const [searchQuery, setSearchQuery] = useState("");

  useEffect(() => {
    const fetchStations = async () => {
      setIsLoading(true);
      await getStationList();
      setIsLoading(false);

      const stationIds = stationLists[language].data.map((s: any) => s.id);
      loadSightCounts(stationIds);
    };
    fetchStations();
  }, [language, selectedCityStore.cityVersion]);

  const columns: GridColDef[] = [
    {
      field: "name",
      headerName: "Название",
      flex: 1,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div className="w-full h-full flex items-center">
            {params.value ? (
              params.value
            ) : (
              <Minus size={20} className="text-red-500" />
            )}
          </div>
        );
      },
    },
    {
      field: "description",
      headerName: "Описание",
      flex: 1,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div className="w-full h-full flex items-center">
            {params.value ? (
              params.value
            ) : (
              <Minus size={20} className="text-red-500" />
            )}
          </div>
        );
      },
    },
    {
      field: "sightCount",
      headerName: "Привязки",
      width: 180,
      align: "center" as const,
      headerAlign: "center" as const,
      sortable: true,
      renderHeader: (params) => (
        <Tooltip title="Отображает количество привязок">
          <span>{params.colDef.headerName}</span>
        </Tooltip>
      ),
      renderCell: (params: GridRenderCellParams) => (
        <div className="w-full h-full flex items-center justify-center">
          {params.value === null ? (
            <CircularProgress size={14} />
          ) : (
            params.value
          )}
        </div>
      ),
    },
    {
      field: "hasTransfers",
      headerName: "Пересадки",
      width: 120,
      align: "center" as const,
      headerAlign: "center" as const,
      sortable: true,
      renderHeader: (params) => (
        <Tooltip title="Отображает подтверждение добавленных пересадок">
          <span>{params.colDef.headerName}</span>
        </Tooltip>
      ),
      renderCell: (params: GridRenderCellParams) => (
        <Box
          sx={{ display: "flex", justifyContent: "center", alignItems: "center", width: "100%", height: "100%" }}
        >
          {params.value ? (
            <Check size={18} className="text-green-600" />
          ) : (
            <X size={18} className="text-red-600" />
          )}
        </Box>
      ),
    },
    {
      field: "actions",
      headerName: "Действия",
      width: 200,
      align: "center" as const,
      headerAlign: "center" as const,
      sortable: false,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div className="flex h-full gap-7 justify-center items-center">
            {canWriteStations && (
              <button title="Редактировать" onClick={() => navigate(`/station/${params.row.id}/edit`)}>
                <Pencil size={20} className="text-blue-500" />
              </button>
            )}
            {canWriteStations && (
              <button
                onClick={() => {
                  setSelectedStationId(params.row.id);
                  setIsTransfersModalOpen(true);
                }}
                title="Управление пересадками"
              >
                <Route size={20} className="text-purple-500" />
              </button>
            )}
            {canWriteStations && (
              <button
                title="Удалить"
                onClick={() => {
                  setIsDeleteModalOpen(true);
                  setRowId(params.row.id);
                }}
              >
                <Trash2 size={20} className="text-red-500" />
              </button>
            )}
          </div>
        );
      },
    },
  ];

  const rows = useMemo(() => {
    const { selectedCityId } = selectedCityStore;
    if (!selectedCityId) {
      return [];
    }
    const query = searchQuery.trim().toLowerCase();
    return stationLists[language].data
      .filter((station: any) => station.city_id === selectedCityId)
      .filter(
        (station: any) =>
          !query ||
          (station.name ?? "").toLowerCase().includes(query) ||
          (station.description ?? "").toLowerCase().includes(query)
      )
      .map((station: any) => ({
        id: station.id,
        name: station.name,
        description: station.description,
        sightCount: sightCounts.has(station.id) ? sightCounts.get(station.id) : null,
        hasTransfers: station.transfers
          ? Object.values(station.transfers).some((v: any) => v != null && v !== "")
          : false,
      }));
  }, [stationLists[language].data, selectedCityStore.selectedCityId, searchQuery, sightCounts.size, sightCountsLoading]);

  return (
    <>
      <LanguageSwitcher />

      <div className="w-full">
        <div className="flex justify-between items-center mb-10">
          <h1 className="text-2xl">Остановки</h1>
          {canWriteStations && (
            <CreateButton
              label="Создать остановку"
              path="/station/create"
            />
          )}
        </div>

        {canWriteStations && ids.length > 0 && (
          <div className="flex justify-end mb-5 duration-300">
            <button
              className="px-4 py-2 bg-red-500 text-white rounded flex gap-2 items-center"
              onClick={() => setIsBulkDeleteModalOpen(true)}
            >
              <Trash2 size={20} className="text-white" /> Удалить выбранные (
              {ids.length})
            </button>
          </div>
        )}

        {rows.length > 0 && (
          <SearchInput value={searchQuery} onChange={setSearchQuery} />
        )}

        <DataGrid
          rows={rows}
          columns={columns}
          onRowDoubleClick={(params) => canWriteStations && navigate(`/station/${params.row.id}/edit`)}
          checkboxSelection={canWriteStations}
          disableRowSelectionExcludeModel
          disableRowSelectionOnClick
          loading={isLoading}
          paginationModel={paginationModel}
          onPaginationModelChange={setPaginationModel}
          pageSizeOptions={[50]}
          onRowSelectionModelChange={
            canWriteStations
              ? (newSelection: any) => {
                  if (Array.isArray(newSelection)) {
                    const selectedIds = newSelection
                      .map((id: string | number) => {
                        const numId =
                          typeof id === "string"
                            ? Number.parseInt(id, 10)
                            : Number(id);
                        return numId;
                      })
                      .filter(
                        (id: number) =>
                          !Number.isNaN(id) && id !== null && id !== undefined
                      );
                    setIds(selectedIds);
                  } else if (
                    newSelection &&
                    typeof newSelection === "object" &&
                    "ids" in newSelection
                  ) {
                    const idsSet = newSelection.ids as Set<string | number>;
                    const selectedIds = Array.from(idsSet)
                      .map((id: string | number) => {
                        const numId =
                          typeof id === "string"
                            ? Number.parseInt(id, 10)
                            : Number(id);
                        return numId;
                      })
                      .filter(
                        (id: number) =>
                          !Number.isNaN(id) && id !== null && id !== undefined
                      );
                    setIds(selectedIds);
                  } else {
                    setIds([]);
                  }
                }
              : undefined
          }
          localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
          slots={{
            noRowsOverlay: () => (
              <Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
                {isLoading ? (
                  <CircularProgress size={20} />
                ) : !selectedCityStore.selectedCityId ? (
                  "Выберите город"
                ) : (
                  "Нет остановок"
                )}
              </Box>
            ),
          }}
        />
      </div>

      <DeleteModal
        open={isDeleteModalOpen}
        onDelete={async () => {
          if (rowId) {
            deleteStation(rowId);
          }
          setIsDeleteModalOpen(false);
          setRowId(null);
        }}
        onCancel={() => {
          setIsDeleteModalOpen(false);
          setRowId(null);
        }}
      />

      <DeleteModal
        open={isBulkDeleteModalOpen}
        onDelete={async () => {
          await Promise.all(ids.map((id) => deleteStation(id)));
          getStationList();
          setIsBulkDeleteModalOpen(false);
          setIds([]);
        }}
        onCancel={() => {
          setIsBulkDeleteModalOpen(false);
        }}
      />

      <EditStationTransfersModal
        open={isTransfersModalOpen}
        onClose={() => {
          setIsTransfersModalOpen(false);
          setSelectedStationId(null);
        }}
        stationId={selectedStationId}
      />
    </>
  );
});
