import React from 'react';
import { Form, Input, Row, Col } from 'antd';
import {
  EasyTwinRenderer,
  FileInfo,
  FileTypeEnum,
  StateConfig,
  PointStateConfig,
  PoiInfoPannelTemplate,
  AssetInfo,
  ObjectPropsSyncChange,
} from '@easytwin/core';

import { LockIcon } from '@/components';
import { FileCard } from '@/pages/FileManage/components';

export interface PointFormProp {
  initData: StateConfig;
  easyTwinRenderer?: EasyTwinRenderer;
  onValuesChanges?: (values: Pick<AssetInfo, 'config'>) => void;
}

type FormValuesChangeType = Omit<PointStateConfig, 'imgFileId'> & {
  imgFileId?: FileInfo;
};

const PointForm: React.FC<PointFormProp> = function ({
  initData,
  easyTwinRenderer,
  onValuesChanges,
}) {
  const [form] = Form.useForm();
  const [fileInfo, setFileInfo] = React.useState<FileInfo>();
  const [editingData, setEditingData] = React.useState<PointStateConfig>(
    initData as PointStateConfig,
  );
  React.useEffect(() => {
    form.setFieldsValue(editingData);
  }, [form, editingData]);

  React.useEffect(() => {
    if (!easyTwinRenderer || !editingData || !fileInfo) return;

    const templateId = 'asstePointPerviewTemplate';
    const id = 'asstePointPerview';

    const viewport = easyTwinRenderer.getViewport();

    const oldtemplate = viewport.templateController.getTemplate<PoiInfoPannelTemplate>(templateId);
    if (oldtemplate) {
      oldtemplate.remove();
      oldtemplate.dispose();
    }

    const template = viewport.templateController.createPoiInfoPannelTemplate({
      id: templateId,
      backgroundStyle: {
        url: fileInfo.url,
        size: {
          x: Number(editingData.width),
          y: Number(editingData.height),
        },
      },
    });

    template.add({
      id,
      position: {
        x: 0,
        y: 0,
        z: 0,
      },
      rowData: [],
    });

    viewport.update();
  }, [easyTwinRenderer, editingData, fileInfo]);

  return (
    <div className="PointForm">
      <Form
        form={form}
        labelCol={{
          span: 6,
        }}
        wrapperCol={{
          span: 18,
        }}
        colon={false}
        labelAlign="left"
        onValuesChange={(_, allValues: FormValuesChangeType) => {
          const newData: PointStateConfig = {
            ...editingData,
            ...allValues,
            imgFileId: editingData.imgFileId,
            imgFileUrl: editingData.imgFileUrl,
          };

          const { imgFileId } = allValues;
          if (imgFileId && typeof imgFileId !== 'string') {
            newData.imgFileId = imgFileId.id;
            newData.imgFileUrl = imgFileId.url;

            setFileInfo(imgFileId);
          }

          const syncAfterData = ObjectPropsSyncChange(
            editingData as PointStateConfig,
            newData,
            'lockedSize',
            ['width', 'height'],
          );
          setEditingData(syncAfterData);

          onValuesChanges?.({
            config: {
              stateConfig: syncAfterData,
            },
          });
        }}>
        {/* 背景图 */}
        <Form.Item name="imgFileId" label="背景图" className="!mb-2">
          <FileCard
            mode={FileTypeEnum.IMAGE}
            changedValueType="info"
            innerContextClassName="p-2"
            showDeleteBtn={false}
          />
        </Form.Item>

        {/* 尺寸 */}
        <Form.Item label="尺寸" className="!mb-2">
          <Input.Group size="small">
            <Row gutter={8}>
              <Col span={10}>
                <Form.Item name="width" className="!mb-0">
                  <Input size="small" suffix="W" />
                </Form.Item>
              </Col>
              <Col span={10}>
                <Form.Item name="height" className="!mb-0">
                  <Input size="small" suffix="H" />
                </Form.Item>
              </Col>
              <Col span={4}>
                <Form.Item name="lockedSize" className="!mb-0">
                  <LockIcon bordered className="!w-7 !h-7" />
                </Form.Item>
              </Col>
            </Row>
          </Input.Group>
        </Form.Item>
      </Form>
    </div>
  );
};

export default PointForm;
