<template>
  <div class="table-box button-table friend-relation-container">
    <ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" :data-callback="dataCallback">
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <div class="header-button">
          <el-button type="primary" @click="openAddDialog"> 添加活动 </el-button>
        </div>
      </template>

      <!-- 状态列 -->
      <template #status="scope">
        <el-tag :type="getStatusType(scope.row.status)">
          {{ getStatusText(scope.row.status) }}
        </el-tag>
      </template>

      <!-- 表格操作 -->
      <template #operation="scope">
        <el-button link type="primary" @click="editRow(scope.row)"> 编辑 </el-button>
        <el-button link type="primary" @click="deleteRow(scope.row)"> 删除 </el-button>
      </template>
    </ProTable>

    <!-- 添加/编辑活动对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px" @close="closeDialog">
      <el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
        <el-form-item label="活动名称" prop="acName">
          <el-input v-model="formData.acName" placeholder="请输入" clearable />
        </el-form-item>

        <el-form-item label="赠送类型">
          <el-radio-group v-model="formData.distributeType" @change="onDistributeTypeChange">
            <el-radio :label="1"> 满减券 </el-radio>
            <el-radio :label="2"> 折扣券 </el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="消费门槛金额(￥)">
          <div style="display: flex; gap: 10px; align-items: center; width: 100%">
            <el-form-item prop="moneyLow" style="flex: 1; margin-bottom: 0">
              <el-input
                v-model="formData.moneyLow"
                type="number"
                :min="0"
                step="0.01"
                placeholder="0.00"
                clearable
                @input="handleMoneyInput('moneyLow')"
              >
                <template #prefix> ￥ </template>
              </el-input>
            </el-form-item>
            <span>~</span>
            <el-form-item prop="moneyHigh" style="flex: 1; margin-bottom: 0">
              <el-input
                v-model="formData.moneyHigh"
                type="number"
                :min="0"
                step="0.01"
                placeholder="0.00"
                clearable
                @input="handleMoneyInput('moneyHigh')"
              >
                <template #prefix> ￥ </template>
              </el-input>
            </el-form-item>
          </div>
        </el-form-item>

        <el-form-item label="来源商家及优惠券">
          <div class="merchant-coupon-list">
            <div v-for="(item, index) in formData.coupons" :key="index" class="merchant-coupon-item">
              <el-select
                v-model="item.merchant"
                placeholder="选择商家"
                style="width: 200px; margin-right: 10px"
                filterable
                @change="handleMerchantChange(index)"
              >
                <el-option
                  v-for="(m, idx) in effectiveMerchantOptions"
                  :key="m.label ? `${String(m.value)}_${m.label}_${idx}` : String(m.value)"
                  :label="m.label"
                  :value="m.value"
                />
              </el-select>
              <el-select
                v-model="item.coupon"
                :placeholder="formData.distributeType === 2 ? '选择折扣券' : '选择满减券'"
                style="width: 200px; margin-right: 10px"
                filterable
                @change="handleCouponChange(index)"
              >
                <el-option
                  v-for="c in getCouponOptions(formData.distributeType)"
                  :key="c.value"
                  :label="c.label"
                  :value="c.value"
                />
              </el-select>
              <span v-if="item.coupon" class="remaining-text">剩余{{ item.remaining }}张</span>
              <el-button type="danger" link @click="removeMerchantCoupon(index)" v-if="formData.coupons.length > 1">
                删除
              </el-button>
            </div>
            <el-button type="primary" link @click="addMerchantCoupon" style="margin-top: 10px">
              <el-icon><Plus /></el-icon>
              添加商家优惠券
            </el-button>
          </div>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeDialog"> 取消 </el-button>
          <el-button type="primary" @click="handleSubmit"> 确定 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="tsx" name="friendRelation">
import { computed, onMounted, reactive, ref } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import ProTable from "@/components/ProTable/index.vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import { localGet } from "@/utils";

import {
  getRuleList,
  saveFriendCouponRule,
  getMutualAttention,
  delFriendCouponRule,
  getRuleById,
  getVoucherList,
  getIssueCouponList
} from "@/api/modules/newLoginApi";

// ProTable 实例
const proTable = ref<ProTableInstance>();

// 对话框相关
const dialogVisible = ref(false);
const dialogTitle = computed(() => (isEdit.value ? "编辑活动" : "添加活动"));
const isEdit = ref(false);
const currentEditId = ref("");

// 表单引用
const formRef = ref<FormInstance>();

// 商家列表（互相关注接口，仅显示 phoneId 带 store 的商家）
const merchantList = ref<Array<{ value: string | number; label: string; raw?: any }>>([]);
const merchantListRaw = ref<any[]>([]);

// 优惠券/折扣券选项缓存 key: '1-couponList' | '2-couponList'
const couponOptionsMap = ref<Record<string, Array<{ value: string; label: string }>>>({});
const couponDataMap = ref<Record<string, any[]>>({});

const normalizeCouponValue = (v: any) => (v != null && v !== "" ? String(v) : "");

// 编辑时合并详情中的 storeName，使商家下拉能正确显示；按 label 去重，避免同一商家出现多次
const effectiveMerchantOptions = computed(() => {
  const base = merchantList.value || [];
  const fromDetail = (formData.coupons || [])
    .filter((c: any) => c.merchant != null && c.merchant !== "" && c.storeName)
    .map((c: any) => ({ value: c.merchant, label: c.storeName }));
  const seenValue = new Set(base.map((o: any) => o.value));
  const extra = fromDetail.filter((o: any) => {
    if (seenValue.has(o.value)) return false;
    seenValue.add(o.value);
    return true;
  });
  const merged = [...base, ...extra];
  // 按 label（店名）去重：同一店名只保留一项，优先保留在 form 中已选中的 value，避免下拉重复显示
  const usedValues = new Set((formData.coupons || []).map((c: any) => c.merchant).filter((v: any) => v != null && v !== ""));
  const byLabel = new Map<string, { value: string | number; label: string }>();
  for (const o of merged) {
    const label = o.label || "";
    const existing = byLabel.get(label);
    if (!existing) {
      byLabel.set(label, o);
    } else if (usedValues.has(o.value) && !usedValues.has(existing.value)) {
      byLabel.set(label, o);
    }
  }
  return Array.from(byLabel.values());
});

const getCouponOptions = (distributeType: number) => {
  const key = distributeType === 2 ? "2-couponList" : "1-couponList";
  return couponOptionsMap.value[key] || [];
};

// 表单数据
const formData = reactive({
  acName: "",
  distributeType: 1 as 1 | 2, // 1-满减券 2-折扣券
  moneyLow: "" as string | number,
  moneyHigh: "" as string | number,
  coupons: [] as Array<{
    merchant: string | number | null;
    coupon: string | null;
    remaining: number;
    storeName?: string;
  }>
});

// 金额验证器
const validateMoneyLow = (rule: any, value: any, callback: any) => {
  if (value === "" || value === null || value === undefined) {
    callback(new Error("请输入最低消费金额"));
    return;
  }

  const numValue = Number(value);
  if (isNaN(numValue)) {
    callback(new Error("请输入有效的金额"));
    return;
  }

  if (numValue < 0) {
    callback(new Error("金额不能为负数"));
    return;
  }

  // 验证小数位数不超过2位
  const decimalPart = String(value).split(".")[1];
  if (decimalPart && decimalPart.length > 2) {
    callback(new Error("最多支持2位小数"));
    return;
  }

  // 如果最高金额已填写，验证最低金额不能大于最高金额
  if (formData.moneyHigh !== "" && formData.moneyHigh !== null && formData.moneyHigh !== undefined) {
    const highValue = Number(formData.moneyHigh);
    if (!isNaN(highValue) && numValue > highValue) {
      callback(new Error("最低金额不能大于最高金额"));
      return;
    }
  }

  callback();
};

const validateMoneyHigh = (rule: any, value: any, callback: any) => {
  if (value === "" || value === null || value === undefined) {
    callback(new Error("请输入最高消费金额"));
    return;
  }

  const numValue = Number(value);
  if (isNaN(numValue)) {
    callback(new Error("请输入有效的金额"));
    return;
  }

  if (numValue < 0) {
    callback(new Error("金额不能为负数"));
    return;
  }

  // 验证小数位数不超过2位
  const decimalPart = String(value).split(".")[1];
  if (decimalPart && decimalPart.length > 2) {
    callback(new Error("最多支持2位小数"));
    return;
  }

  // 如果最低金额已填写，验证最高金额不能小于最低金额
  if (formData.moneyLow !== "" && formData.moneyLow !== null && formData.moneyLow !== undefined) {
    const lowValue = Number(formData.moneyLow);
    if (!isNaN(lowValue) && numValue < lowValue) {
      callback(new Error("最高金额不能小于最低金额"));
      return;
    }
  }

  callback();
};

// 表单验证规则
const formRules = reactive<FormRules>({
  acName: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
  moneyLow: [{ required: true, validator: validateMoneyLow, trigger: "blur" }],
  moneyHigh: [{ required: true, validator: validateMoneyHigh, trigger: "blur" }]
});

// 表格列配置
const columns = reactive<ColumnProps<any>[]>([
  {
    prop: "acName",
    label: "活动名称",
    search: { el: "input", props: { placeholder: "请输入活动名称" } }
  },
  {
    prop: "endDate",
    label: "有效期至"
  },
  {
    prop: "relationType",
    label: "消费门槛",
    render: (scope: any) => {
      return scope.row.moneyLow + "元" + "~" + scope.row.moneyHigh + "元";
    }
  },
  {
    prop: "status",
    label: "状态",
    enum: [
      { label: "启用", value: 0 },
      { label: "禁用", value: 1 }
    ],
    search: { el: "select", props: { placeholder: "请选择状态" } },
    fieldNames: { label: "label", value: "value" },
    render: (scope: any) => {
      return scope.row.status == 0 ? "启用" : "禁用";
    }
  },
  { prop: "operation", label: "操作", fixed: "right", width: 250 }
]);

// 初始化请求参数
const initParam = reactive({
  storeId: localGet("createdId") || ""
});

// 数据回调处理：兼容接口返回数组或 { records/list, total } 格式，确保有数据时分页显示正确总数（iOS 上 total 需为明确数字）
const dataCallback = (data: any) => {
  const list = Array.isArray(data) ? data : (data?.records ?? data?.list ?? []);
  const totalNum =
    typeof data?.total === "number" && Number.isFinite(data.total) ? data.total : Array.isArray(list) ? list.length : 0;
  const total = Math.max(0, Math.floor(Number(totalNum)) || 0);
  return {
    list,
    total
  };
};

// 获取表格列表
const getTableList = (params: any) => {
  return getRuleList(params);
};

// 获取状态文本
const getStatusText = (status: number) => {
  const statusMap: Record<number, string> = {
    0: "待同意",
    1: "已同意",
    2: "已拒绝"
  };
  return statusMap[status] || "--";
};

// 获取状态类型
const getStatusType = (status: number): "success" | "warning" | "info" | "danger" => {
  const typeMap: Record<number, "success" | "warning" | "info" | "danger"> = {
    0: "warning",
    1: "success",
    2: "info"
  };
  return typeMap[status] || "info";
};

// 获取商家列表（互相关注接口，仅显示 phoneId 带 store 的商家）- 与 group_merchant eachOtherInterest 参数一致
const loadAddActivityMerchants = async () => {
  const phone = localGet("iphone") || localGet("geeker-user")?.userInfo?.phone || "";
  try {
    const res: any = await getMutualAttention({
      page: 1,
      size: 1000,
      fansId: `store_${phone}`
    });
    const data = res?.data || res;
    const records = data?.records || data?.list || (Array.isArray(data) ? data : []);
    const list = Array.isArray(records) ? records : [];
    const merchantListFiltered = list.filter((item: any) => {
      const pid = String(item.phoneId ?? item.id ?? "");
      return pid.includes("store");
    });
    merchantListRaw.value = merchantListFiltered;
    // 按 value（id/storeId/phoneId）去重，避免同一商家在接口中多次返回导致下拉重复
    const seen = new Set<string | number>();
    merchantList.value = merchantListFiltered
      .map((item: any) => ({
        value: item.id ?? item.storeId ?? item.phoneId,
        label: item.storeName ?? item.name ?? "",
        raw: item
      }))
      .filter((o: any) => {
        if (seen.has(o.value)) return false;
        seen.add(o.value);
        return true;
      });
  } catch (error) {
    console.error("获取商家列表失败", error);
    merchantList.value = [];
    merchantListRaw.value = [];
  }
};

// 打开添加对话框
const openAddDialog = async () => {
  isEdit.value = false;
  currentEditId.value = "";
  await loadAddActivityMerchants();
  couponOptionsMap.value = {};
  couponDataMap.value = {};
  formData.distributeType = 1;
  formData.coupons = [{ merchant: null, coupon: null, remaining: 0 }];
  formData.acName = "";
  formData.moneyLow = "";
  formData.moneyHigh = "";
  dialogVisible.value = true;
};

// 处理金额输入
const handleMoneyInput = (field: "moneyLow" | "moneyHigh") => {
  // 当一个金额字段改变时，触发另一个字段的验证
  if (formRef.value) {
    const otherField = field === "moneyLow" ? "moneyHigh" : "moneyLow";
    // 如果另一个字段有值，触发其验证
    if (formData[otherField] !== "" && formData[otherField] !== null && formData[otherField] !== undefined) {
      formRef.value.validateField(otherField, () => {});
    }
  }
};

// 关闭对话框
const closeDialog = () => {
  dialogVisible.value = false;
  formRef.value?.resetFields();
  Object.assign(formData, {
    acName: "",
    distributeType: 1,
    moneyLow: "",
    moneyHigh: "",
    coupons: []
  });
  currentEditId.value = "";
};

// 添加商家优惠券
const addMerchantCoupon = () => {
  formData.coupons.push({
    merchant: null,
    coupon: null,
    remaining: 0
  });
};

// 移除商家优惠券
const removeMerchantCoupon = (index: number) => {
  formData.coupons.splice(index, 1);
};

// 赠送类型切换：清空选项缓存并重置行内选择（与 group_merchant setDistributeType 一致）
const onDistributeTypeChange = () => {
  couponOptionsMap.value = {};
  couponDataMap.value = {};
  formData.coupons = formData.coupons.map(() => ({
    merchant: null,
    coupon: null,
    remaining: 0
  }));
  if (formData.coupons.length !== 1) formData.coupons = [{ merchant: null, coupon: null, remaining: 0 }];
  loadAddActivityMerchants();
};

// 加载当前类型下的优惠券/折扣券选项
const loadCouponOptionsByType = async (distributeType: number) => {
  const key = distributeType === 2 ? "2-couponList" : "1-couponList";
  if (couponOptionsMap.value[key]?.length) return;
  const storeId = localGet("createdId") || "";
  try {
    const res: any = await getIssueCouponList({
      storeId,
      tab: 1,
      size: 100,
      page: 1,
      couponName: "",
      couponsFromType: 1,
      couponType: formData.distributeType
    });
    const records = res?.data?.records ?? res?.data ?? [];
    const list = Array.isArray(records) ? records : [];
    couponDataMap.value[key] = list;
    couponOptionsMap.value[key] = list.map((item: any) => ({
      value: String(item.id ?? item.couponId ?? ""),
      label: item.couponName ?? item.name ?? ""
    }));
  } catch (e) {
    couponDataMap.value[key] = [];
    couponOptionsMap.value[key] = [];
  }
};

// 商家选择改变
const handleMerchantChange = async (index: number) => {
  const item = formData.coupons[index];
  item.coupon = null;
  item.remaining = 0;
  if (item.merchant) {
    const raw = merchantListRaw.value.find(
      (m: any) => (m.id ?? m.friendStoreUserId) === item.merchant || (m.storeId ?? m.phoneId) === item.merchant
    );
    if (raw) item.remaining = raw.singleQty ?? raw.couponNum ?? 0;
    await loadCouponOptionsByType(formData.distributeType);
  }
};

// 优惠券/折扣券选择改变
const handleCouponChange = (index: number) => {
  const item = formData.coupons[index];
  const key = formData.distributeType === 2 ? "2-couponList" : "1-couponList";
  const list = couponDataMap.value[key] || [];
  const idKey = formData.distributeType === 2 ? "voucherId" : "couponId";
  if (item.coupon && list.length) {
    const found = list.find((c: any) => String(c[idKey] ?? c.couponId ?? c.id ?? "") === String(item.coupon));
    if (found) item.remaining = found.singleQty ?? found.couponNum ?? 0;
  }
};

// 编辑行数据（与 group_merchant editActivity 逻辑及 getRuleById 回显一致）
const editRow = async (row: any) => {
  isEdit.value = true;
  currentEditId.value = row.id;
  const id = row.id;
  if (!id) return;

  await loadAddActivityMerchants();
  const type = row.type === 2 ? 2 : 1;
  formData.distributeType = type;
  couponOptionsMap.value = {};
  couponDataMap.value = {};

  try {
    const res: any = await getRuleById({ id });
    if (res.code != 200 || !res.data) {
      ElMessage.error(res.msg || "获取活动详情失败");
      return;
    }
    const d = res.data;
    formData.acName = d.acName;
    formData.moneyLow = d.moneyLow;
    formData.moneyHigh = d.moneyHigh;
    formData.distributeType = d.couponType;
    formData.coupons = (d.lifeDiscountCouponFriendRuleDetailVos || []).map((vo: any) => ({
      merchant: vo.friendStoreUserId ?? null,
      coupon: normalizeCouponValue(vo.couponId ?? vo.voucherId),
      remaining: vo.singleQty ?? vo.couponNum ?? 0,
      storeName: vo.storeName ?? ""
    }));
    if (formData.coupons.length === 0) {
      formData.coupons = [{ merchant: null, coupon: null, remaining: 0 }];
    }
    await loadCouponOptionsByType(formData.distributeType);
    // 编辑回显：从已加载的券列表中按券 id 同步剩余张数，避免详情接口未返回 singleQty/couponNum 时一直显示 0
    const key = formData.distributeType === 2 ? "2-couponList" : "1-couponList";
    const list = couponDataMap.value[key] || [];
    const idKey = formData.distributeType === 2 ? "voucherId" : "couponId";
    formData.coupons.forEach((row: any) => {
      if (!row.coupon) return;
      const found = list.find((c: any) => String(c[idKey] ?? c.couponId ?? c.id ?? "") === String(row.coupon));
      if (found) row.remaining = found.singleQty ?? found.couponNum ?? 0;
    });
    dialogVisible.value = true;
  } catch (error: any) {
    ElMessage.error(error?.msg || "获取活动详情失败");
  }
};

// 删除行数据
const deleteRow = (row: any) => {
  ElMessageBox.confirm("确定要删除这个活动吗？", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      try {
        const res: any = await delFriendCouponRule({ id: row.id });
        if (res.code == 200) {
          ElMessage.success("删除成功");
          proTable.value?.getTableList();
        } else {
          ElMessage.error(res.msg || "删除失败");
        }
      } catch (error: any) {
        ElMessage.error(error?.msg || "删除失败");
      }
    })
    .catch(() => {
      // 用户取消删除
    });
};

// 提交表单（与 group_merchant saveActivity 请求参数一致）
const handleSubmit = async () => {
  if (!formRef.value) return;

  await formRef.value.validate(async (valid: boolean) => {
    if (!valid) return;

    if (!formData.coupons.length) {
      ElMessage.warning("请至少添加一个商家优惠券");
      return;
    }
    const hasEmpty = formData.coupons.some((item: any) => !item.merchant || !item.coupon);
    if (hasEmpty) {
      ElMessage.warning("请完善所有商家优惠券信息");
      return;
    }

    const isVoucher = formData.distributeType === 2;
    const details = formData.coupons.map((item: any) =>
      isVoucher
        ? { voucherId: item.coupon, friendStoreUserId: item.merchant }
        : { couponId: item.coupon, friendStoreUserId: item.merchant }
    );

    const requestData: any = {
      storeId: localGet("createdId") || "",
      acName: formData.acName.trim(),
      couponType: formData.distributeType,
      moneyHigh: Number(formData.moneyHigh),
      moneyLow: Number(formData.moneyLow),
      details
    };
    if (isEdit.value && currentEditId.value) {
      requestData.id = currentEditId.value;
    }

    try {
      const res: any = await saveFriendCouponRule(requestData);
      if (res.code == 200) {
        ElMessage.success(isEdit.value ? "编辑成功" : "添加成功");
        closeDialog();
        proTable.value?.getTableList();
      } else {
        ElMessage.error(res.msg || "操作失败");
      }
    } catch (error: any) {
      ElMessage.error(error?.msg || (isEdit.value ? "编辑失败" : "添加失败"));
    }
  });
};

// 页面加载时触发查询
onMounted(() => {
  proTable.value?.getTableList();
});
</script>

<style lang="scss" scoped>
.friend-relation-container {
  .header-button {
    margin-bottom: 16px;
  }
  .merchant-coupon-list {
    width: 100%;
    .merchant-coupon-item {
      display: flex;
      align-items: center;
      margin-bottom: 10px;
    }
    .remaining-text {
      margin-right: 10px;
      font-size: 13px;
      color: var(--el-text-color-regular);
    }
  }
  .dialog-footer {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
  }
}
</style>
