<!-- 编辑弹窗 -->
<template>
  <ele-modal
    :width="1200"
    :visible="visible"
    :maskClosable="false"
    :maxable="maxable"
    :title="isUpdate ? '编辑优惠券' : '新增优惠券'"
    :body-style="{ paddingBottom: '28px' }"
    @update:visible="updateVisible"
    @ok="save"
  >
    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 18 }"
    >
      <!-- 基本信息 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">基本信息</span>
      </a-divider>

      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="优惠券名称" name="name">
            <a-input placeholder="请输入优惠券名称" v-model:value="form.name" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="优惠券类型" name="type">
            <a-select
              v-model:value="form.type"
              placeholder="请选择优惠券类型"
              @change="onTypeChange"
            >
              <a-select-option :value="10">
                <div class="coupon-type-option">
                  <a-tag color="red">满减券</a-tag>
                  <span>满足条件减免金额</span>
                </div>
              </a-select-option>
              <a-select-option :value="20">
                <div class="coupon-type-option">
                  <a-tag color="orange">折扣券</a-tag>
                  <span>按比例折扣</span>
                </div>
              </a-select-option>
              <a-select-option :value="30">
                <div class="coupon-type-option">
                  <a-tag color="green">免费券</a-tag>
                  <span>免费使用</span>
                </div>
              </a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
      </a-row>

      <a-form-item label="优惠券描述" name="description">
        <a-textarea
          placeholder="请输入优惠券描述"
          v-model:value="form.description"
          :rows="3"
          :maxlength="200"
          show-count
        />
      </a-form-item>

      <!-- 优惠设置 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">优惠设置</span>
      </a-divider>

      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="最低消费金额" name="minPrice">
            <a-input-number
              :min="0"
              :precision="2"
              placeholder="请输入最低消费金额"
              v-model:value="form.minPrice"
              style="width: 100%"
            >
              <template #addonAfter>元</template>
            </a-input-number>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <!-- 满减券设置 -->
          <a-form-item
            v-if="form.type === 10"
            label="减免金额"
            name="reducePrice"
          >
            <a-input-number
              :min="0"
              :precision="2"
              placeholder="请输入减免金额"
              v-model:value="form.reducePrice"
              style="width: 100%"
            >
              <template #addonAfter>元</template>
            </a-input-number>
          </a-form-item>

          <!-- 折扣券设置 -->
          <a-form-item v-if="form.type === 20" label="折扣率" name="discount">
            <a-input-number
              :min="0.1"
              :max="99.9"
              :precision="1"
              placeholder="请输入折扣率"
              v-model:value="form.discount"
              style="width: 100%"
            >
              <template #addonAfter>折</template>
            </a-input-number>
          </a-form-item>
        </a-col>
      </a-row>

      <!-- 有效期设置 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">有效期设置</span>
      </a-divider>

      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="到期类型" name="expireType">
            <a-radio-group
              v-model:value="form.expireType"
              @change="onExpireTypeChange"
            >
              <a-radio :value="10">
                <a-tag color="blue">领取后生效</a-tag>
                <span style="margin-left: 8px">用户领取后开始计时</span>
              </a-radio>
              <a-radio :value="20">
                <a-tag color="purple">固定时间</a-tag>
                <span style="margin-left: 8px">指定有效期时间段</span>
              </a-radio>
            </a-radio-group>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item
            v-if="form.expireType === 10"
            label="有效天数"
            name="expireDay"
          >
            <a-input-number
              :min="1"
              placeholder="请输入有效天数"
              v-model:value="form.expireDay"
              style="width: 100%"
            >
              <template #addonAfter>天</template>
            </a-input-number>
          </a-form-item>
        </a-col>
      </a-row>

      <div v-if="form.expireType === 20" class="fixed-time-config">
        <a-alert
          message="固定时间配置"
          description="设置优惠券的固定有效期时间段"
          type="info"
          show-icon
          style="margin-bottom: 16px"
        />
        <a-row :gutter="16">
          <a-col :span="12">
            <a-form-item label="有效期开始时间" name="startTime">
              <a-date-picker
                placeholder="请选择开始时间"
                v-model:value="form.startTime"
                style="width: 100%"
                show-time
              />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item label="有效期结束时间" name="endTime">
              <a-date-picker
                placeholder="请选择结束时间"
                v-model:value="form.endTime"
                style="width: 100%"
                show-time
              />
            </a-form-item>
          </a-col>
        </a-row>
      </div>

      <!-- 适用范围 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">适用范围</span>
      </a-divider>

      <a-form-item label="适用范围" name="applyRange">
        <a-radio-group
          v-model:value="form.applyRange"
          @change="onApplyRangeChange"
        >
          <a-radio :value="10">
            <a-tag color="cyan">全部商品</a-tag>
            <span style="margin-left: 8px">适用于所有商品</span>
          </a-radio>
          <a-radio :value="20">
            <a-tag color="geekblue">指定商品</a-tag>
            <span style="margin-left: 8px">仅适用于指定商品</span>
          </a-radio>
          <a-radio :value="30">
            <a-tag color="purple">指定分类</a-tag>
            <span style="margin-left: 8px">适用于指定商品分类</span>
          </a-radio>
        </a-radio-group>
      </a-form-item>

      <div v-if="form.applyRange === 30" class="apply-range-config">
        <a-alert
          message="分类限制配置"
          description="选择优惠券适用的商品分类"
          type="info"
          show-icon
          style="margin-bottom: 16px"
        />
        <a-form-item label="限制分类">
          <a-cascader
            v-model:value="applyCateListValue"
            :options="goodsCateList"
            multiple
            placeholder="请选择商品分类"
            :fieldNames="{ label: 'title', value: 'categoryId' }"
            style="width: 100%"
          />
        </a-form-item>
      </div>

      <div v-if="form.applyRange === 20" class="apply-range-config">
        <a-alert
          message="商品限制配置"
          description="选择优惠券适用的具体商品"
          type="info"
          show-icon
          style="margin-bottom: 16px"
        />
        <a-form-item label="限制商品">
          <a-select
            mode="multiple"
            v-model:value="applyItemListValue"
            placeholder="请选择商品"
            style="width: 100%"
            :filter-option="false"
            :show-search="true"
            @search="searchGoods"
          >
            <a-select-option
              v-for="(item, index) in goodsList"
              :key="index"
              :value="item.goodsId"
            >
              {{ item.name }}
            </a-select-option>
          </a-select>
        </a-form-item>
      </div>

      <!-- 发放设置 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">发放设置</span>
      </a-divider>

      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="发放总数量" name="totalCount">
            <a-input-number
              :min="-1"
              placeholder="请输入发放总数量"
              v-model:value="form.totalCount"
              style="width: 100%"
            >
              <template #addonAfter>张</template>
            </a-input-number>
            <div style="color: #999; font-size: 12px; margin-top: 4px">
              -1 表示无限制
            </div>
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="每人限领数量" name="limitPerUser">
            <a-input-number
              :min="-1"
              placeholder="请输入每人限领数量"
              v-model:value="form.limitPerUser"
              style="width: 100%"
            >
              <template #addonAfter>张</template>
            </a-input-number>
            <div style="color: #999; font-size: 12px; margin-top: 4px">
              -1 表示无限制
            </div>
          </a-form-item>
        </a-col>
      </a-row>

      <!-- 状态设置 -->
      <a-divider orientation="left">
        <span style="color: #1890ff; font-weight: 600">状态设置</span>
      </a-divider>

      <a-row :gutter="16">
        <a-col :span="8">
          <a-form-item label="启用状态" name="enabled">
            <a-switch
              v-model:checked="form.enabled"
              :checked-value="1"
              :un-checked-value="0"
              checked-children="启用"
              un-checked-children="禁用"
            />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="显示状态" name="status">
            <a-switch
              v-model:checked="form.status"
              :checked-value="0"
              :un-checked-value="1"
              checked-children="显示"
              un-checked-children="隐藏"
            />
          </a-form-item>
        </a-col>
        <a-col :span="8">
          <a-form-item label="排序" name="sortNumber">
            <a-input-number
              :min="0"
              placeholder="数字越小越靠前"
              v-model:value="form.sortNumber"
              style="width: 100%"
            />
          </a-form-item>
        </a-col>
      </a-row>

      <!-- 优惠券预览 -->
      <div class="coupon-preview" v-if="form.name && form.type">
        <a-divider orientation="left">
          <span style="color: #1890ff; font-weight: 600">优惠券预览</span>
        </a-divider>
        <div class="coupon-card">
          <div class="coupon-header">
            <div class="coupon-type">
              <a-tag :color="getCouponTypeColor()">{{
                getCouponTypeName()
              }}</a-tag>
            </div>
            <div class="coupon-value">
              {{ getCouponValueText() }}
            </div>
          </div>
          <div class="coupon-body">
            <div class="coupon-name">{{ form.name }}</div>
            <div class="coupon-desc">{{ form.description || '暂无描述' }}</div>
            <div class="coupon-condition">
              满{{ form.minPrice || 0 }}元可用
            </div>
          </div>
          <div class="coupon-footer">
            <div class="coupon-expire">
              {{ getExpireText() }}
            </div>
          </div>
        </div>
      </div>
    </a-form>
  </ele-modal>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch } from 'vue';
  import { Form, message } from 'ant-design-vue';
  import { assignObject } from 'ele-admin-pro';
  import { addShopCoupon, updateShopCoupon } from '@/api/shop/shopCoupon';
  import { ShopCoupon } from '@/api/shop/shopCoupon/model';
  import { FormInstance } from 'ant-design-vue/es/form';
  import { ShopGoods } from '@/api/shop/shopGoods/model';
  import { listShopGoods } from '@/api/shop/shopGoods';
  import { ShopGoodsCategory } from '@/api/shop/shopGoodsCategory/model';
  import { listShopGoodsCategory } from '@/api/shop/shopGoodsCategory';
  import dayjs from 'dayjs';

  // 是否是修改
  const isUpdate = ref(false);
  const useForm = Form.useForm;

  const props = defineProps<{
    // 弹窗是否打开
    visible: boolean;
    // 修改回显的数据
    data?: ShopCoupon | null;
  }>();

  const emit = defineEmits<{
    (e: 'done'): void;
    (e: 'update:visible', visible: boolean): void;
  }>();

  // 提交状态
  const loading = ref(false);
  // 是否显示最大化切换按钮
  const maxable = ref(true);
  // 表格选中数据
  const formRef = ref<FormInstance | null>(null);

  // 表单数据
  const form = reactive<ShopCoupon>({
    id: undefined,
    name: '',
    description: '',
    type: 10,
    reducePrice: undefined,
    discount: undefined,
    minPrice: 0,
    expireType: 10,
    expireDay: 30,
    startTime: undefined,
    endTime: undefined,
    applyRange: 10,
    applyRangeConfig: '',
    isExpire: 0,
    sortNumber: 100,
    status: 0,
    deleted: 0,
    userId: undefined,
    tenantId: undefined,
    createTime: undefined,
    updateTime: undefined,
    totalCount: -1,
    issuedCount: 0,
    limitPerUser: 1,
    enabled: 1
  });

  // 商品分类列表
  const goodsCateList = ref<ShopGoodsCategory[]>([]);
  // 商品列表
  const goodsList = ref<ShopGoods[]>([]);
  // 适用分类值
  const applyCateListValue = ref<number[]>([]);
  // 适用商品值
  const applyItemListValue = ref<number[]>([]);

  /* 更新visible */
  const updateVisible = (value: boolean) => {
    emit('update:visible', value);
  };

  // 表单验证规则
  const rules = reactive({
    name: [
      {
        required: true,
        message: '请输入优惠券名称',
        trigger: 'blur'
      },
      {
        min: 2,
        max: 50,
        message: '优惠券名称长度应在2-50个字符之间',
        trigger: 'blur'
      }
    ],
    type: [
      {
        required: true,
        message: '请选择优惠券类型',
        trigger: 'change'
      }
    ],
    reducePrice: [
      {
        validator: (rule: any, value: any) => {
          if (form.type === 10 && (!value || value <= 0)) {
            return Promise.reject('满减券减免金额必须大于0');
          }
          return Promise.resolve();
        },
        trigger: 'blur'
      }
    ],
    discount: [
      {
        validator: (rule: any, value: any) => {
          if (form.type === 20 && (!value || value <= 0 || value >= 100)) {
            return Promise.reject('折扣率必须在0-100之间');
          }
          return Promise.resolve();
        },
        trigger: 'blur'
      }
    ],
    minPrice: [
      {
        required: true,
        message: '请输入最低消费金额',
        trigger: 'blur'
      }
    ],
    expireType: [
      {
        required: true,
        message: '请选择到期类型',
        trigger: 'change'
      }
    ],
    expireDay: [
      {
        validator: (rule: any, value: any) => {
          if (form.expireType === 10 && (!value || value <= 0)) {
            return Promise.reject('有效天数必须大于0');
          }
          return Promise.resolve();
        },
        trigger: 'blur'
      }
    ],
    startTime: [
      {
        validator: (rule: any, value: any) => {
          if (form.expireType === 20 && !value) {
            return Promise.reject('请选择有效期开始时间');
          }
          return Promise.resolve();
        },
        trigger: 'change'
      }
    ],
    endTime: [
      {
        validator: (rule: any, value: any) => {
          if (form.expireType === 20 && !value) {
            return Promise.reject('请选择有效期结束时间');
          }
          if (
            form.expireType === 20 &&
            value &&
            form.startTime &&
            dayjs(value).isBefore(dayjs(form.startTime))
          ) {
            return Promise.reject('结束时间不能早于开始时间');
          }
          return Promise.resolve();
        },
        trigger: 'change'
      }
    ],
    totalCount: [
      {
        required: true,
        message: '请输入发放总数量',
        trigger: 'blur'
      }
    ],
    limitPerUser: [
      {
        required: true,
        message: '请输入每人限领数量',
        trigger: 'blur'
      }
    ]
  });

  /* 优惠券类型改变 */
  const onTypeChange = (value: number) => {
    // 清空相关字段
    if (value !== 10) {
      form.reducePrice = undefined;
    }
    if (value !== 20) {
      form.discount = undefined;
    }
  };

  /* 到期类型改变 */
  const onExpireTypeChange = (e: any) => {
    const value = e.target.value;
    if (value === 10) {
      form.startTime = undefined;
      form.endTime = undefined;
      form.expireDay = 30;
    } else {
      form.expireDay = undefined;
    }
  };

  /* 适用范围改变 */
  const onApplyRangeChange = (e: any) => {
    const value = e.target.value;
    applyCateListValue.value = [];
    applyItemListValue.value = [];
    form.applyRangeConfig = '';
  };

  /* 搜索商品 */
  const searchGoods = async (value: string) => {
    if (value && value.trim()) {
      try {
        const res = await listShopGoods({ keywords: value.trim() });
        goodsList.value = res || [];
        console.log('搜索到的商品:', goodsList.value);
      } catch (e) {
        console.error('搜索商品失败:', e);
        goodsList.value = [];
      }
    }
  };

  /* 获取优惠券类型颜色 */
  const getCouponTypeColor = () => {
    const colorMap = {
      10: 'red',
      20: 'orange',
      30: 'green'
    };
    return colorMap[form.type] || 'blue';
  };

  /* 获取优惠券类型名称 */
  const getCouponTypeName = () => {
    const nameMap = {
      10: '满减券',
      20: '折扣券',
      30: '免费券'
    };
    return nameMap[form.type] || '优惠券';
  };

  /* 获取优惠券价值文本 */
  const getCouponValueText = () => {
    switch (form.type) {
      case 10:
        return `￥${form.reducePrice || 0}`;
      case 20:
        return `${form.discount || 0}折`;
      case 30:
        return '免费';
      default:
        return '优惠';
    }
  };

  /* 获取有效期文本 */
  const getExpireText = () => {
    if (form.expireType === 10) {
      return `领取后${form.expireDay || 0}天内有效`;
    } else {
      const start = form.startTime
        ? dayjs(form.startTime).format('YYYY.MM.DD')
        : '';
      const end = form.endTime ? dayjs(form.endTime).format('YYYY.MM.DD') : '';
      return start && end ? `${start} - ${end}` : '请设置有效期';
    }
  };

  const { resetFields } = useForm(form, rules);

  /* 保存编辑 */
  const save = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        loading.value = true;
        const formData = {
          ...form
        };

        // 处理时间字段转换
        if (formData.startTime && dayjs.isDayjs(formData.startTime)) {
          formData.startTime = formData.startTime.format('YYYY-MM-DD HH:mm:ss');
        }
        if (formData.endTime && dayjs.isDayjs(formData.endTime)) {
          formData.endTime = formData.endTime.format('YYYY-MM-DD HH:mm:ss');
        }

        // 处理适用范围配置
        if (form.applyRange === 20 && applyItemListValue.value.length) {
          formData.couponApplyItemList = applyItemListValue.value.map((pk) => ({
            pk,
            type: 0
          }));
        } else {
          formData.couponApplyItemList = [];
        }

        if (form.applyRange === 30 && applyCateListValue.value.length) {
          formData.couponApplyCateList = applyCateListValue.value.map(
            (cateId) => ({
              cateId,
              cateLevel: 0
            })
          );
        } else {
          formData.couponApplyCateList = [];
        }

        const saveOrUpdate = isUpdate.value ? updateShopCoupon : addShopCoupon;
        saveOrUpdate(formData)
          .then((msg) => {
            loading.value = false;
            message.success(msg);
            updateVisible(false);
            emit('done');
          })
          .catch((e) => {
            loading.value = false;
            message.error(e.message);
          });
      })
      .catch(() => {});
  };

  /* 获取商品列表 */
  const getGoodsList = async () => {
    try {
      const res = await listShopGoods({ pageSize: 50 });
      goodsList.value = res || [];
      console.log('获取到的商品列表:', goodsList.value);
    } catch (e) {
      console.error('获取商品列表失败:', e);
      goodsList.value = [];
    }
  };

  /* 获取商品分类列表 */
  const getGoodsCateList = async () => {
    try {
      const res = await listShopGoodsCategory();
      goodsCateList.value = res || [];
      console.log('获取到的商品分类列表:', goodsCateList.value);
    } catch (e) {
      console.error('获取商品分类列表失败:', e);
      goodsCateList.value = [];
    }
  };

  watch(
    () => props.visible,
    async (visible) => {
      if (visible) {
        await getGoodsList();
        await getGoodsCateList();

        if (props.data) {
          assignObject(form, props.data);

          // 处理时间字段转换
          if (props.data.startTime) {
            form.startTime = dayjs(props.data.startTime);
          }
          if (props.data.endTime) {
            form.endTime = dayjs(props.data.endTime);
          }

          // 处理适用范围数据
          if (
            props.data.couponApplyCateList &&
            props.data.couponApplyCateList.length > 0
          ) {
            applyCateListValue.value = props.data.couponApplyCateList.map(
              (item) => item.cateId
            );
          }
          if (
            props.data.couponApplyItemList &&
            props.data.couponApplyItemList.length > 0
          ) {
            applyItemListValue.value = props.data.couponApplyItemList.map(
              (item) => item.pk
            );
          }

          isUpdate.value = true;
        } else {
          // 重置为默认值
          Object.assign(form, {
            id: undefined,
            name: '',
            description: '',
            type: 10,
            reducePrice: undefined,
            discount: undefined,
            minPrice: 0,
            expireType: 10,
            expireDay: 30,
            startTime: undefined,
            endTime: undefined,
            applyRange: 10,
            applyRangeConfig: '',
            isExpire: 0,
            sortNumber: 100,
            status: 0,
            deleted: 0,
            userId: undefined,
            tenantId: undefined,
            createTime: undefined,
            updateTime: undefined,
            totalCount: -1,
            issuedCount: 0,
            limitPerUser: 1,
            enabled: 1
          });

          isUpdate.value = false;
        }
      } else {
        applyCateListValue.value = [];
        applyItemListValue.value = [];
        resetFields();
      }
    },
    { immediate: true }
  );
</script>

<style lang="less" scoped>
  .coupon-type-option {
    display: flex;
    align-items: center;

    .ant-tag {
      margin-right: 8px;
    }

    span {
      color: #666;
      font-size: 12px;
    }
  }

  .fixed-time-config,
  .apply-range-config {
    background: #fafafa;
    padding: 16px;
    border-radius: 6px;
    margin-bottom: 16px;
  }

  .coupon-preview {
    margin-top: 24px;

    .coupon-card {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      border-radius: 12px;
      padding: 20px;
      color: white;
      position: relative;
      overflow: hidden;

      &::before {
        content: '';
        position: absolute;
        top: 0;
        right: 0;
        width: 100px;
        height: 100px;
        background: rgba(255, 255, 255, 0.1);
        border-radius: 50%;
        transform: translate(30px, -30px);
      }

      .coupon-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;

        .coupon-value {
          font-size: 24px;
          font-weight: bold;
        }
      }

      .coupon-body {
        .coupon-name {
          font-size: 18px;
          font-weight: 600;
          margin-bottom: 8px;
        }

        .coupon-desc {
          font-size: 14px;
          opacity: 0.9;
          margin-bottom: 12px;
        }

        .coupon-condition {
          font-size: 12px;
          opacity: 0.8;
        }
      }

      .coupon-footer {
        margin-top: 16px;
        padding-top: 16px;
        border-top: 1px solid rgba(255, 255, 255, 0.2);

        .coupon-expire {
          font-size: 12px;
          opacity: 0.8;
        }
      }
    }
  }

  :deep(.ant-divider-horizontal.ant-divider-with-text-left) {
    margin: 24px 0 16px 0;

    .ant-divider-inner-text {
      padding: 0 16px 0 0;
    }
  }

  :deep(.ant-form-item) {
    margin-bottom: 16px;
  }

  :deep(.ant-radio) {
    display: flex;
    align-items: center;
    margin-bottom: 8px;

    .ant-radio-inner {
      margin-right: 8px;
    }
  }

  :deep(.ant-select-selection-item) {
    display: flex;
    align-items: center;
  }

  :deep(.ant-input-number) {
    width: 100%;
  }

  :deep(.ant-alert) {
    .ant-alert-message {
      font-weight: 600;
    }
  }
</style>
