import { SGW_ROUTE_BANZONES_LIST } from '@/constants/slave/sgw/routes';
import VietNamMap, {
  VietNamMapRef,
} from '@/pages/Slave/SGW/Map/components/VietNamMap';
import { BaseMap, DATA_LAYER } from '@/pages/Slave/SGW/Map/type';
import {
  apiCreateBanzone,
  apiGetZoneById,
  apiUpdateBanzone,
} from '@/services/slave/sgw/ZoneController';
import {
  getAreaFromRadius,
  getCircleRadius,
} from '@/utils/slave/sgw/geomUtils';
import { DeleteOutlined, EditFilled, GatewayOutlined } from '@ant-design/icons';
import {
  PageContainer,
  ProCard,
  ProForm,
  ProFormInstance,
} from '@ant-design/pro-components';
import {
  FormattedMessage,
  history,
  useIntl,
  useLocation,
  useModel,
  useParams,
} from '@umijs/max';
import { Button, Flex, Form, Grid, message } from 'antd';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import { useCallback, useEffect, useRef, useState } from 'react';
import ZoneForm from './components/ZoneForm';
import { useMapGeometrySync } from './hooks';
import {
  AreaCondition,
  checkValidateGeometry,
  DrawActionType,
  formatLineStringWKT,
  formatPolygonGeometryToWKT,
  GeometryType,
  parseLineStringWKT,
  parseMultiPolygonWKT,
  parsePointWKT,
  PolygonGeometry,
  ZoneFormData,
  ZoneFormField,
  ZoneLocationState,
} from './type';
const CreateOrUpdateBanzone = () => {
  const location = useLocation() as { state: ZoneLocationState };
  const shape = location.state?.shape;
  const type = location.state?.type;
  const { id: zoneId } = useParams();
  const intl = useIntl();
  const { useBreakpoint } = Grid;
  const screens = useBreakpoint();
  const formRef = useRef<ProFormInstance<ZoneFormData>>();
  const vietNamMapRef = useRef<VietNamMapRef>(null);
  const baseMap = useRef<BaseMap | null>(null);
  const drawController = useRef<any>(null);
  const [loading, setLoading] = useState(false);
  const [formReady, setFormReady] = useState(false);
  const { groupMap } = useModel('master.useGroups');
  const [mapActions, setMapActions] = useState<DrawActionType>({
    isDrawing: false,
    isModifying: false,
  });

  const { clearMapFeatures, updateMapFromForm } = useMapGeometrySync({
    baseMap: baseMap,
    dataLayerId: DATA_LAYER,
    form: formRef,
    shape,
    enabled: !!baseMap.current,
  });

  // Handler for back navigation
  const handleBack = () => {
    history.push(SGW_ROUTE_BANZONES_LIST);
    formRef.current?.resetFields();
  };

  const handleMapReady = useCallback((baseMapInstance: BaseMap) => {
    baseMap.current = baseMapInstance;
    // Create a vector layer for dynamic features
    const vectorDataLayer = new VectorLayer({
      source: new VectorSource(),
    });
    vectorDataLayer.set('id', DATA_LAYER);
    baseMapInstance.addLayer(vectorDataLayer);
    baseMapInstance.setView([116.152685, 15.70581], 5);
    // Initialize draw controller
    drawController.current = baseMapInstance.DrawAndModifyFeature(DATA_LAYER);
  }, []);

  const handleEnableModify = () => {
    if (drawController.current) {
      setMapActions({
        isDrawing: false,
        isModifying: true,
      });
      drawController.current.removeInteractions();
      drawController.current.enableModify();
    }
  };

  const handleSubmit = async (values?: ZoneFormData) => {
    if (!values) return;
    // Validate required fields
    if (!values[ZoneFormField.AreaName]) {
      message.error(
        intl.formatMessage({ id: 'banzone.form.name.error.required' }),
      );
      return;
    }
    if (!values[ZoneFormField.AreaType]) {
      message.error(
        intl.formatMessage({ id: 'banzone.form.name.area_type.required' }),
      );
      return;
    }
    if (!values[ZoneFormField.AreaId]) {
      message.error(
        intl.formatMessage({ id: 'banzone.form.name.province.required' }),
      );
      return;
    }
    const lineStringData = values[ZoneFormField.PolylineData];
    const polygonData = values[ZoneFormField.PolygonGeometry];
    const circleData = values[ZoneFormField.CircleData];

    if (!lineStringData && !polygonData && !circleData) {
      message.error(
        intl.formatMessage({ id: 'banzone.form.name.geometry.required' }),
      );
      return;
    }

    let geometryJson = '';

    // // Convert geometry to API format
    switch (shape) {
      case GeometryType.POLYGON: {
        const polygonWKT: string = formatPolygonGeometryToWKT(
          polygonData || [],
        );
        geometryJson = JSON.stringify({
          geom_type: GeometryType.POLYGON,
          geom_poly: polygonWKT,
          geom_lines: '',
          geom_point: '',
          geom_radius: 0,
        });
        break;
      }
      case GeometryType.LINESTRING: {
        const polylineData = JSON.parse(lineStringData || '[]');
        const polylineWKT: string = formatLineStringWKT(polylineData);
        geometryJson = JSON.stringify({
          geom_type: GeometryType.LINESTRING,
          geom_poly: '',
          geom_lines: polylineWKT,
          geom_point: '',
          geom_radius: 0,
        });
        break;
      }
      case GeometryType.CIRCLE: {
        // For circle, API expects radius in hecta, convert from meters
        const radiusInMetter = getCircleRadius(circleData?.area || 0);
        const pointWKT = `POINT(${circleData?.center[0] || 0} ${
          circleData?.center[1] || 0
        })`;
        geometryJson = JSON.stringify({
          geom_type: GeometryType.CIRCLE,
          geom_poly: '',
          geom_lines: '',
          geom_point: pointWKT,
          geom_radius: radiusInMetter,
        });
        break;
      }
      default:
        message.error('Loại hình học không hợp lệ!');
        return;
    }
    const groupId = values[ZoneFormField.AreaId];
    const provinceCode = Array.isArray(groupId)
      ? groupId.map((id) => groupMap[id]?.code || '').join(',')
      : groupMap[groupId as string]?.code || '';
    // // Prepare request body
    const requestBody: SgwModel.ZoneBodyRequest = {
      name: values[ZoneFormField.AreaName],
      type: values[ZoneFormField.AreaType],
      group_id: groupId as string,
      province_code: provinceCode,
      enabled: values[ZoneFormField.AreaEnabled] ?? true,
      description: values[ZoneFormField.AreaDescription],
      conditions: values[ZoneFormField.AreaConditions] as SgwModel.Condition[],
      geom: geometryJson,
    };

    console.log('Submit body:', requestBody);

    try {
      setLoading(true);
      if (type === 'create') {
        const key = 'create';
        message.open({
          key,
          type: 'loading',
          content: intl.formatMessage({ id: 'banzone.creating' }),
        });
        await apiCreateBanzone(requestBody);
        message.open({
          key,
          type: 'success',
          content: intl.formatMessage({ id: 'banzone.creating_success' }),
        });
      } else if (type === 'update' && zoneId) {
        const key = 'update';
        message.open({
          key,
          type: 'loading',
          content: intl.formatMessage({ id: 'banzone.updating' }),
        });
        await apiUpdateBanzone(zoneId, requestBody);
        message.open({
          key,
          type: 'success',
          content: intl.formatMessage({ id: 'banzone.updating_success' }),
        });
      } else {
        message.error(
          type === 'update'
            ? intl.formatMessage({ id: 'banzone.updating_fail' })
            : intl.formatMessage({ id: 'banzone.creating_fail' }),
        );
        return;
      }
      setTimeout(() => {
        handleBack();
      }, 1000);
    } catch (error) {
      console.error('Failed to save zone:', error);
      message.error(intl.formatMessage({ id: 'banzone.fail.save' }));
    } finally {
      setLoading(false);
    }
  };

  const handleOnClickDraw = () => {
    drawController.current = baseMap.current?.DrawAndModifyFeature(DATA_LAYER);
    setMapActions({
      isDrawing: true,
      isModifying: false,
    });
    drawController.current.removeInteractions();
    switch (shape) {
      case 1:
        drawController.current.drawPolygon();
        break;
      case 2:
        drawController.current.drawLineString();
        break;
      case 3:
        drawController.current.drawCircle();
        break;
      case 4:
        drawController.current.drawPoint();
        break;
      default:
        break;
    }
  };

  const polygonGeometry =
    (Form.useWatch(
      ZoneFormField.PolygonGeometry,
      formReady && formRef.current ? formRef.current : undefined,
    ) as PolygonGeometry[]) || [];

  const polylineData = Form.useWatch(
    ZoneFormField.PolylineData,
    formReady && formRef.current ? formRef.current : undefined,
  );

  const circleData = Form.useWatch(
    ZoneFormField.CircleData,
    formReady && formRef.current ? formRef.current : undefined,
  );

  useEffect(() => {
    if (polygonGeometry && polygonGeometry.length > 0) {
      updateMapFromForm(GeometryType.POLYGON);
    }
  }, [polygonGeometry, formRef]);

  useEffect(() => {
    if (polylineData && checkValidateGeometry(polylineData)) {
      updateMapFromForm(GeometryType.LINESTRING);
    }
  }, [polylineData, formRef]);

  useEffect(() => {
    if (circleData) {
      updateMapFromForm(GeometryType.CIRCLE);
    }
  }, [circleData, formRef]);
  return (
    <PageContainer
      onBack={handleBack}
      title={
        type === 'create' ? (
          <FormattedMessage id="banzones.create" />
        ) : (
          <FormattedMessage id="banzones.update" />
        )
      }
      style={{
        padding: 10,
      }}
    >
      <ProCard split={screens.md ? 'vertical' : 'horizontal'}>
        <ProCard colSpan={{ xs: 24, sm: 24, md: 10, lg: 10, xl: 10 }}>
          <ProForm<ZoneFormData>
            formRef={formRef}
            layout="vertical"
            onFinish={handleSubmit}
            onInit={(_, form) => {
              formRef.current = form;
              setFormReady(true);
            }}
            initialValues={{
              [ZoneFormField.AreaEnabled]: true,
            }}
            request={async () => {
              if (type === 'update' && zoneId) {
                try {
                  const zone: SgwModel.Banzone = await apiGetZoneById(zoneId);
                  if (!zone) return {} as ZoneFormData;
                  // Parse geometry (API may use `geom` or `geometry` field)
                  let parsedGeometry: SgwModel.Geom | undefined;
                  const geomRaw = (zone as any).geom ?? (zone as any).geometry;
                  if (geomRaw) {
                    try {
                      parsedGeometry =
                        typeof geomRaw === 'string'
                          ? JSON.parse(geomRaw)
                          : geomRaw;
                    } catch (e) {
                      console.warn('Failed to parse geometry', e);
                    }
                  }
                  const groupId = Object.entries(groupMap).find(
                    ([, value]) => value.code === zone.province_code,
                  )?.[0] as string | undefined;
                  // Build base form data
                  const formData: Partial<ZoneFormData> = {
                    [ZoneFormField.AreaName]: zone.name || '',
                    [ZoneFormField.AreaType]: zone.type ?? 1,
                    [ZoneFormField.AreaEnabled]: zone.enabled ?? true,
                    [ZoneFormField.AreaDescription]: zone.description || '',
                    [ZoneFormField.AreaId]: groupId || '',
                    [ZoneFormField.AreaConditions]:
                      zone.conditions as AreaCondition[],
                  };
                  // Map geometry to form fields depending on geometry type
                  if (parsedGeometry) {
                    switch (parsedGeometry.geom_type) {
                      case GeometryType.POLYGON: {
                        const polygons = parseMultiPolygonWKT(
                          parsedGeometry.geom_poly || '',
                        );
                        formData[ZoneFormField.PolygonGeometry] = polygons.map(
                          (polygon) => ({
                            geometry: polygon,
                            id: Math.random().toString(36).substring(2, 9),
                          }),
                        );
                        break;
                      }
                      case GeometryType.LINESTRING: {
                        const polyline = parseLineStringWKT(
                          parsedGeometry.geom_lines || '',
                        );
                        formData[ZoneFormField.PolylineData] =
                          JSON.stringify(polyline);
                        break;
                      }

                      case GeometryType.CIRCLE: {
                        const center = parsePointWKT(
                          parsedGeometry.geom_point || '',
                        );
                        formData[ZoneFormField.CircleData] = {
                          center: center || [0, 0],
                          radius: parsedGeometry.geom_radius || 0,
                          area: getAreaFromRadius(
                            parsedGeometry.geom_radius || 0,
                          ),
                        };
                        break;
                      }
                      default:
                        break;
                    }
                  }

                  return formData as ZoneFormData;
                } catch (error) {
                  console.error('Failed to load zone for request:', error);
                  return {} as ZoneFormData;
                }
              }
              return {} as ZoneFormData;
            }}
            submitter={{
              searchConfig: {
                submitText:
                  type === 'create'
                    ? intl.formatMessage({ id: 'banzone.create.button.title' })
                    : intl.formatMessage({ id: 'banzone.update.button.title' }),
              },
              submitButtonProps: {
                loading: loading,
              },
              render: (_, dom) => {
                return (
                  <Flex
                    gap={8}
                    justify="center"
                    style={{ marginTop: 24, marginBottom: 24 }}
                  >
                    {dom}
                  </Flex>
                );
              },
            }}
          >
            <ZoneForm formRef={formRef} shape={shape} />
            <Flex align="center" gap={8} justify="end">
              <Button
                onClick={handleOnClickDraw}
                variant={`${mapActions.isDrawing ? 'solid' : 'dashed'}`}
                color={`${mapActions.isDrawing ? 'green' : 'default'}`}
                icon={<GatewayOutlined />}
              >
                <FormattedMessage
                  id="banzone.map_action.draw"
                  defaultMessage="Draw"
                />
              </Button>
              <Button
                onClick={handleEnableModify}
                variant={`${mapActions.isModifying ? 'solid' : 'dashed'}`}
                color={`${mapActions.isModifying ? 'green' : 'default'}`}
                icon={<EditFilled />}
              >
                <FormattedMessage
                  id="banzone.map_action.modify"
                  defaultMessage="Modify"
                />
              </Button>
              <Button
                danger
                type="primary"
                icon={<DeleteOutlined />}
                onClick={() => {
                  clearMapFeatures();
                  setMapActions({
                    isDrawing: false,
                    isModifying: false,
                  });
                  switch (shape) {
                    case GeometryType.POLYGON:
                      formRef.current?.setFieldValue(
                        ZoneFormField.PolygonGeometry,
                        [],
                      );
                      break;
                    case GeometryType.LINESTRING:
                      formRef.current?.setFieldValue(
                        ZoneFormField.PolylineData,
                        '',
                      );
                      break;
                    case GeometryType.CIRCLE:
                      formRef.current?.setFieldValue(
                        ZoneFormField.CircleData,
                        undefined,
                      );
                      break;
                    default:
                      break;
                  }
                }}
              ></Button>
            </Flex>
          </ProForm>
        </ProCard>
        <ProCard ghost colSpan={{ xs: 24, sm: 24, md: 14, lg: 14, xl: 14 }}>
          <VietNamMap
            ref={vietNamMapRef}
            style={{
              maxWidth: '100%',
              height: '100%',
              width: '100%',
            }}
            onMapReady={handleMapReady}
          />
        </ProCard>
      </ProCard>
    </PageContainer>
  );
};

export default CreateOrUpdateBanzone;
