import { getCircleRadius } from '@/utils/slave/sgw/geomUtils';
import { PlusOutlined } from '@ant-design/icons';
import {
  ProFormDigit,
  ProFormInstance,
  ProFormItem,
  ProFormText,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Button, Col, Flex, Form, Input, Row, Tag, Tooltip } from 'antd';
import { MutableRefObject, useMemo, useState } from 'react';
import {
  CircleGeometry,
  GeometryType,
  PolygonGeometry,
  tagPlusStyle,
  validateGeometry,
  ZoneFormData,
  ZoneFormField,
} from '../type';
import PolygonModal from './PolygonModal';

type GeometryFormProps = {
  shape?: number;
  form: MutableRefObject<ProFormInstance<ZoneFormData> | null | undefined>;
  zoneData?: SgwModel.Geom;
};

const GeometryForm = ({ shape, form }: GeometryFormProps) => {
  const [isPolygonModalOpen, setIsPolygonModalOpen] = useState<boolean>(false);
  const [indexTag, setIndexTag] = useState<number>(-1);
  const intl = useIntl();
  const polygonGeometry =
    (Form.useWatch(
      ZoneFormField.PolygonGeometry,
      form.current || undefined,
    ) as PolygonGeometry[]) || [];

  // Circle area calculation (subscribe to Radius so it updates)
  const area = Form.useWatch(
    [ZoneFormField.CircleData, 'area'],
    form.current || undefined,
  ) as number | undefined;

  const radiusArea = useMemo(() => {
    if (shape === GeometryType.CIRCLE) {
      if (area && area > 0) {
        return getCircleRadius(area);
      }
    }
    return 0;
  }, [shape, area]);

  const handleRemovePolygon = (index: number) => {
    const newPolygons = polygonGeometry.filter(
      (_, i) => i !== index,
    ) as PolygonGeometry[];
    form.current?.setFieldsValue({
      [ZoneFormField.PolygonGeometry]: newPolygons,
    });
  };

  const handleEditPolygon = (index: number) => {
    setIsPolygonModalOpen(true);
    setIndexTag(index);
  };

  // Format coordinates for display
  const formatCoords = (coords: number[][]) => {
    return coords.map((c) => `[${c[0]}, ${c[1]}]`).join(', ');
  };

  switch (shape) {
    case GeometryType.POLYGON:
      return (
        <>
          <ProFormItem
            name={ZoneFormField.PolygonGeometry}
            label={intl.formatMessage({
              id: 'banzone.geometry.coordinates',
              defaultMessage: 'Tọa độ',
            })}
            required
          >
            <Flex gap="10px 4px" wrap>
              {polygonGeometry.map((polygon, index) => (
                <Tooltip
                  key={index}
                  title={formatCoords(polygon.geometry) || ''}
                >
                  <Tag
                    closable
                    onClose={(e) => {
                      e.preventDefault();
                      handleRemovePolygon(index);
                    }}
                    onClick={() => handleEditPolygon(index)}
                    color="blue"
                    style={{ cursor: 'pointer' }}
                  >
                    {intl.formatMessage({
                      id: 'banzones.title',
                      defaultMessage: 'Khu vực',
                    })}{' '}
                    {index + 1}
                  </Tag>
                </Tooltip>
              ))}
              <Button
                style={tagPlusStyle}
                icon={<PlusOutlined />}
                onClick={() => {
                  setIndexTag(-1);
                  setIsPolygonModalOpen(true);
                }}
              >
                <FormattedMessage
                  id="banzone.geometry.add_zone"
                  defaultMessage="Thêm vùng"
                />
              </Button>
            </Flex>
          </ProFormItem>
          <PolygonModal
            isVisible={isPolygonModalOpen}
            setVisible={setIsPolygonModalOpen}
            initialData={polygonGeometry}
            index={indexTag}
            handleSubmit={async (values) => {
              form.current?.setFieldsValue({
                [ZoneFormField.PolygonGeometry]: values,
              });
              setIndexTag(-1);
              setIsPolygonModalOpen(false);
            }}
          />
        </>
      );

    case GeometryType.LINESTRING:
      return (
        <ProFormItem
          required
          rules={[
            {
              required: true,
              message: intl.formatMessage({
                id: 'banzone.geometry.coordinates.not_empty',
                defaultMessage: 'Tọa độ không được để trống!',
              }),
            },
            {
              validator: (_: any, value: string) => {
                return validateGeometry(value);
              },
            },
          ]}
          name={ZoneFormField.PolylineData}
          label={intl.formatMessage({
            id: 'banzone.geometry.coordinates',
            defaultMessage: 'Tọa độ',
          })}
          tooltip={intl.formatMessage({
            id: 'banzone.geometry.coordinates.tooltip',
            defaultMessage:
              'Danh sách các toạ độ theo định dạng: [[longitude,latitude],[longitude,latitude],...]',
          })}
        >
          <Input.TextArea
            autoSize={{ minRows: 5, maxRows: 10 }}
            placeholder={intl.formatMessage({
              id: 'banzone.geometry.coordinates.placeholder',
              defaultMessage:
                'Ví dụ: [[109.5, 12.3], [109.6, 12.4], [109.7, 12.5]]',
            })}
          />
        </ProFormItem>
      );

    case GeometryType.CIRCLE:
      return (
        <>
          <Row gutter={16}>
            <Col span={12}>
              <ProFormText
                name={[ZoneFormField.CircleData, 'center', 0]}
                label={intl.formatMessage({
                  id: 'banzone.geometry.longitude',
                  defaultMessage: 'Kinh độ',
                })}
                placeholder={intl.formatMessage({
                  id: 'banzone.geometry.longitude.placeholder',
                  defaultMessage: 'Nhập kinh độ',
                })}
                rules={[
                  {
                    required: true,
                    message: intl.formatMessage({
                      id: 'banzone.geometry.longitude.required',
                      defaultMessage: 'Kinh độ không được để trống!',
                    }),
                  },
                ]}
                fieldProps={{
                  type: 'number',
                  step: '0.000001',
                  onChange: (e) => {
                    const lng = parseFloat(e.target.value);
                    const currentCircle = (form.current?.getFieldValue(
                      ZoneFormField.CircleData,
                    ) as CircleGeometry) || { center: [0, 0], area: 0 };
                    form.current?.setFieldsValue({
                      [ZoneFormField.CircleData]: {
                        ...currentCircle,
                        center: [lng, currentCircle.center?.[1] || 0],
                      },
                    });
                  },
                }}
              />
            </Col>
            <Col span={12}>
              <ProFormText
                name={[ZoneFormField.CircleData, 'center', 1]}
                label={intl.formatMessage({
                  id: 'banzone.geometry.latitude',
                  defaultMessage: 'Vĩ độ',
                })}
                placeholder={intl.formatMessage({
                  id: 'banzone.geometry.latitude.placeholder',
                  defaultMessage: 'Nhập vĩ độ',
                })}
                rules={[
                  {
                    required: true,
                    message: intl.formatMessage({
                      id: 'banzone.geometry.latitude.required',
                      defaultMessage: 'Vĩ độ không được để trống!',
                    }),
                  },
                ]}
                fieldProps={{
                  type: 'number',
                  step: '0.000001',
                  onChange: (e) => {
                    const lat = parseFloat(e.target.value);
                    const currentCircle = (form.current?.getFieldValue(
                      ZoneFormField.CircleData,
                    ) as CircleGeometry) || { center: [0, 0], radius: 0 };
                    form.current?.setFieldsValue({
                      [ZoneFormField.CircleData]: {
                        ...currentCircle,
                        center: [currentCircle.center?.[0] || 0, lat],
                      },
                    });
                  },
                }}
              />
            </Col>
          </Row>
          <Row gutter={16}>
            <Col span={12}>
              <ProFormDigit
                name={[ZoneFormField.CircleData, 'area']}
                label={intl.formatMessage({
                  id: 'banzone.geometry.area',
                  defaultMessage: 'Diện tích (Hecta)',
                })}
                placeholder={intl.formatMessage({
                  id: 'banzone.geometry.area.placeholder',
                  defaultMessage: 'Nhập diện tích',
                })}
                min={1}
                fieldProps={{
                  precision: 0,
                  onChange: (value) => {
                    const currentCircle = (form.current?.getFieldValue(
                      ZoneFormField.CircleData,
                    ) as CircleGeometry) || { center: [0, 0], radius: 0 };
                    form.current?.setFieldsValue({
                      [ZoneFormField.CircleData]: {
                        center: currentCircle.center || [0, 0],
                        area: value || 0,
                      },
                    });
                  },
                }}
                rules={[
                  {
                    required: true,
                    message: intl.formatMessage({
                      id: 'banzone.geometry.area.required',
                      defaultMessage: 'Diện tích không được để trống!',
                    }),
                  },
                ]}
              />
            </Col>
            <Col span={12}>
              <ProFormItem
                name={[ZoneFormField.CircleData, 'radius']}
                label={intl.formatMessage({
                  id: 'banzone.geometry.radius',
                  defaultMessage: 'Bán kính (m)',
                })}
              >
                <Input
                  disabled
                  readOnly
                  value={
                    radiusArea > 0
                      ? `${radiusArea} ${intl.formatMessage({
                          id: 'banzone.geometry.metrics',
                          defaultMessage: 'mét',
                        })}`
                      : ''
                  }
                  addonAfter={intl.formatMessage({
                    id: 'banzone.geometry.auto_calculate',
                    defaultMessage: 'Tự động tính',
                  })}
                />
              </ProFormItem>
            </Col>
          </Row>
        </>
      );

    default:
      return <div>Vui lòng chọn loại hình học để nhập toạ độ.</div>;
  }
};

export default GeometryForm;
