<script setup lang="ts">
import type { Dayjs } from 'dayjs';

import type { CouponEditorForm } from '../types';

import type {
  MarketingCouponChannel,
  MarketingCouponStoreScopeMode,
  MarketingCouponType,
  MarketingCouponValidityType,
} from '#/api/marketing';

import {
  Button,
  DatePicker,
  Drawer,
  Form,
  Input,
  InputNumber,
  Radio,
  Select,
  Spin,
} from 'ant-design-vue';
/**
 * 文件职责：优惠券编辑抽屉。
 * 1. 承载券基础信息、发放规则与适用范围配置。
 * 2. 对外抛出字段更新与保存事件。
 */
import dayjs from 'dayjs';

import {
  COUPON_CHANNEL_OPTIONS,
  COUPON_EDITOR_TYPE_OPTIONS,
  COUPON_STORE_SCOPE_OPTIONS,
  COUPON_VALIDITY_OPTIONS,
} from '../composables/coupon-page/constants';

defineProps<{
  form: CouponEditorForm;
  loading: boolean;
  open: boolean;
  storeOptions: Array<{ label: string; value: string }>;
  submitText: string;
  submitting: boolean;
  title: string;
}>();

const emit = defineEmits<{
  (event: 'close'): void;
  (event: 'setChannels', value: MarketingCouponChannel[]): void;
  (event: 'setCouponType', value: MarketingCouponType): void;
  (event: 'setMinimumSpend', value: null | number): void;
  (event: 'setName', value: string): void;
  (event: 'setPerUserLimit', value: null | number): void;
  (event: 'setRelativeValidDays', value: null | number): void;
  (event: 'setStoreIds', value: string[]): void;
  (event: 'setStoreScopeMode', value: MarketingCouponStoreScopeMode): void;
  (event: 'setTotalQuantity', value: null | number): void;
  (event: 'setValidDateRange', value: [Dayjs, Dayjs] | null): void;
  (event: 'setValidityType', value: MarketingCouponValidityType): void;
  (event: 'setValue', value: null | number): void;
  (event: 'submit'): void;
}>();

function onStoreIdsChange(value: Array<number | string>) {
  emit('setStoreIds', value.map(String));
}

function onCouponTypeChange(value: unknown) {
  if (
    value === 'amount_off' ||
    value === 'discount' ||
    value === 'free_delivery'
  ) {
    emit('setCouponType', value);
  }
}

function onValidityTypeChange(value: unknown) {
  if (value === 'fixed' || value === 'days') {
    emit('setValidityType', value);
  }
}

function onStoreScopeModeChange(value: unknown) {
  if (value === 'all' || value === 'stores') {
    emit('setStoreScopeMode', value);
  }
}

function onDateRangeChange(value: [Dayjs, Dayjs] | [string, string] | null) {
  if (!value) {
    emit('setValidDateRange', null);
    return;
  }

  const [start, end] = value;
  if (typeof start === 'string' || typeof end === 'string') {
    emit('setValidDateRange', [dayjs(String(start)), dayjs(String(end))]);
    return;
  }

  emit('setValidDateRange', value as [Dayjs, Dayjs]);
}

function onNameChange(value: string) {
  emit('setName', String(value ?? ''));
}

function onMinimumSpendChange(value: null | number | string) {
  emit('setMinimumSpend', parseNullableNumber(value));
}

function onValueChange(value: null | number | string) {
  emit('setValue', parseNullableNumber(value));
}

function onTotalQuantityChange(value: null | number | string) {
  emit('setTotalQuantity', parseNullableNumber(value));
}

function onPerUserLimitChange(value: null | number | string) {
  emit('setPerUserLimit', parseNullableNumber(value));
}

function onRelativeValidDaysChange(value: null | number | string) {
  emit('setRelativeValidDays', parseNullableNumber(value));
}

function onStoreIdsSelectChange(value: unknown) {
  const values = Array.isArray(value) ? value : [];
  onStoreIdsChange(values.map(String));
}

function parseNullableNumber(value: null | number | string) {
  if (value === null || value === undefined || value === '') {
    return null;
  }
  const numeric = Number(value);
  return Number.isNaN(numeric) ? null : numeric;
}

function resolveToggledChannels(
  channels: MarketingCouponChannel[],
  channel: MarketingCouponChannel,
) {
  if (channels.includes(channel)) {
    return channels.filter((item) => item !== channel);
  }
  return [...channels, channel];
}
</script>

<template>
  <Drawer
    :open="open"
    :title="title"
    width="560"
    :destroy-on-close="false"
    class="mcp-editor-drawer"
    @close="emit('close')"
  >
    <Spin :spinning="loading">
      <Form layout="vertical" class="mcp-editor-form">
        <Form.Item label="券名称" required>
          <Input
            :value="form.name"
            :maxlength="64"
            placeholder="如：新用户满减券"
            @update:value="onNameChange"
          />
        </Form.Item>

        <Form.Item label="券类型" required>
          <Radio.Group
            :value="form.couponType"
            button-style="solid"
            @update:value="onCouponTypeChange"
          >
            <Radio.Button
              v-for="item in COUPON_EDITOR_TYPE_OPTIONS"
              :key="item.value"
              :value="item.value"
            >
              {{ item.label }}
            </Radio.Button>
          </Radio.Group>
        </Form.Item>

        <Form.Item
          v-if="form.couponType === 'amount_off'"
          label="面额设置"
          required
        >
          <div class="mcp-inline-fields">
            <span>满</span>
            <InputNumber
              :value="form.minimumSpend ?? undefined"
              :min="0.01"
              :precision="2"
              placeholder="如：50"
              @update:value="onMinimumSpendChange"
            />
            <span>元减</span>
            <InputNumber
              :value="form.value ?? undefined"
              :min="0.01"
              :precision="2"
              placeholder="如：15"
              @update:value="onValueChange"
            />
            <span>元</span>
          </div>
        </Form.Item>

        <Form.Item
          v-if="form.couponType === 'discount'"
          label="折扣力度"
          required
        >
          <div class="mcp-inline-fields">
            <InputNumber
              :value="form.value ?? undefined"
              :min="0.01"
              :max="9.99"
              :precision="2"
              placeholder="如：8"
              @update:value="onValueChange"
            />
            <span>折</span>
          </div>
          <div class="mcp-field-hint">输入 8 表示打 8 折，即优惠 20%</div>
        </Form.Item>

        <Form.Item
          v-if="form.couponType === 'free_delivery'"
          label="面额设置"
          class="mcp-form-muted"
        >
          免配送费券无需设置面额
        </Form.Item>
        <div class="mcp-section-divider"></div>

        <Form.Item label="发放总量" required>
          <InputNumber
            :value="form.totalQuantity"
            :min="1"
            :precision="0"
            class="mcp-input-wide"
            placeholder="如：1000"
            @update:value="onTotalQuantityChange"
          />
          <div class="mcp-field-hint">设置后不可减少，可增加</div>
        </Form.Item>

        <Form.Item label="每人限领">
          <InputNumber
            :value="form.perUserLimit ?? undefined"
            :min="1"
            :precision="0"
            class="mcp-input-wide"
            placeholder="如：1"
            @update:value="onPerUserLimitChange"
          />
          <div class="mcp-field-hint">不填则不限制</div>
        </Form.Item>
        <div class="mcp-section-divider"></div>

        <Form.Item label="有效期类型" required>
          <Radio.Group
            :value="form.validityType"
            button-style="solid"
            @update:value="onValidityTypeChange"
          >
            <Radio.Button
              v-for="item in COUPON_VALIDITY_OPTIONS"
              :key="item.value"
              :value="item.value"
            >
              {{ item.label }}
            </Radio.Button>
          </Radio.Group>
        </Form.Item>

        <Form.Item
          v-if="form.validityType === 'fixed'"
          label="有效时间范围"
          required
        >
          <DatePicker.RangePicker
            :value="form.validDateRange ?? undefined"
            format="YYYY-MM-DD"
            class="mcp-range-picker"
            @update:value="onDateRangeChange"
          />
        </Form.Item>

        <Form.Item v-else label="领取后有效天数" required>
          <div class="mcp-inline-fields">
            <span>领取后</span>
            <InputNumber
              :value="form.relativeValidDays ?? undefined"
              :min="1"
              :precision="0"
              placeholder="如：7"
              @update:value="onRelativeValidDaysChange"
            />
            <span>天内有效</span>
          </div>
        </Form.Item>

        <div
          v-if="form.couponType !== 'free_delivery'"
          class="mcp-section-divider"
        ></div>

        <Form.Item v-if="form.couponType !== 'free_delivery'" label="使用门槛">
          <div class="mcp-inline-fields">
            <span>订单满</span>
            <InputNumber
              :value="form.minimumSpend ?? undefined"
              :min="0.01"
              :precision="2"
              placeholder="如：50"
              @update:value="onMinimumSpendChange"
            />
            <span>元可用</span>
          </div>
          <div class="mcp-field-hint">不填则无门槛</div>
        </Form.Item>

        <Form.Item label="适用渠道" required>
          <div class="mcp-channel-pills">
            <button
              v-for="item in COUPON_CHANNEL_OPTIONS"
              :key="item.value"
              type="button"
              class="mcp-channel-pill"
              :class="{ checked: form.channels.includes(item.value) }"
              @click="
                emit(
                  'setChannels',
                  resolveToggledChannels(form.channels, item.value),
                )
              "
            >
              {{ item.label }}
            </button>
          </div>
        </Form.Item>

        <Form.Item label="适用门店" required>
          <Radio.Group
            :value="form.storeScopeMode"
            @update:value="onStoreScopeModeChange"
          >
            <Radio
              v-for="item in COUPON_STORE_SCOPE_OPTIONS"
              :key="item.value"
              :value="item.value"
            >
              {{ item.label }}
            </Radio>
          </Radio.Group>

          <Select
            v-if="form.storeScopeMode === 'stores'"
            mode="multiple"
            :value="form.storeIds"
            :options="storeOptions"
            class="mcp-store-multi"
            placeholder="请选择适用门店"
            @update:value="onStoreIdsSelectChange"
          />
        </Form.Item>
      </Form>
    </Spin>

    <template #footer>
      <div class="mcp-drawer-footer">
        <Button @click="emit('close')">取消</Button>
        <Button type="primary" :loading="submitting" @click="emit('submit')">
          {{ submitText }}
        </Button>
      </div>
    </template>
  </Drawer>
</template>
