import { FC, useState, useEffect, useMemo } from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import { useQuery, useMutation } from 'react-query';
import { useParams, useNavigate } from 'react-router-dom';

import InfoIcon from '@material-hu/icons/material/Info';
import Box from '@material-hu/mui/Box';
import Card from '@material-hu/mui/Card';
import CircularProgress from '@material-hu/mui/CircularProgress';
import Container from '@material-hu/mui/Container';
import Divider from '@material-hu/mui/Divider';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { IDEA_STATUS_ID } from 'src/constants/recognitions';
import useGeneralError from 'src/hooks/useGeneralError';
import CardHeader from 'src/pages/dashboard/recognitions/components/CardHeader';
import IdeaDataForm from 'src/pages/dashboard/recognitions/components/IdeaDataForm';
import RequiredFieldsAlert from 'src/pages/dashboard/recognitions/components/RequiredFieldsAlert';
import UserDataForm from 'src/pages/dashboard/recognitions/components/UserDataForm';
import { useTranslation } from 'src/pages/dashboard/recognitions/i18n';
import { recognitionsKeys } from 'src/pages/dashboard/recognitions/queries';
import { recognitionsRoutes } from 'src/pages/dashboard/recognitions/routes';
import {
  getIdeaDetails,
  getUploadedFiles,
  getEmployeesData,
  getCurrentApprover,
  editData,
  uploadFile,
  setApprovalStatus,
} from 'src/services/recognitions';
import {
  getUserId,
  getUploadedFile,
  checkCorrectAnswers,
  checkIsMissingImage,
  getEditIdeaValues,
  getImageBody,
  hasImagesBeenUploaded,
} from 'src/utils/recognitions';

import ImplementationDataForm from './ImplementationDataForm';

export const IdeaDetail: FC = () => {
  const { ideaId } = useParams();
  const userId = getUserId();

  const { t } = useTranslation();
  const navigate = useNavigate();
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();

  const [idea, setIdea] = useState(null);
  const [startImage, setStartImage] = useState(null);
  const [endImage, setEndImage] = useState(null);

  const [showIncorrectAnswers, setShowIncorrectAnswers] = useState(false);
  const [isImageMissing, setIsImageMissing] = useState(false);

  const defaultValues = idea?.[0];

  const methods = useForm({
    defaultValues: defaultValues || {},
  });

  const { errors } = methods.formState;

  const { isLoading: isIdeaLoading } = useQuery(
    [recognitionsKeys.ideaDetail(userId, ideaId)],
    () => getIdeaDetails(ideaId),
    {
      enabled: !!ideaId && !!userId,
      onSuccess: data => {
        setIdea(JSON.parse(data.data.Data));
      },
    },
  );

  const { data: filesData, isLoading: isFilesLoading } = useQuery(
    [recognitionsKeys.files(idea?.[0].folio)],
    () => getUploadedFiles(idea?.[0].folio),
    {
      enabled: !!idea,
    },
  );

  const { data: employeesData, isLoading: isEmployeesLoading } = useQuery(
    [recognitionsKeys.employees(idea?.[0].folio)],
    () => getEmployeesData(idea?.[0].folio),
    {
      enabled: !!idea,
    },
  );

  const { data: approverData, isLoading: isEmployeesApprover } = useQuery(
    [recognitionsKeys.approverId(idea?.[0].folio)],
    () => getCurrentApprover(idea?.[0].folio),
    {
      enabled: !!idea,
    },
  );

  const selectedUsers = useMemo(
    () =>
      employeesData?.data?.Data?.map(obj => {
        const { employeeId, ...rest } = obj;
        return { EmployeeNumber: employeeId, ...rest };
      }),
    [employeesData],
  );

  const beforeImage = getUploadedFile(filesData?.data?.DataFiles, true);
  const afterImage = idea?.[0].ideaImplemented
    ? getUploadedFile(filesData?.data.DataFiles, false)
    : null;

  useEffect(() => {
    if (beforeImage !== null) {
      setStartImage(beforeImage);
    }
    if (afterImage !== null) {
      setEndImage(afterImage);
    }
  }, [filesData]);

  const uploadImage = async (folio, isStart) => {
    const imageBody = getImageBody(
      folio,
      startImage,
      endImage,
      userId,
      isStart,
    );
    const responseUpload = await uploadFile(imageBody);
    return responseUpload.data.StatusCode;
  };

  const imageUploadAction = uploadSuccess => {
    if (uploadSuccess) {
      enqueueSnackbar({
        title: t('IDEA_SUCCESSFULLY_EDITED'),
        variant: 'success',
      });
      navigate(recognitionsRoutes.ideas());
    } else {
      enqueueSnackbar({ title: t('IDEA_ERROR_EDITED'), variant: 'error' });
    }
  };

  const mutation = useMutation(editData, {
    onSuccess: async (response, variables) => {
      const { StatusCode } = response.data;
      const { folio, ideaImplemented, statusID } = idea?.[0] || {};

      if (StatusCode !== '0') return;

      if (
        !ideaImplemented &&
        statusID === IDEA_STATUS_ID.IN_PROCESS &&
        isApprover
      ) {
        const imageStatusCode = await uploadImage(folio, false);
        const data = {
          folio: folio,
          approverId: userId,
          statusId: 3,
        };
        const newResponse = await setApprovalStatus(data);
        const { StatusCode: NewStatusCode } = newResponse.data;
        imageUploadAction(imageStatusCode === '0' && NewStatusCode === '0');
      } else if (statusID === IDEA_STATUS_ID.IN_DRAFT) {
        const uploadPromises = [uploadImage(folio, true)];
        if (variables.ideaImplemented) {
          uploadPromises.push(uploadImage(folio, false));
        }
        const statusCodes = await Promise.all(uploadPromises);
        imageUploadAction(hasImagesBeenUploaded(statusCodes));
      }
    },
    onError: err => showGeneralError(err, t('UPLOAD_IMAGE_ERROR')),
  });

  const onSubmit = async data => {
    const currentIdea = idea?.[0];
    if (!currentIdea) return;
    const values = getEditIdeaValues(data, currentIdea);
    if (!checkCorrectAnswers(values)) {
      setShowIncorrectAnswers(true);
      return;
    } else if (checkIsMissingImage(values, startImage, endImage)) {
      setIsImageMissing(true);
      return;
    }
    mutation.mutate(values);
  };

  const handleAddEndImage = img => setEndImage(img);
  const handleAddStartImage = img => setStartImage(img);

  const isLoading =
    isIdeaLoading ||
    isFilesLoading ||
    isEmployeesLoading ||
    isEmployeesApprover;

  const isApprover =
    approverData?.data?.DataApproval?.[0].approverId === userId;

  const { ideaImplemented, statusID } = idea?.[0] || {};
  const implementIdea =
    !ideaImplemented && statusID === IDEA_STATUS_ID.IN_PROCESS && isApprover;
  const inDraft = statusID === IDEA_STATUS_ID.IN_DRAFT;

  return (
    <Container
      sx={{ py: 4 }}
      maxWidth="sm"
    >
      {isLoading && (
        <Box sx={{ textAlign: 'center' }}>
          <CircularProgress />
        </Box>
      )}
      {!isLoading && idea && idea[0] && (
        <FormProvider {...methods}>
          <form onSubmit={methods.handleSubmit(onSubmit)}>
            <Card sx={{ width: '100%' }}>
              <Box sx={{ p: 2 }}>
                <Typography
                  color="textPrimary"
                  variant="h5"
                  component="h1"
                >
                  {t('USER_DATA')}
                </Typography>
              </Box>
              <Divider />
              <UserDataForm
                defaultValues={idea[0]}
                isIdeaDetail
              />
            </Card>
            <Card sx={{ width: '100%', mt: 2 }}>
              <CardHeader
                title={t('IDEA_DATA_SIEN')}
                Icon={InfoIcon}
                message={t('IDEA_SIEN_TOOLTIP')}
              />
              <Divider />
              <IdeaDataForm
                startImage={startImage}
                endImage={endImage}
                selectedUsers={selectedUsers}
                onAddStartImage={handleAddStartImage}
                onAddEndImage={handleAddEndImage}
                isReadOnly={!inDraft}
                defaultValues={idea[0]}
                isIdeaDetail
              />
              {Object.keys(errors).length > 0 && (
                <RequiredFieldsAlert message={t('REQUIRED_FIELDS_ALERT')} />
              )}
              {Object.keys(errors).length === 0 &&
                (showIncorrectAnswers || isImageMissing) && (
                  <RequiredFieldsAlert
                    message={
                      isImageMissing
                        ? t('MISSING_ATTACH_IMAGE')
                        : t('INCORRECT_CREATE_IDEA_DATA')
                    }
                  />
                )}
            </Card>
            {implementIdea && (
              <Card sx={{ width: '100%', mt: 2 }}>
                <Box sx={{ p: 2 }}>
                  <Typography
                    color="textPrimary"
                    variant="h5"
                    component="h1"
                  >
                    {t('IDEA_IMPLEMENTATION')}
                  </Typography>
                </Box>
                <Divider />
                <ImplementationDataForm
                  endImage={endImage}
                  onAddEndImage={handleAddEndImage}
                />
              </Card>
            )}
            <Box
              sx={{
                display: 'flex',
                width: '100%',
                justifyContent: inDraft ? 'space-between' : 'flex-end',
                mt: 2,
              }}
            >
              <Button
                variant="contained"
                onClick={() => navigate(recognitionsRoutes.ideas())}
                color={inDraft ? 'secondary' : 'primary'}
              >
                {t('GO_BACK')}
              </Button>
              {inDraft && (
                <Button
                  variant="contained"
                  type="submit"
                >
                  {t('UPDATE_IDEA')}
                </Button>
              )}
            </Box>
          </form>
        </FormProvider>
      )}
    </Container>
  );
};

export default IdeaDetail;
