import { Trans, useTranslation } from "react-i18next";
import { DialogContent, Stack } from "@mui/material";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks.ts";
import {
  ChangeEvent,
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState,
} from "react";
import {
  closeRenameFileModal,
  setRenameFileModalError,
} from "../../../redux/fileManagerSlice.ts";
import DraggableDialog, {
  StyledDialogContentText,
} from "../../Dialogs/DraggableDialog.tsx";
import { renameDialogPromisePool } from "../../../redux/thunks/dialog.ts";
import { validateFileName } from "../../../redux/thunks/file.ts";
import { FileType } from "../../../api/explorer.ts";

import { FmIndexContext } from "../FmIndexContext.tsx";
import { FilledTextField } from "../../Common/StyledComponents.tsx";

const Rename = () => {
  const { t } = useTranslation();
  const dispatch = useAppDispatch();

  const [name, setName] = useState("");
  const formRef = useRef<HTMLFormElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const fmIndex = useContext(FmIndexContext);

  const open = useAppSelector(
    (state) => state.fileManager[0].renameFileModalOpen,
  );
  const targets = useAppSelector(
    (state) => state.fileManager[0].renameFileModalSelected,
  );
  const promiseId = useAppSelector(
    (state) => state.fileManager[0].renameFileModalPromiseId,
  );
  const loading = useAppSelector(
    (state) => state.fileManager[0].renameFileModalLoading,
  );
  const error = useAppSelector(
    (state) => state.fileManager[0].renameFileModalError,
  );

  const onClose = useCallback(() => {
    dispatch(
      closeRenameFileModal({
        index: 0,
        value: undefined,
      }),
    );
    if (promiseId) {
      renameDialogPromisePool[promiseId]?.reject("cancel");
    }
  }, [dispatch, targets, promiseId]);

  const onAccept = useCallback(
    (e?: React.FormEvent<HTMLFormElement>) => {
      if (e) {
        e.preventDefault();
      }
      if (promiseId) {
        dispatch(
          validateFileName(
            0,
            renameDialogPromisePool[promiseId]?.resolve,
            name,
          ),
        );
      }
    },
    [promiseId, name],
  );

  const onOkClicked = useCallback(() => {
    if (formRef.current) {
      if (formRef.current.reportValidity()) {
        onAccept();
      }
    }
  }, [formRef, onAccept]);

  useEffect(() => {
    if (targets && open) {
      setName(targets.name);
    }
  }, [targets, open]);

  useEffect(() => {
    if (targets && open && inputRef.current) {
      const lastDot =
        targets.type == FileType.folder ? 0 : targets.name.lastIndexOf(".");
      inputRef.current.setSelectionRange(
        0,
        lastDot > 0 ? lastDot : targets.name.length,
      );
    }
  }, [inputRef.current, open]);

  const onNameChange = useCallback(
    (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
      setName(e.target.value);
      if (error) {
        dispatch(setRenameFileModalError({ index: 0, value: undefined }));
      }
    },
    [dispatch, setName, error],
  );

  return (
    <DraggableDialog
      title={t("application:fileManager.rename")}
      showActions
      loading={loading}
      showCancel
      onAccept={onOkClicked}
      dialogProps={{
        open: open ?? false,
        onClose: onClose,
        fullWidth: true,
        maxWidth: "sm",
        disableRestoreFocus: true,
      }}
    >
      <DialogContent>
        <Stack spacing={2}>
          <StyledDialogContentText>
            <Trans
              i18nKey="modals.renameDescription"
              ns={"application"}
              values={{
                name: targets?.name,
              }}
              components={[<strong key={0} />]}
            />
          </StyledDialogContentText>
          <form ref={formRef} onSubmit={onAccept}>
            <FilledTextField
              inputRef={inputRef}
              variant="filled"
              autoFocus
              error={!!error}
              helperText={error}
              margin="dense"
              label={t("application:modals.newName")}
              type="text"
              value={name}
              onChange={onNameChange}
              fullWidth
              required
            />
          </form>
        </Stack>
      </DialogContent>
    </DraggableDialog>
  );
};
export default Rename;
