import { t, Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { useQueryClient } from '@tanstack/react-query';
import { Button, Card, Col, Form, Input, notification, Row } from 'antd';
import { useNavigate } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid';
import { ImageAnnotator } from '../../components/annotator';
import {
  AnnotatorProvider,
  useStoreInstance,
} from '../../components/annotator/store-context';
import { ShapeConfig, ShapeTypes } from '../../components/annotator/types';
import { StyledUpload, useAntdLocalFiles } from '../../hooks/useAntLocalFiles';
import { ApiCode } from '../../models';
import { useCreateTemplateJob, useUser } from '../../queries';
import { shapesToStringData } from '../../utils/shape-convert';
import { validateTemplate } from '../../utils/template-validation';
import { validationPatterns } from '../../utils/validation-patterns';
import { AnchorsPosition } from './anchors-position';
import { ExtractedFields } from './extracted-fields';

const defaultAnchors: ShapeConfig[] = [
  {
    id: uuidv4(),
    type: ShapeTypes.RECTANGLE,
    x: 10,
    y: 10,
    width: 150,
    height: 150,
    isAnchor: true,
    stroke: 'rgb(0,255,0)',
    fill: 'rgba(0,255,0,0.2)',
    strokeWidth: 4,
  },
  {
    id: uuidv4(),
    type: ShapeTypes.RECTANGLE,
    x: 170,
    y: 10,
    width: 150,
    height: 150,
    isAnchor: true,
    stroke: 'rgb(0,255,0)',
    fill: 'rgba(0,255,0,0.2)',
    strokeWidth: 4,
  },
  {
    id: uuidv4(),
    type: ShapeTypes.RECTANGLE,
    x: 10,
    y: 170,
    width: 150,
    height: 150,
    isAnchor: true,
    stroke: 'rgb(0,255,0)',
    fill: 'rgba(0,255,0,0.2)',
    strokeWidth: 4,
  },
];

const CreateTemplatePage = () => {
  const { i18n } = useLingui();
  const navigate = useNavigate();
  const storeInstance = useStoreInstance();
  const { antdUploadProps, selectedFileUri, selectedFile } = useAntdLocalFiles({
    maxCount: 1,
  });
  const [form] = Form.useForm<{ name: string }>();
  const userQuery = useUser();
  const queryClient = useQueryClient();

  const createTemplateJobMutation = useCreateTemplateJob({
    onSuccess(data) {
      navigate('/template-settings');
      queryClient.invalidateQueries({
        queryKey: ['list-templates', userQuery.data?.userId],
      });
    },
  });

  return (
    <Row
      style={{
        height: '100%',
        width: '100%',
      }}
      gutter={[8, 8]}
      align="stretch"
    >
      <Col span={16} style={{ height: '100%' }}>
        <Card
          bordered
          title={
            <Row justify="space-between" style={{ paddingTop: 16 }}>
              <Form form={form} initialValues={{ name: '' }}>
                <Form.Item
                  name={['name']}
                  label={<Trans>Template name</Trans>}
                  rules={[
                    {
                      required: true,
                      message: t(i18n)`Please, specify a template name.`,
                    },
                    {
                      pattern:
                        validationPatterns.validateStringMaxLength.pattern,
                      message:
                        validationPatterns.validateStringMaxLength.message,
                    },
                    {
                      whitespace: true,
                      message: t(
                        i18n,
                      )`Template name can not contain white spaces only.`,
                    },
                  ]}
                >
                  <Input style={{ width: 340 }} size="middle" />
                </Form.Item>
              </Form>
              <Button
                type="primary"
                onClick={async () => {
                  const formValues = await form.validateFields();

                  let templateValidation = validateTemplate(
                    storeInstance.getStore().shapes,
                  );

                  if (!templateValidation.status) {
                    notification.warning({
                      message: t(i18n)`Template Settings`,
                      description: t(
                        i18n,
                      )`Create template error: ${templateValidation.message}`,
                    });
                    return;
                  }

                  try {
                    const templateData = shapesToStringData(
                      storeInstance.getStore().shapes,
                    );

                    await createTemplateJobMutation.mutateAsync({
                      file: selectedFile.originFileObj,
                      userId: userQuery.data?.userId,
                      listNameBox: templateData.listNameBox,
                      listBBox: templateData.listBBox,
                      listAnchor: templateData.listAnchor,
                      tempName: formValues.name,
                    });
                    notification.success({
                      message: t(i18n)`Template Settings`,
                      description: t(i18n)`Create template successfully.`,
                    });
                  } catch (error) {
                    if (error.response.data.code == ApiCode.DuplicateBox) {
                      notification.warning({
                        message: t(i18n)`Template Settings`,
                        description: t(
                          i18n,
                        )`Create template error: Extracted fields must have unique labels.`,
                      });
                    } else {
                      notification.error({
                        message: t(i18n)`Template Settings`,
                        description: t(i18n)`Create template error: ${error}`,
                      });
                    }
                  }
                }}
                disabled={!selectedFile}
                loading={createTemplateJobMutation.isLoading}
              >
                <Trans>Create Template</Trans>
              </Button>
            </Row>
          }
          style={{
            height: '100%',
            display: 'flex',
            flexDirection: 'column',
          }}
          bodyStyle={{
            overflow: 'auto',
            display: 'flex',
            flexDirection: 'column',
            flex: 1,
            padding: 8,
          }}
        >
          <ImageAnnotator background={selectedFileUri} initialShapes={[]} />
          <div style={{ height: 8 }} />
          <StyledUpload
            accept=".jpg,.png,.jpeg,"
            listType="picture-card"
            {...antdUploadProps}
            onChange={({ fileList, ...rest }) => {
              antdUploadProps.onChange({ fileList, ...rest });
              storeInstance.setShapes(defaultAnchors);
            }}
          >
            {antdUploadProps.fileList.length <= 8 && <Trans>+ Upload</Trans>}
          </StyledUpload>
        </Card>
      </Col>
      <Col
        span={8}
        style={{
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          gap: 8,
        }}
      >
        <AnchorsPosition />
        <ExtractedFields />
      </Col>
    </Row>
  );
};

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