import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid";
import { ruRU } from "@mui/x-data-grid/locales";
import { authStore, languageStore, snapshotStore, SearchInput } from "@shared";
import { useEffect, useState, useMemo } from "react";
import { observer } from "mobx-react-lite";
import { DatabaseBackup, Trash2 } from "lucide-react";
import { CreateButton, DeleteModal, SnapshotRestore } from "@widgets";
import { Alert, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, TextField } from "@mui/material";

const LOW_STORAGE_THRESHOLD_GB = 10;

const SEGMENT_COLORS = [
  "#FF3B30",
  "#FF9500",
  "#FFCC00",
  "#8E8E93",
  "#AEAEB2",
  "#34C759",
  "#007AFF",
  "#5856D6",
  "#AF52DE",
  "#FF2D55",
];

export const SnapshotListPage = observer(() => {
  const {
    snapshots,
    getSnapshots,
    deleteSnapshot,
    restoreSnapshot,
    storageInfo,
    getStorageInfo,
    createEmptySnapshot,
  } = snapshotStore;
  const canWriteDevices = authStore.canWrite("devices");
  const canCreateSnapshot =
    authStore.hasRole("snapshot_create") && canWriteDevices;
  const canManageSnapshots = authStore.canWrite("snapshot") && canWriteDevices;

  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
  const [rowId, setRowId] = useState<string | null>(null);
  const { language } = languageStore;
  const [isRestoreModalOpen, setIsRestoreModalOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [isEmptySnapshotModalOpen, setIsEmptySnapshotModalOpen] = useState(false);
  const [emptySnapshotName, setEmptySnapshotName] = useState("");
  const [isCreatingEmpty, setIsCreatingEmpty] = useState(false);
  const [paginationModel, setPaginationModel] = useState({
    page: 0,
    pageSize: 50,
  });

  const availableGB = storageInfo ? storageInfo.available_disk_space_gb : null;
  const totalGB = storageInfo ? storageInfo.total_disk_space_gb : null;
  const usedGB =
    totalGB !== null && availableGB !== null ? totalGB - availableGB : null;
  const isLowStorage =
    availableGB !== null && availableGB < LOW_STORAGE_THRESHOLD_GB;

  useEffect(() => {
    const fetchSnapshots = async () => {
      setIsLoading(true);
      await Promise.all([getSnapshots(), getStorageInfo()]);
      setIsLoading(false);
    };
    fetchSnapshots();
  }, [language]);

  const formatCreationTime = (isoString: string | undefined) => {
    if (!isoString) return "";
    const [datePart, timePartWithMs] = isoString.split("T");
    if (!datePart || !timePartWithMs) return isoString;
    const timePart = timePartWithMs.split(".")[0];
    return `${datePart} - ${timePart}`;
  };

  const columns: GridColDef[] = [
    {
      field: "color",
      headerName: "",
      width: 28,
      sortable: false,
      disableColumnMenu: true,
      renderCell: (params: GridRenderCellParams) => (
        <div className="flex items-center justify-center h-full w-full">
          <span
            style={{
              display: "inline-block",
              width: 12,
              height: 12,
              backgroundColor: params.value,
              borderRadius: "50%",
            }}
          />
        </div>
      ),
    },
    {
      field: "name",
      headerName: "Название",
      flex: 1,
    },
    {
      field: "parent",
      headerName: "Родитель",
      flex: 1,
    },
    {
      field: "created_at",
      headerName: "Дата создания",
      flex: 1,
      renderCell: (params: GridRenderCellParams) => {
        return <div>{params.value ? params.value : "-"}</div>;
      },
    },
    {
      field: "occupied_disk_space_gb",
      headerName: "Размер",
      width: 120,
      renderCell: (params: GridRenderCellParams) => {
        return (
          <div>
            {params.value != null ? `${params.value.toFixed(1)} ГБ` : "-"}
          </div>
        );
      },
    },
    ...(canManageSnapshots
      ? [
          {
            field: "actions",
            headerName: "Действия",
            width: 300,
            headerAlign: "center" as const,
            sortable: false,
            renderCell: (params: GridRenderCellParams) => (
              <div className="flex h-full gap-7 justify-center items-center">
                <button
                  title="Восстановить"
                  onClick={() => {
                    setIsRestoreModalOpen(true);
                    setRowId(params.row.id);
                  }}
                >
                  <DatabaseBackup size={20} className="text-blue-500" />
                </button>
                <button
                  title="Удалить"
                  onClick={() => {
                    setIsDeleteModalOpen(true);
                    setRowId(params.row.id);
                  }}
                >
                  <Trash2 size={20} className="text-red-500" />
                </button>
              </div>
            ),
          },
        ]
      : []),
  ];

  const rows = useMemo(() => {
    const query = searchQuery.trim().toLowerCase();
    return snapshots
      .filter(
        (snapshot) =>
          !query ||
          (snapshot.Name ?? "").toLowerCase().includes(query) ||
          (snapshots.find((s) => s.ID === snapshot.ParentID)?.Name ?? "")
            .toLowerCase()
            .includes(query),
      )
      .map((snapshot, index) => ({
        id: snapshot.ID,
        name: snapshot.Name,
        parent: snapshots.find((s) => s.ID === snapshot.ParentID)?.Name,
        created_at: formatCreationTime(snapshot.CreationTime),
        occupied_disk_space_gb: snapshot.occupied_disk_space_gb,
        color: SEGMENT_COLORS[index % SEGMENT_COLORS.length],
      }));
  }, [snapshots, searchQuery]);

  const snapshotsGB = rows.reduce(
    (sum, row) => sum + (row.occupied_disk_space_gb ?? 0),
    0,
  );
  const systemGB = usedGB !== null ? Math.max(0, usedGB - snapshotsGB) : null;

  return (
    <>
      <div style={{ width: "100%" }}>
        <div className="flex justify-between items-center mb-10">
          <h1 className="text-2xl ">Экспорт Медиа</h1>

          <div className="flex gap-3">
            {canCreateSnapshot && (
              <Button
                variant="outlined"
                disabled={isLowStorage}
                onClick={() => {
                  setEmptySnapshotName("");
                  setIsEmptySnapshotModalOpen(true);
                }}
              >
                Создать пустой экспорт
              </Button>
            )}
            {canCreateSnapshot && (
              <CreateButton
                label="Создать экспорт медиа"
                path="/snapshot/create"
                disabled={isLowStorage}
              />
            )}
          </div>
        </div>
        {usedGB != null && totalGB != null && (
          <div className="bg-white rounded-2xl p-5 mb-6 shadow-sm border border-gray-100">
            <div className="flex items-baseline gap-3 mb-3">
              <span className="text-lg font-semibold">Хранилище</span>
              <span className="text-sm text-gray-500">
                Используется: {usedGB.toFixed(2)} ГБ из {totalGB.toFixed(0)} ГБ
              </span>
            </div>

            <div className="flex w-full h-3 rounded-lg overflow-hidden bg-gray-100">
              {rows.map((row) => {
                const pct =
                  row.occupied_disk_space_gb != null && totalGB > 0
                    ? (row.occupied_disk_space_gb / totalGB) * 100
                    : 0;
                if (pct <= 0) return null;
                return (
                  <div
                    key={row.id}
                    style={{
                      width: `${pct}%`,
                      backgroundColor: row.color,
                    }}
                    title={`${row.name}: ${row.occupied_disk_space_gb?.toFixed(1)} ГБ`}
                  />
                );
              })}
              {systemGB !== null && systemGB > 0 && totalGB > 0 && (
                <div
                  style={{
                    width: `${(systemGB / totalGB) * 100}%`,
                    backgroundColor: "#C7C7CC",
                  }}
                  title={`Системные данные: ${systemGB.toFixed(1)} ГБ`}
                />
              )}
            </div>

            <div className="flex flex-wrap gap-x-5 gap-y-1 mt-3">
              {rows.map((row) => {
                if (row.occupied_disk_space_gb == null || row.occupied_disk_space_gb <= 0)
                  return null;
                return (
                  <div
                    key={row.id}
                    className="flex items-center gap-1.5 text-xs text-gray-700"
                  >
                    <span
                      className="inline-block w-2.5 h-2.5 rounded-full"
                      style={{ backgroundColor: row.color }}
                    />
                    {row.name}
                  </div>
                );
              })}
              {systemGB !== null && systemGB > 0 && (
                <div className="flex items-center gap-1.5 text-xs text-gray-700">
                  <span
                    className="inline-block w-2.5 h-2.5 rounded-full"
                    style={{ backgroundColor: "#C7C7CC" }}
                  />
                  Системные данные
                </div>
              )}
              {availableGB !== null && availableGB > 0 && (
                <div className="flex items-center gap-1.5 text-xs text-gray-700">
                  <span className="inline-block w-2.5 h-2.5 rounded-full bg-gray-100" />
                  Свободно
                </div>
              )}
            </div>
          </div>
        )}

        {isLowStorage && (
          <Alert severity="warning" className="mb-4">
            Недостаточно места на диске! Осталось {availableGB?.toFixed(1)} ГБ
            из {totalGB?.toFixed(0)} ГБ. Создание новых экспортов заблокировано.
            Удалите ненужные экспорты для освобождения места или обратитесь к
            администратору сервера.
          </Alert>
        )}

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

        <DataGrid
          rows={rows}
          columns={columns}
          loading={isLoading}
          paginationModel={paginationModel}
          onPaginationModelChange={setPaginationModel}
          pageSizeOptions={[50]}
          localeText={ruRU.components.MuiDataGrid.defaultProps.localeText}
          slots={{
            noRowsOverlay: () => (
              <Box sx={{ mt: 5, textAlign: "center", color: "text.secondary" }}>
                {isLoading ? (
                  <CircularProgress size={20} />
                ) : (
                  "Нет экспортов медиа"
                )}
              </Box>
            ),
          }}
        />
      </div>

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

      <Dialog
        open={isEmptySnapshotModalOpen}
        onClose={() => setIsEmptySnapshotModalOpen(false)}
        fullWidth
        maxWidth="xs"
      >
        <DialogTitle>Создать пустой экспорт</DialogTitle>
        <DialogContent>
          <TextField
            autoFocus
            fullWidth
            label="Название"
            value={emptySnapshotName}
            onChange={(e) => setEmptySnapshotName(e.target.value)}
            margin="normal"
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setIsEmptySnapshotModalOpen(false)}>
            Отмена
          </Button>
          <Button
            variant="contained"
            disabled={!emptySnapshotName.trim() || isCreatingEmpty}
            onClick={async () => {
              setIsCreatingEmpty(true);
              try {
                await createEmptySnapshot(emptySnapshotName);
                await getSnapshots();
                setIsEmptySnapshotModalOpen(false);
              } finally {
                setIsCreatingEmpty(false);
              }
            }}
          >
            {isCreatingEmpty ? <CircularProgress size={20} /> : "Создать"}
          </Button>
        </DialogActions>
      </Dialog>

      <SnapshotRestore
        open={isRestoreModalOpen}
        loading={isLoading}
        onDelete={async () => {
          setIsLoading(true);
          if (rowId) {
            await restoreSnapshot(rowId);
          }
          setIsRestoreModalOpen(false);
          setRowId(null);
          setIsLoading(false);
        }}
        onCancel={() => {
          setIsRestoreModalOpen(false);
          setRowId(null);
        }}
      />
    </>
  );
});
