import { RedoOutlined } from '@ant-design/icons';
import { t, Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import {
  Button,
  Card,
  Col,
  notification,
  Result,
  Row,
  Space,
  Tooltip,
} from 'antd';
import { useEffect } from 'react';
import { useParams } from 'react-router';
import { ImageAnnotator } from '../../components/annotator';
import {
  AnnotatorProvider,
  useStoreInstance,
} from '../../components/annotator/store-context';
import { EllipsisTitle } from '../../components/ellipsis-typography';
import { DEFAULT_REFRESH_INTERVAL } from '../../consts';
import { StyledUpload, useAntdLocalFiles } from '../../hooks/useAntLocalFiles';
import { useAutoRefreshFlag } from '../../hooks/useAutoRefreshFlag';
import { JobStatus, ModelStatus, ProcessTypes, Template } from '../../models';
import {
  useCreateTemplateOcrJob,
  useTemplateOcrJob,
  useTemplates,
  useUser,
} from '../../queries';
import { extractShapesFromTemplateOcrResults } from '../../utils/shape-convert';
import { ExtractInformation } from './extracted-info';

const TemplatePage = () => {
  const { i18n } = useLingui();
  const userQuery = useUser();
  const storeInstance = useStoreInstance();
  const {
    antdUploadProps,
    selectedFileUri,
    selectedFile,
    reset: resetFileUpload,
  } = useAntdLocalFiles({
    maxCount: 1,
  });
  const { id } = useParams();

  useEffect(() => {
    if (id) {
      resetFileUpload();
      createTemplateOcrJobMutation.reset();
      storeInstance.setShapes([]);
      storeInstance.setBackground('');
    }
  }, [id]);

  const currentTemplate = useCurrentTemplate(Number(id));

  const {
    isRefreshing,
    trigger: triggerRefresh,
    stop: stopRefresh,
  } = useAutoRefreshFlag({
    onStopByTimeout() {
      notification.info({
        message: t(
          i18n,
        )`Request may need more time to process, please click Refresh button to retrieve results.`,
      });
    },
  });
  const createTemplateOcrJobMutation = useCreateTemplateOcrJob();
  const templateOcrQuery = useTemplateOcrJob(
    createTemplateOcrJobMutation.data,
    {
      enabled: createTemplateOcrJobMutation.isSuccess,
      retry: false,
      refetchInterval: isRefreshing ? DEFAULT_REFRESH_INTERVAL : false,
      onSuccess(data: any) {
        if (data.status === JobStatus.Success) {
          const newShapes = extractShapesFromTemplateOcrResults(
            data.data,
            currentTemplate.data?.data_boxs,
          );

          storeInstance.setShapes(newShapes);

          const cropImage = data.files.find(
            (item) => item.file_category === 'Crop',
          )?.file_url;

          if (cropImage) {
            storeInstance.setBackground(cropImage);
          }

          stopRefresh();

          switch (data.data.status) {
            case ModelStatus.BlurryWithData:
            case ModelStatus.BlurryWithoutData:
              notification.warning({
                message: t(i18n)`Key Information Extraction`,
                description: t(
                  i18n,
                )`The results might not be correct because blurriness is detected on the uploaded image.`,
              });
              break;
            case ModelStatus.Success:
              notification.success({
                message: t(i18n)`Key Information Extraction`,
                description: t(i18n)`Data extracted successfully!`,
              });
              break;
            default:
              notification.warning({
                message: t(i18n)`Key Information Extraction`,
                description: t(i18n)`No message from model status`,
              });
          }
        } else {
          if (data.status === JobStatus.ModelFailed) {
            switch (data.data.status) {
              case ModelStatus.NotMatch:
                notification.warning({
                  message: t(i18n)`Key Information Extraction`,
                  description: t(
                    i18n,
                  )`Uploaded image is not match with template.`,
                });
                break;
              case ModelStatus.Failed:
                notification.warning({
                  message: t(i18n)`Key Information Extraction`,
                  description: t(
                    i18n,
                  )`Can not extract information from uploaded image.`,
                });
                break;
              default:
                notification.warning({
                  message: t(i18n)`Key Information Extraction`,
                  description: t(i18n)`No message from model status`,
                });
            }
            stopRefresh();
          } else if (!isRefreshing) {
            notification.info({
              message: t(i18n)`Key Information Extraction`,
              description: t(
                i18n,
              )`Request may need more time to process, please click Refresh button to retrieve results.`,
            });
          }
        }
      },
    },
  );

  if (currentTemplate.isSuccess && !currentTemplate.data) {
    return (
      <Result
        status="404"
        title="404"
        subTitle={t(
          i18n,
        )`You can't use this template. It may have been deleted or you don't have permission to use it.`}
      />
    );
  }

  return (
    <Row
      style={{
        height: '100%',
        width: '100%',
      }}
      gutter={[8, 8]}
      align="stretch"
    >
      <Col span={16} style={{ height: '100%' }}>
        <Card
          bordered
          title={
            <EllipsisTitle
              ellipsis
              level={4}
              style={{
                marginBottom: 0,
                marginRight: 8,
              }}
            >
              {currentTemplate.data?.name}
            </EllipsisTitle>
          }
          extra={
            <Space>
              <Button
                type="primary"
                onClick={async () => {
                  try {
                    await createTemplateOcrJobMutation.mutateAsync({
                      file: selectedFile.originFileObj,
                      processType: ProcessTypes.Template,
                      userId: userQuery.data?.userId,
                      templateId: currentTemplate.data?.id,
                    });
                    triggerRefresh();
                    notification.success({
                      message: t(i18n)`Key Information Extraction`,
                      description: t(
                        i18n,
                      )`Extract information has been queued successfully.`,
                    });
                  } catch (error) {
                    notification.error({
                      message: t(i18n)`Key Information Extraction`,
                      description: t(i18n)`Extract information error: ${error}`,
                    });
                  }
                }}
                disabled={!selectedFile}
                loading={createTemplateOcrJobMutation.isLoading || isRefreshing}
              >
                <Trans>Start Recognition</Trans>
              </Button>
              {createTemplateOcrJobMutation.isSuccess && !isRefreshing && (
                <Tooltip title={<Trans>Refresh</Trans>}>
                  <Button
                    onClick={() => templateOcrQuery.refetch()}
                    disabled={
                      templateOcrQuery.data?.status === JobStatus.Success ||
                      templateOcrQuery.data?.status === JobStatus.ModelFailed
                    }
                    icon={<RedoOutlined spin={templateOcrQuery.isFetching} />}
                  />
                </Tooltip>
              )}
            </Space>
          }
          style={{
            height: '100%',
            display: 'flex',
            flexDirection: 'column',
          }}
          bodyStyle={{
            overflow: 'auto',
            display: 'flex',
            flexDirection: 'column',
            flex: 1,
            padding: 8,
          }}
        >
          <ImageAnnotator
            background={selectedFileUri}
            initialShapes={[]}
            readOnly
          />
          <div style={{ height: 8 }} />
          <StyledUpload
            accept=".jpg,.png,.jpeg"
            listType="picture-card"
            {...antdUploadProps}
            onChange={({ fileList, ...rest }) => {
              antdUploadProps.onChange({ fileList, ...rest });
              storeInstance.setShapes([]);
              createTemplateOcrJobMutation.reset();
            }}
          >
            {antdUploadProps.fileList.length <= 8 && <Trans>+ Upload</Trans>}
          </StyledUpload>
        </Card>
      </Col>
      <Col span={8} style={{ height: '100%' }}>
        <ExtractInformation />
      </Col>
    </Row>
  );
};

function useCurrentTemplate(id: Template['id']) {
  const userQuery = useUser();
  const templatesQuery = useTemplates(userQuery.data?.userId, {
    retry: false,
    enabled: userQuery.isSuccess,
  });

  return {
    isLoading: userQuery.isLoading || templatesQuery.isLoading,
    isSuccess: userQuery.isSuccess && templatesQuery.isSuccess,
    isError: userQuery.isError || templatesQuery.isError,
    data: templatesQuery.data?.find((item) => item.id === id),
  };
}

export default function () {
  return (
    <AnnotatorProvider>
      <TemplatePage />
    </AnnotatorProvider>
  );
}
