import { FC, useState } from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import { useQuery, useMutation } from 'react-query';
import { 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 Button from '@material-hu/components/design-system/Buttons/Button';

import { defaultValues } from 'src/constants/recognitions';
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 SuccessIdea from 'src/pages/dashboard/recognitions/components/SuccessIdea';
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 {
  getPlants,
  getAreas,
  getSupervisors,
  createIdea,
  uploadFile,
  addEmployee,
} from 'src/services/recognitions';
import {
  transformPlantsData,
  transformAreasData,
  transformSupervisorsData,
  getOptionName,
  getUserData,
  getUserId,
  checkCorrectAnswers,
  checkIsMissingImage,
  getFolio,
  getOptionSupervisor,
  getImageBody,
} from 'src/utils/recognitions';

import GoBackButton from 'src/components/dashboard/GoBackButton';

export const CreateIdea: FC = () => {
  const userId = getUserId();
  const userData = getUserData();

  const methods = useForm({ defaultValues });

  const { t } = useTranslation();
  const navigate = useNavigate();

  const [openConfirmPage, setOpenConfirmPage] = useState(false);
  const [confirmMessage, setConfirmMessage] = useState(null);
  const [showIncorrectAnswers, setShowIncorrectAnswers] = useState(false);
  const [isImageMissing, setIsImageMissing] = useState(false);

  const [startImage, setStartImage] = useState(null);
  const [endImage, setEndImage] = useState(null);
  const [selectedUsers, setSelectedUsers] = useState([]);
  const [loadingAssets, setLoadingAssets] = useState(false);

  const selectedEmployeePlantId = methods.watch('employeePlantID');
  const selectedEmployeeAreaId = methods.watch('employeeAreaID');
  const selectedIdeaPlantId = methods.watch('ideaPlantID');

  const { data: plants, isLoading: isLoadingPlants } = useQuery(
    recognitionsKeys.plants(),
    () => getPlants(),
  );

  const { data: employeeAreas, isLoading: isLoadingEmployeeAreas } = useQuery(
    recognitionsKeys.employeeArea(selectedEmployeePlantId),
    () => getAreas(selectedEmployeePlantId),
    {
      enabled: !!selectedEmployeePlantId,
      onSuccess: () => {
        methods.setValue('employeeAreaID', '');
      },
    },
  );

  const { data: supervisors, isLoading: isLoadingSupervisors } = useQuery(
    recognitionsKeys.employeeSupervisor(selectedEmployeeAreaId),
    () => getSupervisors(selectedEmployeeAreaId),
    {
      enabled: !!selectedEmployeeAreaId,
      onSuccess: () => {
        methods.setValue('managerID', '');
      },
    },
  );

  const { data: ideaAreas, isLoading: isLoadingIdeaAreas } = useQuery(
    recognitionsKeys.ideaArea(selectedIdeaPlantId),
    () => getAreas(selectedIdeaPlantId),
    {
      enabled: !!selectedIdeaPlantId,
      onSuccess: () => {
        methods.setValue('ideaAreaID', '');
      },
    },
  );

  const plantsData = transformPlantsData(plants);
  const employeeAreasData = employeeAreas?.data?.Areas
    ? transformAreasData(employeeAreas)
    : [];
  const supervisorsData = supervisors?.data?.Supervisores
    ? transformSupervisorsData(supervisors)
    : [];
  const ideasAreasData = ideaAreas?.data?.Areas
    ? transformAreasData(ideaAreas)
    : [];

  const mutation = useMutation(createIdea, {
    onSuccess: async (response, variables) => {
      const { StatusCode, ExtraCode, Message } = response.data;
      if (StatusCode === '0') {
        const folio = getFolio(Message);
        const startImageBody = getImageBody(
          folio,
          startImage,
          endImage,
          userId,
          true,
        );

        const uploadPromises = [uploadFile(startImageBody)];
        if (variables.ideaImplemented) {
          const endImageBody = getImageBody(
            folio,
            startImage,
            endImage,
            userId,
            false,
          );
          uploadPromises.push(uploadFile(endImageBody));
        }

        let employeePromises = [];
        if (variables.team) {
          employeePromises = selectedUsers.map(user => {
            return addEmployee({
              folio,
              employeeId: user.EmployeeNumber,
              employeeName: user.EmployeeName,
              authorId: userId,
            });
          });
        }
        const allPromises = [...uploadPromises, ...employeePromises];
        await Promise.all(allPromises);
        setLoadingAssets(false);
        setOpenConfirmPage(true);
        setConfirmMessage(ExtraCode);
      }
    },
  });

  const onSubmit = data => {
    if (!checkCorrectAnswers(data)) {
      setShowIncorrectAnswers(true);
      return;
    } else if (checkIsMissingImage(data, startImage, endImage)) {
      setIsImageMissing(true);
      return;
    }

    const values = {
      ...data,
      employeeID: userData.UserId,
      employeeArea: getOptionName(data.employeeAreaID, employeeAreasData),
      employeePlant: getOptionName(data.employeePlantID, plantsData),
      ideaPlant: getOptionName(data.ideaPlantID, plantsData),
      ideaArea: getOptionName(data.ideaAreaID, ideasAreasData),
      manager: getOptionSupervisor(data.managerID, supervisorsData),
      managerID: 0,
      modifiedBy: userData.UserId,
      createdBy: userData.UserId,
      categoryID: data.category,
    };
    setLoadingAssets(true);
    mutation.mutate(values);
  };

  const isLoading = mutation.isLoading && loadingAssets;

  const handleGoBack = () => navigate(recognitionsRoutes.home());

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

  const handleAddSelectedUsers = users => setSelectedUsers(users);

  const { errors } = methods.formState;

  if (!userId) {
    navigate(recognitionsRoutes.home());
  }

  if (!openConfirmPage) {
    return (
      <Container
        sx={{ py: 4 }}
        maxWidth="sm"
      >
        {isLoadingPlants && (
          <Box
            sx={{
              display: 'flex',
              width: '100%',
              justifyContent: 'center',
              mt: 4,
            }}
          >
            <CircularProgress />
          </Box>
        )}
        {!isLoadingPlants && (
          <>
            <GoBackButton onClick={handleGoBack} />
            <FormProvider {...methods}>
              <form onSubmit={methods.handleSubmit(onSubmit)}>
                <Card sx={{ width: '100%' }}>
                  <CardHeader title={t('USER_DATA')} />
                  <Divider />
                  {userData && plantsData && (
                    <UserDataForm
                      userData={userData}
                      plantsData={plantsData}
                      areasData={employeeAreasData}
                      supervisorsData={supervisorsData}
                      isLoadingAreas={isLoadingEmployeeAreas}
                      isLoadingSupervisors={isLoadingSupervisors}
                    />
                  )}
                </Card>
                <Card sx={{ width: '100%', mt: 3 }}>
                  <CardHeader
                    title={t('IDEA_DATA_SIEN')}
                    Icon={InfoIcon}
                    message={t('IDEA_SIEN_TOOLTIP')}
                  />
                  <Divider />
                  <IdeaDataForm
                    plantsData={plantsData}
                    areasData={ideasAreasData}
                    isLoadingAreas={isLoadingIdeaAreas}
                    onAddStartImage={handleAddStartImage}
                    onAddEndImage={handleAddEndImage}
                    startImage={startImage}
                    endImage={endImage}
                    onAddSelectedUsers={handleAddSelectedUsers}
                    selectedUsers={selectedUsers}
                  />
                  {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>
                <Box
                  sx={{
                    display: 'flex',
                    width: '100%',
                    justifyContent: 'flex-end',
                    mt: 2,
                  }}
                >
                  <Button
                    variant="contained"
                    type="submit"
                    disabled={isLoading}
                    loading={isLoading}
                  >
                    {t('CREATE_IDEA')}
                  </Button>
                </Box>
              </form>
            </FormProvider>
          </>
        )}
      </Container>
    );
  }

  return <SuccessIdea message={confirmMessage} />;
};

export default CreateIdea;
