import CancelIcon from "@mui/icons-material/Close";
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
import EditIcon from "@mui/icons-material/Edit";
import SaveIcon from "@mui/icons-material/Save";
import {
  DataGrid,
  GridActionsCellItem,
  GridColDef,
  GridRowId,
  GridRowModes,
  GridRowModesModel,
} from "@mui/x-data-grid";
import React from "react";
import { FamilyApi, FamilyUser } from "../../api/FamilyApi";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { useConfirm } from "../../hooks/context_providers/ConfirmDialogProvider";
import { AsyncWidget } from "../../widgets/AsyncWidget";
import { useUser } from "../../widgets/BaseAuthenticatedPage";
import { useFamily } from "../../widgets/BaseFamilyRoute";
import { FamilyPageTitle } from "../../widgets/FamilyPageTitle";
import { TimeWidget } from "../../widgets/TimeWidget";

export function FamilyUsersListRoute(): React.ReactElement {
  const family = useFamily();

  const [users, setUsers] = React.useState<FamilyUser[] | null>(null);

  const key = React.useRef(1);

  const load = async () => {
    setUsers(await FamilyApi.GetUsersList(family.family.family_id));
  };

  const reload = async () => {
    key.current += 1;
    setUsers(null);
  };

  return (
    <AsyncWidget
      loadKey={`${family.family.family_id}-${key.current}`}
      errMsg="Echec du chargement de la liste des utilisateurs de la famille !"
      load={load}
      ready={users !== null}
      build={() => (
        <>
          <FamilyPageTitle title="Utilisateurs de la famille" />
          <UsersTable users={users!} onReload={reload} />
        </>
      )}
    />
  );
}

function UsersTable(p: {
  users: FamilyUser[];
  onReload: () => void;
}): React.ReactElement {
  const alert = useAlert();
  const confirm = useConfirm();
  const user = useUser();
  const family = useFamily();

  const [rowModesModel, setRowModesModel] = React.useState<GridRowModesModel>(
    {}
  );

  const handleEditClick = (id: GridRowId) => () => {
    setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } });
  };

  const handleSaveClick = (id: GridRowId) => () => {
    setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
  };

  // Remove a membership
  const handleDeleteClick = (id: GridRowId) => async () => {
    try {
      const user = p.users.find((u) => u.user_id === id)!;
      if (
        !(await confirm(
          `Voulez-vous vraiment retirer ${user.user_name} de cette famille ?`
        ))
      )
        return;

      await FamilyApi.RemoveUser(user);
      p.onReload();
    } catch (e) {
      console.error(e);
      alert("Echec de la suppression de l'utilisateur !");
    }
  };

  const handleCancelClick = (id: GridRowId) => () => {
    setRowModesModel({
      ...rowModesModel,
      [id]: { mode: GridRowModes.View, ignoreModifications: true },
    });
  };

  const columns: GridColDef[] = [
    { field: "user_id", headerName: "#", flex: 1 },
    { field: "user_mail", headerName: "Adresse mail", flex: 5 },
    { field: "user_name", headerName: "Nom d'utilisateur", flex: 5 },
    {
      field: "time_create",
      headerName: "Date d'ajout",
      flex: 5,
      renderCell(params) {
        return <TimeWidget time={params.row.time_create} />;
      },
    },
    {
      field: "is_admin",
      headerName: "Admin",
      flex: 2,
      type: "boolean",
      editable: family.family.is_admin,
    },
  ];

  if (family.family.is_admin)
    columns.push({
      field: "actions",
      type: "actions",
      headerName: "Actions",
      flex: 2,
      cellClassName: "actions",
      getActions: ({ id }) => {
        const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;

        if (id === user.user.id) return [];

        if (isInEditMode) {
          return [
            <GridActionsCellItem
              icon={<SaveIcon />}
              label="Save"
              sx={{
                color: "primary.main",
              }}
              onClick={handleSaveClick(id)}
            />,
            <GridActionsCellItem
              icon={<CancelIcon />}
              label="Cancel"
              className="textPrimary"
              onClick={handleCancelClick(id)}
              color="inherit"
            />,
          ];
        }

        return [
          <GridActionsCellItem
            icon={<EditIcon />}
            label="Edit"
            className="textPrimary"
            onClick={handleEditClick(id)}
            color="inherit"
          />,
          <GridActionsCellItem
            icon={<DeleteIcon />}
            label="Delete"
            onClick={handleDeleteClick(id)}
            color="inherit"
          />,
        ];
      },
    });

  return (
    <DataGrid
      style={{ flex: "1" }}
      rows={p.users}
      columns={columns}
      autoPageSize
      editMode="row"
      rowModesModel={rowModesModel}
      getRowId={(c) => c.user_id}
      isCellEditable={(params) => params.row.user_id !== user.user.id}
      processRowUpdate={async (n: FamilyUser) => {
        await FamilyApi.UpdateUser(n);
        return n;
      }}
      onProcessRowUpdateError={(e) => {
        console.error(e);
        alert("Échec de la mise à jour des informations utilisateurs !");
      }}
    />
  );
}
