import type { Ref } from 'vue';

/**
 * 文件职责：多边形区域编辑动作。
 * 1. 管理区域抽屉开关与表单赋值。
 * 2. 处理区域新增、编辑、删除。
 */
import type { PolygonZoneDto } from '#/api/store-delivery';
import type {
  DeliveryDrawerMode,
  PolygonZoneFormState,
} from '#/views/store/delivery/types';

import { message } from 'ant-design-vue';

import { countPolygonsInGeoJson } from './geojson';

interface CreateZoneActionsOptions {
  createZoneId: () => string;
  getTierColorByIndex: (index: number) => string;
  isZoneDrawerOpen: Ref<boolean>;
  polygonZones: Ref<PolygonZoneDto[]>;
  sortPolygonZones: (source: PolygonZoneDto[]) => PolygonZoneDto[];
  zoneDrawerMode: Ref<DeliveryDrawerMode>;
  zoneForm: PolygonZoneFormState;
}

export function createZoneActions(options: CreateZoneActionsOptions) {
  /** 打开新增/编辑区域抽屉，并填充表单。 */
  function openZoneDrawer(mode: DeliveryDrawerMode, zone?: PolygonZoneDto) {
    options.zoneDrawerMode.value = mode;

    if (mode === 'edit' && zone) {
      options.zoneForm.id = zone.id;
      options.zoneForm.name = zone.name;
      options.zoneForm.deliveryFee = zone.deliveryFee;
      options.zoneForm.minOrderAmount = zone.minOrderAmount;
      options.zoneForm.etaMinutes = zone.etaMinutes;
      options.zoneForm.priority = zone.priority;
      options.zoneForm.color = zone.color;
      options.zoneForm.polygonGeoJson = zone.polygonGeoJson ?? '';
      options.isZoneDrawerOpen.value = true;
      return;
    }

    const nextPriority = options.polygonZones.value.length + 1;
    options.zoneForm.id = '';
    options.zoneForm.name = '';
    options.zoneForm.deliveryFee = 5;
    options.zoneForm.minOrderAmount = 20;
    options.zoneForm.etaMinutes = 30;
    options.zoneForm.priority = nextPriority;
    options.zoneForm.color = options.getTierColorByIndex(nextPriority - 1);
    options.zoneForm.polygonGeoJson = '';
    options.isZoneDrawerOpen.value = true;
  }

  /** 切换区域抽屉可见性。 */
  function setZoneDrawerOpen(value: boolean) {
    options.isZoneDrawerOpen.value = value;
  }

  /** 更新区域名称。 */
  function setZoneName(value: string) {
    options.zoneForm.name = value;
  }

  /** 更新区域配送费。 */
  function setZoneDeliveryFee(value: number) {
    options.zoneForm.deliveryFee = Math.max(0, Number(value || 0));
  }

  /** 更新区域起送金额。 */
  function setZoneMinOrderAmount(value: number) {
    options.zoneForm.minOrderAmount = Math.max(0, Number(value || 0));
  }

  /** 更新区域预计送达时间。 */
  function setZoneEtaMinutes(value: number) {
    options.zoneForm.etaMinutes = Math.max(1, Number(value || 1));
  }

  /** 更新区域优先级。 */
  function setZonePriority(value: number) {
    options.zoneForm.priority = Math.max(1, Math.floor(Number(value || 1)));
  }

  /** 更新区域标识色。 */
  function setZoneColor(value: string) {
    options.zoneForm.color = value || '#1677ff';
  }

  /** 更新区域多边形 GeoJSON。 */
  function setZonePolygonGeoJson(value: string) {
    options.zoneForm.polygonGeoJson = value?.trim() ?? '';
  }

  /** 提交区域表单并更新列表。 */
  function handleZoneSubmit() {
    // 1. 必填校验。
    const normalizedName = options.zoneForm.name.trim();
    if (!normalizedName) {
      message.error('请输入区域名称');
      return false;
    }

    if (countPolygonsInGeoJson(options.zoneForm.polygonGeoJson) <= 0) {
      message.error('请先绘制配送区域');
      return false;
    }

    // 2. 优先级冲突校验。
    const hasPriorityConflict = options.polygonZones.value.some((item) => {
      if (item.id === options.zoneForm.id) return false;
      return item.priority === options.zoneForm.priority;
    });
    if (hasPriorityConflict) {
      message.error('优先级已存在，请调整后重试');
      return false;
    }

    // 3. 写回列表。
    const record: PolygonZoneDto = {
      id: options.zoneForm.id || options.createZoneId(),
      name: normalizedName,
      deliveryFee: options.zoneForm.deliveryFee,
      minOrderAmount: options.zoneForm.minOrderAmount,
      etaMinutes: options.zoneForm.etaMinutes,
      priority: options.zoneForm.priority,
      color: options.zoneForm.color,
      polygonGeoJson: options.zoneForm.polygonGeoJson,
    };

    options.polygonZones.value =
      options.zoneDrawerMode.value === 'edit' && options.zoneForm.id
        ? options.sortPolygonZones(
            options.polygonZones.value.map((item) =>
              item.id === options.zoneForm.id ? record : item,
            ),
          )
        : options.sortPolygonZones([...options.polygonZones.value, record]);

    options.isZoneDrawerOpen.value = false;
    message.success(
      options.zoneDrawerMode.value === 'edit' ? '区域已更新' : '区域已添加',
    );
    return true;
  }

  /** 删除指定区域。 */
  function handleDeleteZone(zoneId: string) {
    options.polygonZones.value = options.polygonZones.value.filter(
      (item) => item.id !== zoneId,
    );
    message.success('区域已删除');
    return true;
  }

  return {
    handleDeleteZone,
    handleZoneSubmit,
    openZoneDrawer,
    setZoneColor,
    setZoneDeliveryFee,
    setZoneDrawerOpen,
    setZoneEtaMinutes,
    setZoneMinOrderAmount,
    setZoneName,
    setZonePolygonGeoJson,
    setZonePriority,
  };
}
