import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router';

import { useModal } from '@material-hu/hooks/useModal';
import CardActions from '@material-hu/mui/CardActions';
import Container from '@material-hu/mui/Container';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuFormCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox/form';
import HuDialog from '@material-hu/components/design-system/Dialog';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import HuFormUploader from '@material-hu/components/design-system/Uploader/form';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { type FileDetails, FileType } from 'src/types/files';
import { type Audience } from 'src/types/segmentation';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { formatFormSegmentation } from 'src/utils/segmentationUtils';
import { getFileNameExtension } from 'src/utils/stringUtils';
import {
  validateRequired,
  validateRequiredStringRule,
  validateStringTestRule,
} from 'src/utils/validation';

import FormSegmentation from 'src/components/FormInputs/FormSegmentation';

import { useFiles } from '../hooks/useFiles';
import { filesRoutes } from '../routes';

type Props = {
  currentFile?: FileDetails;
  parentFolder?: FileDetails;
  maxSize?: number;
};

export enum FileFormFields {
  FILES = 'files',
  SEGMENTATION = 'segmentation',
  NAME = 'name',
  PARENT_FOLDER_ID = 'parentFolderId',
  FILE = 'file',
}

const File = ({ currentFile, parentFolder, maxSize }: Props) => {
  const HuGoThemeProvider = useHuGoTheme();
  const { t } = useLokaliseTranslation(['files', 'material_hu_only']);
  const navigate = useNavigate();
  const isEditing = !!currentFile;
  const fileName = currentFile?.name;
  const originalExtension = getFileNameExtension(fileName);

  const parentFolderId = currentFile?.parentId || parentFolder?.id;

  const fileOrFolder = currentFile || parentFolder;
  const defaultAudience: Audience = {
    segmentation: [],
    userSegmentation: [],
  };
  const segmentationSource = fileOrFolder ?? defaultAudience;

  type FileFormValues = {
    files: Array<{ file: File }>;
    segmentation: ReturnType<typeof formatFormSegmentation>;
    name: string;
    propagateSegmentation: boolean;
  };

  const form = useForm<FileFormValues>({
    defaultValues: {
      files: [],
      segmentation: formatFormSegmentation(segmentationSource as Audience),
      name: currentFile?.name || '',
      propagateSegmentation: false,
    },
    mode: 'onChange',
  });
  const {
    watch,
    handleSubmit,
    formState: { isSubmitting, isValid, errors },
  } = form;
  const { segmentation, propagateSegmentation } = watch();

  const handleSave = handleSubmit(values => {
    const body = {
      ...values,
      files: values.files.map(file => file.file),
      file: currentFile,
      parentFolderId,
    };
    mutateAsync(body);
  });

  const cardTitle =
    (fileName && t('EDITING', { name: fileName })) ||
    (parentFolder && t('FOLDER', { name: parentFolder.name })) ||
    '';
  const handleBack = () => {
    navigate(-1);
  };

  const isSubmitDisabled = isEditing
    ? !isValid // check isValid because of rules on name input
    : Object.keys(errors).length > 0; // errors is not tied to "isValid"

  const onCloseModal = () => {
    closeModal();
    navigate(filesRoutes.file(parentFolderId));
  };

  const {
    modal: filesUploadedModal,
    closeModal,
    showModal: showFilesUploadedModal,
  } = useModal(() => (
    <HuDialog
      title={t('FILES_ASYNC_UPLOAD_TITLE')}
      textBody={t('FILES_ASYNC_UPLOAD_MESSAGE')}
      onClose={onCloseModal}
      primaryButtonProps={{
        color: 'primary',
        children: t('GENERAL:ACCEPT'),
        onClick: onCloseModal,
      }}
    />
  ));

  const {
    modal: propagateSegmentationModal,
    closeModal: closePropagateSegmentationModal,
    showModal: showPropagateSegmentationModal,
  } = useModal(() => (
    <HuDialog
      title={t('you_will_change_segmentation')}
      textBody={t('you_will_change_segmentation_sure', {
        folderName: fileName,
      })}
      primaryButtonProps={{
        children: t('GENERAL:ACCEPT'),
        onClick: () => {
          handleSave();
          closePropagateSegmentationModal();
        },
      }}
      secondaryButtonProps={{
        children: t('GENERAL:CANCEL'),
        onClick: closePropagateSegmentationModal,
      }}
      onClose={closePropagateSegmentationModal}
    />
  ));

  const { mutateAsync, isMutationLoading } = useFiles({
    segmentation,
    isEditing,
    parentFolderId,
    showFilesUploadedModal,
  });

  const title = isEditing
    ? t('TITLE', { context: currentFile?.type })
    : t('ADD_FILES', { context: FileType.FILE });
  return (
    <HuGoThemeProvider>
      {filesUploadedModal}
      {propagateSegmentationModal}
      <Container
        maxWidth="lg"
        sx={{ py: 2, display: 'flex', flexDirection: 'column', gap: 2 }}
      >
        <Typography variant="globalL">{title}</Typography>
        <HuCardContainer sx={{ width: '100%' }}>
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
            sx={{
              display: '-webkit-box',
              overflow: 'hidden',
              WebkitBoxOrient: 'vertical',
              WebkitLineClamp: 2,
              textOverflow: 'ellipsis',
              wordWrap: 'break-word',
              flex: 1,
            }}
          >
            {cardTitle}
          </Typography>
          <Stack sx={{ gap: 3, p: 2, justifyContent: 'center' }}>
            <FormProvider {...form}>
              {!isEditing && (
                <HuFormUploader
                  rules={{ required: t('MUST_SELECT_FILES') }}
                  name={FileFormFields.FILES}
                  uploaderProps={{
                    sx: { width: '100%' },
                    fileSizeLimit: maxSize,
                    label: title,
                    acceptedTypes: ['image', 'video', 'msword', 'pdf'],
                    uploadFunction: file =>
                      new Promise(resolve =>
                        resolve({
                          status: 'success',
                          file,
                        }),
                      ),
                  }}
                />
              )}
              {isEditing && (
                <HuFormInputClassic
                  name={FileFormFields.NAME}
                  inputProps={{ label: t('FILENAME'), sx: { mb: 2 } }}
                  rules={{
                    ...validateRequired(),

                    validate: {
                      require: validateRequiredStringRule,
                      test: validateStringTestRule(
                        'name-extension',
                        t('WRONG_EXTENSION', {
                          extension: currentFile.extension,
                        }),
                        value =>
                          currentFile.type === FileType.FOLDER ||
                          Boolean(value?.endsWith(`.${originalExtension}`)),
                      ),
                    },
                  }}
                />
              )}
              <Stack sx={{ gap: 1 }}>
                <FormSegmentation
                  name={FileFormFields.SEGMENTATION}
                  segmentationErrorMessage={t('MUST_SELECT_SEGMENTATION')}
                />
                {isEditing && currentFile.type === FileType.FOLDER && (
                  <HuFormCheckbox
                    name="propagateSegmentation"
                    checkBoxProps={{ label: t('PROPAGATE_SEGMENTATION') }}
                  />
                )}
              </Stack>
            </FormProvider>
          </Stack>
          <CardActions sx={{ justifyContent: 'flex-end' }}>
            <Button
              variant="secondary"
              onClick={handleBack}
              sx={{ mr: 'auto' }}
            >
              {t('GENERAL:CANCEL')}
            </Button>
            <Button
              loading={isSubmitting || isMutationLoading}
              variant="primary"
              onClick={
                propagateSegmentation
                  ? showPropagateSegmentationModal
                  : handleSave
              }
              disabled={isSubmitDisabled}
            >
              {t('SAVE')}
            </Button>
          </CardActions>
        </HuCardContainer>
      </Container>
    </HuGoThemeProvider>
  );
};

export default File;
