<script lang="ts" setup>
import { computed, reactive, ref, watch } from 'vue';

import { Page } from '@vben/common-ui';
import { useAccessStore } from '@vben/stores';

import {
  getResidentInviteConfig,
  saveResidentInviteConfig,
} from '#/api/legacy/resident-activity';
import ActivityResourceGroupSelectDrawer from '#/views/props/components/activity-resource-group-select-drawer.vue';
import { getAllowedSysOrigins } from '#/views/system/shared';

import {
  Button,
  Card,
  Input,
  InputNumber,
  Modal,
  Space,
  Spin,
  Switch,
  Tag,
  message,
} from 'antdv-next';

defineOptions({ name: 'ResidentInviteConfigPage' });

function createReward() {
  return {
    goldAmount: 0,
    rewardGroupId: null,
    rewardGroupName: '',
  };
}

function createRule(threshold = 1) {
  return {
    enabled: true,
    goldAmount: 0,
    rewardGroupId: null,
    rewardGroupName: '',
    threshold,
  };
}

const accessStore = useAccessStore();
const sysOriginOptions = computed(() => {
  const options = getAllowedSysOrigins(accessStore.accessCodes || []);
  return options.length > 0 ? options : getAllowedSysOrigins([]);
});

const loading = ref(false);
const saving = ref(false);
const groupPickerOpen = ref(false);

const pickerTarget = reactive({
  listKey: '',
  rowIndex: -1,
});

const form = reactive<Record<string, any>>({
  antiCheat: {
    sameDeviceOnce: true,
    sameIpOnce: true,
  },
  downloadUrl: '',
  enabled: false,
  inviteeBindReward: createReward(),
  inviteeRechargeRules: [],
  inviterBindReward: createReward(),
  inviterTotalRechargeRules: [],
  inviterValidCountRules: [],
  serviceContact: '',
  shareDesc: '',
  shareTitle: '',
  sysOrigin: '',
  timezone: 'Asia/Riyadh',
});

function normalizeReward(value: Record<string, any> | null | undefined) {
  return {
    goldAmount: Number(value?.goldAmount || 0),
    rewardGroupId: value?.rewardGroupId ?? null,
    rewardGroupName: value?.rewardGroupName || '',
  };
}

function normalizeRuleList(list: Array<Record<string, any>> | null | undefined) {
  return (list || []).map((item) => ({
    enabled: item?.enabled !== false,
    goldAmount: Number(item?.goldAmount || 0),
    rewardGroupId: item?.rewardGroupId ?? null,
    rewardGroupName: item?.rewardGroupName || '',
    threshold: Number(item?.threshold || 0),
  }));
}

function normalizeConfig(result: Record<string, any> | null | undefined) {
  const value = result ?? {};
  form.sysOrigin = String(value.sysOrigin || form.sysOrigin || sysOriginOptions.value[0]?.value || '');
  form.enabled = Boolean(value.enabled);
  form.downloadUrl = String(value.downloadUrl || '');
  form.shareTitle = String(value.shareTitle || '');
  form.shareDesc = String(value.shareDesc || '');
  form.serviceContact = String(value.serviceContact || '');
  form.timezone = String(value.timezone || 'Asia/Riyadh');
  form.antiCheat.sameIpOnce = value?.antiCheat?.sameIpOnce !== false;
  form.antiCheat.sameDeviceOnce = value?.antiCheat?.sameDeviceOnce !== false;
  form.inviterBindReward = normalizeReward(value.inviterBindReward);
  form.inviteeBindReward = normalizeReward(value.inviteeBindReward);
  form.inviteeRechargeRules = normalizeRuleList(value.inviteeRechargeRules);
  form.inviterValidCountRules = normalizeRuleList(value.inviterValidCountRules);
  form.inviterTotalRechargeRules = normalizeRuleList(value.inviterTotalRechargeRules);
}

async function loadData() {
  if (!form.sysOrigin) {
    return;
  }
  loading.value = true;
  try {
    const result = await getResidentInviteConfig(form.sysOrigin);
    normalizeConfig(result);
  } finally {
    loading.value = false;
  }
}

watch(
  sysOriginOptions,
  (options) => {
    if (!form.sysOrigin) {
      form.sysOrigin = String(options[0]?.value || '');
    }
  },
  { immediate: true },
);

watch(
  () => form.sysOrigin,
  (value) => {
    if (value) {
      void loadData();
    }
  },
  { immediate: true },
);

function addRule(listKey: string) {
  const list = form[listKey] as Array<Record<string, any>>;
  const nextThreshold = list.length > 0 ? Number(list[list.length - 1]?.threshold || 0) + 1 : 1;
  list.push(createRule(nextThreshold));
}

function normalizeRowIndex(index: number | string) {
  return typeof index === 'number' ? index : Number(index || 0);
}

function removeRule(listKey: string, index: number | string) {
  (form[listKey] as Array<Record<string, any>>).splice(normalizeRowIndex(index), 1);
}

function openRewardPicker(listKey: string, rowIndex: number | string = -1) {
  pickerTarget.listKey = listKey;
  pickerTarget.rowIndex = normalizeRowIndex(rowIndex);
  groupPickerOpen.value = true;
}

function clearRewardGroup(listKey: string, rowIndex: number | string = -1) {
  const normalizedRowIndex = normalizeRowIndex(rowIndex);
  const target = normalizedRowIndex >= 0
    ? (form[listKey] as Array<Record<string, any>>)[normalizedRowIndex]
    : form[listKey];
  target.rewardGroupId = null;
  target.rewardGroupName = '';
}

function handleRewardGroupSelect(row: Record<string, any>) {
  const target = pickerTarget.rowIndex >= 0
    ? (form[pickerTarget.listKey] as Array<Record<string, any>>)[pickerTarget.rowIndex]
    : form[pickerTarget.listKey];
  target.rewardGroupId = row.id;
  target.rewardGroupName = row.name;
  groupPickerOpen.value = false;
}

async function submitForm() {
  saving.value = true;
  try {
    await saveResidentInviteConfig({
      antiCheat: { ...form.antiCheat },
      downloadUrl: String(form.downloadUrl || '').trim(),
      enabled: Boolean(form.enabled),
      inviteeBindReward: { ...form.inviteeBindReward },
      inviteeRechargeRules: (form.inviteeRechargeRules || []).map((item: Record<string, any>) => ({
        enabled: Boolean(item.enabled),
        goldAmount: Number(item.goldAmount || 0),
        rewardGroupId: item.rewardGroupId ?? null,
        threshold: Number(item.threshold || 0),
      })),
      inviterBindReward: { ...form.inviterBindReward },
      inviterTotalRechargeRules: (form.inviterTotalRechargeRules || []).map((item: Record<string, any>) => ({
        enabled: Boolean(item.enabled),
        goldAmount: Number(item.goldAmount || 0),
        rewardGroupId: item.rewardGroupId ?? null,
        threshold: Number(item.threshold || 0),
      })),
      inviterValidCountRules: (form.inviterValidCountRules || []).map((item: Record<string, any>) => ({
        enabled: Boolean(item.enabled),
        goldAmount: Number(item.goldAmount || 0),
        rewardGroupId: item.rewardGroupId ?? null,
        threshold: Number(item.threshold || 0),
      })),
      serviceContact: String(form.serviceContact || '').trim(),
      shareDesc: String(form.shareDesc || '').trim(),
      shareTitle: String(form.shareTitle || '').trim(),
      sysOrigin: form.sysOrigin,
      timezone: String(form.timezone || '').trim(),
    });
    message.success('保存成功');
    await loadData();
  } finally {
    saving.value = false;
  }
}

function handleSubmit() {
  Modal.confirm({
    async onOk() {
      await submitForm();
    },
    title: '确认覆盖当前系统的整套邀请活动配置？',
  });
}

const rewardSections = [
  { key: 'inviteeRechargeRules', title: '被邀请人充值达标奖励', thresholdLabel: '充值金币阈值' },
  { key: 'inviterValidCountRules', title: '邀请有效人数任务', thresholdLabel: '邀请人数阈值' },
  { key: 'inviterTotalRechargeRules', title: '邀请名下累计充值任务', thresholdLabel: '累计充值金币阈值' },
];
</script>

<template>
  <Page title="邀请活动配置">
    <Card>
      <Space class="toolbar" wrap>
        <div class="toolbar-item">
          <div class="toolbar-label">系统</div>
          <SysOriginSelect
            v-model:value="form.sysOrigin"
            style="width: 160px"
            :options="sysOriginOptions"
          />
        </div>
        <Button :loading="saving" type="primary" @click="handleSubmit">
          保存配置
        </Button>
      </Space>

      <Spin :spinning="loading">
        <div class="section-list">
          <Card size="small" title="基础设置">
            <div class="grid">
              <div class="field">
                <div class="label">活动开关</div>
                <Switch v-model:checked="form.enabled" />
              </div>
              <div class="field">
                <div class="label">时区</div>
                <Input v-model:value="form.timezone" />
              </div>
              <div class="field field-span-2">
                <div class="label">下载地址</div>
                <Input v-model:value="form.downloadUrl" />
              </div>
              <div class="field field-span-2">
                <div class="label">分享标题</div>
                <Input v-model:value="form.shareTitle" />
              </div>
              <div class="field field-span-2">
                <div class="label">分享描述</div>
                <Input v-model:value="form.shareDesc" />
              </div>
              <div class="field field-span-2">
                <div class="label">客服联系方式</div>
                <Input v-model:value="form.serviceContact" />
              </div>
              <div class="field">
                <div class="label">同 IP 只计一次</div>
                <Switch v-model:checked="form.antiCheat.sameIpOnce" />
              </div>
              <div class="field">
                <div class="label">同设备只计一次</div>
                <Switch v-model:checked="form.antiCheat.sameDeviceOnce" />
              </div>
            </div>
          </Card>

          <Card size="small" title="邀请方首邀奖励">
            <div class="reward-row">
              <div class="field">
                <div class="label">金币</div>
                <InputNumber v-model:value="form.inviterBindReward.goldAmount" :min="0" style="width: 180px" />
              </div>
              <div class="field field-grow">
                <div class="label">奖励组</div>
                <div class="reward-group-box">
                  <Tag v-if="form.inviterBindReward.rewardGroupName" color="blue">
                    {{ form.inviterBindReward.rewardGroupName }}
                  </Tag>
                  <span v-else class="placeholder">未选择奖励组</span>
                </div>
              </div>
              <Button @click="openRewardPicker('inviterBindReward')">选择奖励组</Button>
              <Button @click="clearRewardGroup('inviterBindReward')">清空</Button>
            </div>
          </Card>

          <Card size="small" title="被邀请方注册礼包">
            <div class="reward-row">
              <div class="field">
                <div class="label">金币</div>
                <InputNumber v-model:value="form.inviteeBindReward.goldAmount" :min="0" style="width: 180px" />
              </div>
              <div class="field field-grow">
                <div class="label">奖励组</div>
                <div class="reward-group-box">
                  <Tag v-if="form.inviteeBindReward.rewardGroupName" color="blue">
                    {{ form.inviteeBindReward.rewardGroupName }}
                  </Tag>
                  <span v-else class="placeholder">未选择奖励组</span>
                </div>
              </div>
              <Button @click="openRewardPicker('inviteeBindReward')">选择奖励组</Button>
              <Button @click="clearRewardGroup('inviteeBindReward')">清空</Button>
            </div>
          </Card>

          <Card
            v-for="section in rewardSections"
            :key="section.key"
            size="small"
            :title="section.title"
          >
            <div class="section-head">
              <div class="section-tip">
                阶梯可配置为金币、奖励组或两者同时发放。
              </div>
              <Button type="dashed" @click="addRule(section.key)">新增阶梯</Button>
            </div>

            <div v-if="(form[section.key] || []).length === 0" class="empty-box">
              暂无配置
            </div>

            <div
              v-for="(item, index) in form[section.key]"
              :key="`${section.key}-${index}`"
              class="rule-item"
            >
              <div class="field">
                <div class="label">{{ section.thresholdLabel }}</div>
                <InputNumber v-model:value="item.threshold" :min="1" style="width: 180px" />
              </div>
              <div class="field">
                <div class="label">金币</div>
                <InputNumber v-model:value="item.goldAmount" :min="0" style="width: 180px" />
              </div>
              <div class="field field-grow">
                <div class="label">奖励组</div>
                <div class="reward-group-box">
                  <Tag v-if="item.rewardGroupName" color="blue">
                    {{ item.rewardGroupName }}
                  </Tag>
                  <span v-else class="placeholder">未选择奖励组</span>
                </div>
              </div>
              <div class="field switch-field">
                <div class="label">启用</div>
                <Switch v-model:checked="item.enabled" />
              </div>
              <Button @click="openRewardPicker(section.key, index)">选择奖励组</Button>
              <Button @click="clearRewardGroup(section.key, index)">清空</Button>
              <Button danger @click="removeRule(section.key, index)">删除</Button>
            </div>
          </Card>
        </div>
      </Spin>
    </Card>

    <ActivityResourceGroupSelectDrawer
      :open="groupPickerOpen"
      :sys-origin="form.sysOrigin"
      @close="groupPickerOpen = false"
      @select="handleRewardGroupSelect"
    />
  </Page>
</template>

<style scoped>
.toolbar {
  margin-bottom: 16px;
}

.toolbar-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.toolbar-label,
.label {
  color: #475569;
  font-weight: 600;
}

.section-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.field-span-2 {
  grid-column: span 2;
}

.reward-row,
.rule-item {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}

.field-grow {
  flex: 1;
  min-width: 240px;
}

.switch-field {
  min-width: 88px;
}

.reward-group-box {
  min-height: 32px;
  display: flex;
  align-items: center;
}

.placeholder {
  color: #94a3b8;
}

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  gap: 12px;
}

.empty-box {
  color: #94a3b8;
  padding: 12px 0;
}

.section-tip {
  color: #64748b;
}
</style>
