import { type FC, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useNavigate, useParams } from 'react-router-dom';

import { type TFunction } from 'i18next';
import AvatarUI from '@material-hu/mui/Avatar';
import Box from '@material-hu/mui/Box';
import Chip from '@material-hu/mui/Chip';
import { grey } from '@material-hu/mui/colors';
import { styled, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';
import useMediaQuery from '@material-hu/mui/useMediaQuery';

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

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { useMassiveAssign } from 'src/pages/dashboard/forms/MassiveAssignContext';
import {
  assignApprovalWorkflow,
  cancelFormAnswer,
  fetchFormCompletedPdfBlob,
} from 'src/services/forms';
import { getProfileById } from 'src/services/users';
import {
  FormStatus,
  FormStepType,
  FormType,
  type StepType,
} from 'src/types/forms';
import { openBlob } from 'src/utils/files';
import { getLabel } from 'src/utils/form';
import { useLokaliseTranslation } from 'src/utils/i18n';

import RegularChatName from 'src/components/dashboard/chat/ChatName/RegularChatName';
import { MakeAction } from 'src/components/dashboard/form/approvalWorkflow';
import FormConfirmationDialogWithReason from 'src/components/dashboard/form/FormConfirmationDialogWithReason';
import {
  formKeys,
  removeFormChatNotification,
  updateListsForms,
} from 'src/components/dashboard/form/queries';
import { formRoutes } from 'src/components/dashboard/form/routes';
import GoBackButton from 'src/components/dashboard/GoBackButton';
import LoadingButton from 'src/components/LoadingButton';

const Container = styled(Box)(({ theme }) => ({
  display: 'flex',
  flexShrink: 0,
  flexDirection: 'row',
  alignItems: 'center',
  justifyContent: 'space-between',
  backgroundColor: theme.palette.background.paper,
  borderBottom: `1px solid ${theme.palette.divider}`,
  minHeight: 64,
  padding: theme.spacing(1, 2),
  overflowX: 'hidden',
  zIndex: 1,
  width: '100%',
}));

const TitleContainer = styled(Box)(() => ({
  width: '100%',
  display: 'flex',
  flexDirection: 'column',
  alignItems: 'flex-start',
}));

const Avatar = styled(AvatarUI)(() => ({
  display: 'flex',
  justifyContent: 'center',
  backgroundColor: '#1264A3',
  borderRadius: '50%',
  alignItems: 'center',
  marginRight: '18px',
}));

type StatusProps = {
  mobile?: boolean;
};

const Status = styled(Chip)<StatusProps>(({ theme, mobile }) => ({
  maxWidth: 'max-content',
  width: '100%',
  color: theme.palette.new.text.neutral.inverted,
  marginTop: mobile ? theme.spacing(0.5) : 0,
  marginLeft: mobile ? 0 : theme.spacing(2),
  marginBottom: mobile ? 0 : theme.spacing(0.5),
  '&.unassigned': {
    backgroundColor: grey[700],
  },
  '&.pending': {
    backgroundColor: grey[700],
  },
  '&.approved': {
    backgroundColor: theme.palette.success.main,
  },
  '&.rejected': {
    backgroundColor: theme.palette.error.main,
  },
  '&.cancelled': {
    backgroundColor: theme.palette.warning.main,
  },
}));

const ButtonsContainer = styled(Box)(({ theme }) => ({
  display: 'block',
  textAlign: 'center',
  '& .actionBtn': {
    minWidth: '200px',
    fontStyle: 'italic',
    marginTop: theme.spacing(4),
    textTransform: 'uppercase',
  },
}));

export type ApprovalWorkflowHeaderProps = {
  pictureUrl: string;
  title: string;
  approvalStatus: FormStatus;
  templateId: number;
  steps: StepType[];
  isResponsible: boolean;
  viewAgent?: boolean;
  canEditAnswer?: boolean;
  userId: number;
  lastStep?: any;
  stepsType?: string;
  handleApprove: () => void;
  handleReject: () => void;
};

const assignApprovalWorkflowWrap = ({ formId, stepId, body }) =>
  assignApprovalWorkflow(formId, stepId, body);

const ApprovalWorkflowHeader: FC<ApprovalWorkflowHeaderProps> = props => {
  const {
    pictureUrl,
    title,
    approvalStatus,
    templateId,
    steps,
    viewAgent,
    userId,
    lastStep,
    handleApprove,
    handleReject,
    stepsType,
    canEditAnswer,
  } = props;

  const [isLoadingPdf, setIsLoadingPdf] = useState<boolean>(false);
  const [isOpen, setIsOpen] = useState(false);

  const { removeItem } = useMassiveAssign();

  const { id } = useParams();
  const queryClient = useQueryClient();
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();
  const { user } = useAuth();
  const navigate = useNavigate();

  const { t } = useLokaliseTranslation('forms');

  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  const postMutation = useMutation(assignApprovalWorkflowWrap, {
    onSuccess: () => {
      queryClient.invalidateQueries(formKeys.formApprovalWorkflow(Number(id)));

      updateListsForms();
      removeFormChatNotification();
      removeItem(Number(id));
      enqueueSnackbar({ title: t('SUCCESS_ASSIGN_FORM'), variant: 'success' });
    },
    onError: error => {
      showGeneralError(error, t('ERROR_ASSIGN_FORM'));
    },
  });

  const { mutate: cancelFormMutate, isLoading } = useMutation(
    (reason: string) => cancelFormAnswer(Number(id), reason),
    {
      onError: err => {
        showGeneralError(err, t('ERROR_CANCEL_ANSWER'));
      },
      onSuccess: () => {
        queryClient.invalidateQueries(
          formKeys.formApprovalWorkflow(Number(id)),
        );
        queryClient.invalidateQueries(formKeys.listCompleted(FormType.FORM));
        enqueueSnackbar({
          title: t('FORMS:SUCCESS_CANCEL_ANSWER'),
          variant: 'success',
        });
        setIsOpen(false);
      },
    },
  );

  const completedId = steps[0].lastTransaction?.formId;

  const isPdfAnswer = stepsType === FormStepType.FILE;

  const { data } = useQuery(
    ['userProfile', Number(userId)],
    () => getProfileById(userId),
    {
      enabled: !!userId,
    },
  );

  const userData = data?.data || undefined;

  const handleShowForm = () => {
    navigate(
      isPdfAnswer
        ? formRoutes.form.pdfCompleted(FormType.FORM, templateId, id)
        : formRoutes.form.completed(FormType.FORM, templateId, completedId),
    );
  };

  const handleAssign = () => {
    postMutation.mutate({
      formId: id,
      stepId: lastStep.stepId,
      body: { responsibleId: user.id },
    });
  };

  const handleDownloadPdf = async () => {
    try {
      setIsLoadingPdf(true);

      const pdfData = await queryClient.fetchQuery(
        formKeys.pdf.blob(templateId, completedId),
        () => fetchFormCompletedPdfBlob(templateId, completedId),
      );

      const { blob = null, blobUrl = null } = pdfData || {};

      openBlob(blob, blobUrl);
    } catch (err) {
      showGeneralError(err, t('ERROR_LOADING_PDF_REPORT'));
    } finally {
      setIsLoadingPdf(false);
    }
  };

  const handleBack = e => {
    e.preventDefault();
    navigate(formRoutes.requests.general(FormType.FORM));
  };

  const handleEditForm = () =>
    navigate(formRoutes.form.edit(FormType.FORM, templateId, id));

  const handleCancelForm = () => setIsOpen(true);

  const handleCloseDialog = () => setIsOpen(false);

  const submit = ({ message }) => cancelFormMutate(message);

  const actionHandlers = {
    UNASSIGNED: { handleAssign },
    PENDING: { handleApprove, handleReject },
  };

  const actionTitles = {
    UNASSIGNED: {
      unassignedTitle: t('ASSIGN_ME_FORM'),
    },
    PENDING: {
      approveTitle: t('APPROVE_FORM'),
      rejectTitle: t('REJECT_FORM'),
    },
  };

  const isAgent = userId !== user?.id;
  const isFinishFlow = [
    FormStatus.APPROVED,
    FormStatus.REJECTED,
    FormStatus.CANCELLED,
  ].includes(approvalStatus);

  return (
    <>
      <Container>
        <Box
          sx={{
            display: 'flex',
            flex: 1,
            alignItems: 'center',
            justifyContent: 'flex-start',
          }}
        >
          {(!isAgent || isMobile) && (
            <GoBackButton
              sx={{ alignSelf: 'center', mr: 1, minWidth: '40px' }}
              onClick={handleBack}
            />
          )}
          <Avatar variant="square">
            <img
              src={pictureUrl}
              alt=""
              style={{
                height: '65%',
                width: '65%',
              }}
            />
          </Avatar>
          <TitleContainer>
            <Typography
              color="textPrimary"
              noWrap
              variant="subtitle2"
            >
              {title}
            </Typography>
            {userData && isAgent && (
              <RegularChatName
                otherUser={userData}
                color="info.dark"
                sx={{ ml: '0 !important' }}
              />
            )}
            {isMobile && (
              <Status
                mobile
                color="primary"
                label={getLabel(true, approvalStatus, t as TFunction)}
                size="small"
                className={approvalStatus.toLowerCase()}
              />
            )}
          </TitleContainer>
          {!isMobile && (
            <Status
              color="primary"
              label={getLabel(true, approvalStatus, t as TFunction)}
              size="small"
              className={approvalStatus.toLowerCase()}
            />
          )}
        </Box>
      </Container>
      {viewAgent && !isFinishFlow && (
        <Box
          sx={{
            backgroundColor: 'background.paper',
            minHeight: 50,
            width: '100%',
            zIndex: 1,
          }}
        >
          <MakeAction
            approvalStatus={lastStep?.approvalStatus}
            {...actionHandlers[lastStep?.approvalStatus]}
            {...actionTitles[lastStep?.approvalStatus]}
          />
        </Box>
      )}
      <ButtonsContainer
        sx={{
          paddingTop: isFinishFlow ? '20px' : '0px',
        }}
      >
        {!viewAgent && canEditAnswer && (
          <Button
            variant="contained"
            className="actionBtn"
            sx={{ mr: 2 }}
            size="large"
            color="primary"
            onClick={handleEditForm}
          >
            {t('EDIT_MY_FORM')}
          </Button>
        )}
        <Button
          variant="contained"
          className="actionBtn"
          sx={{ mr: 2 }}
          size="large"
          color="primary"
          onClick={handleShowForm}
        >
          {viewAgent ? t('SHOW_FORM') : t('SHOW_MY_FORM')}
        </Button>
        {!viewAgent && !isFinishFlow && (
          <Button
            variant="contained"
            className="actionBtn"
            sx={{ mr: 2 }}
            size="large"
            color="primary"
            onClick={handleCancelForm}
          >
            {t('CANCEL_ANSWER')}
          </Button>
        )}
        {!isPdfAnswer && (
          <LoadingButton
            variant="contained"
            className="actionBtn"
            size="large"
            color="primary"
            onClick={handleDownloadPdf}
            disabled={isLoadingPdf}
            loading={isLoadingPdf}
            loadingPosition="start"
          >
            {t('DOWNLOAD_ANSWER')}
          </LoadingButton>
        )}
      </ButtonsContainer>
      <FormConfirmationDialogWithReason
        open={isOpen}
        onClose={handleCloseDialog}
        title={t('CANCEL_ANSWER')}
        acceptLabel={t('CANCEL_ANSWER_CONFIRM')}
        description={t('CANCEL_ANSWER_DESCRIPTION')}
        placeholder={t('CANCEL_ANSWER_PLACEHOLDER')}
        submit={submit}
        acceptDisabled
        showCancel
        isLoading={isLoading}
      />
    </>
  );
};

export default ApprovalWorkflowHeader;
