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

import {
  Button,
  Drawer,
  Form,
  FormItem,
  Input,
  message,
  Select,
  Space,
  Switch,
} from 'antdv-next';

import { listEmojiGroupsBySysOrigin } from '#/api/legacy/app-system';
import { listBadgePictureBySysOrigin } from '#/api/legacy/badge';
import { listGiftBySysOrigin } from '#/api/legacy/gift';
import {
  listNotFamilyBySysOriginType,
  listSysOriginTypeList,
  saveOrUpdatePropsActivityRewardGroup,
} from '#/api/legacy/props';
import { getDisplaySysOriginText } from '#/views/system/shared';

import {
  formatRewardText,
  getPropsTypeName,
  getRewardBadgeType,
  isBadgeRewardType,
  isCurrencyRewardType,
  isGameCouponType,
  isPropsCouponType,
  PROPS_SOURCE_GROUP_ADD_TYPES,
  PROPS_SOURCE_GROUP_TYPE_MAP,
} from '../shared';
import RewardIcon from './reward-icon.vue';

const props = defineProps<{
  open: boolean;
  record: null | Record<string, any>;
  sysOrigin: string;
}>();

const emit = defineEmits<{
  close: [];
  success: [];
}>();

const saving = ref(false);
const draftLoading = ref(false);

type DraftSourceOption = {
  badgeName?: string;
  cover?: string;
  id: number | string;
  name: string;
  remark?: string;
  sourceUrl?: string;
};

type RewardGroupItem = {
  badgeName?: string;
  content: number | string;
  cover?: string;
  detailType: string;
  quantity: number | string;
  remark: string;
  sourceUrl?: string;
  type: string;
};

const form = reactive<{
  id: number | string;
  name: string;
  rewardConfigList: RewardGroupItem[];
  shelfStatus: boolean;
  sysOrigin: string;
}>({
  id: '',
  name: '',
  rewardConfigList: [],
  shelfStatus: true,
  sysOrigin: '',
});

const draft = reactive<{
  content: number | string;
  quantity: number | string;
  remark: string;
  type: string;
}>({
  content: '',
  quantity: '',
  remark: '',
  type: '',
});

const sourceOptionsMap = reactive<
  Record<string, { list: DraftSourceOption[]; loaded: boolean; loading: boolean }>
>({});

const selectedDraftResource = ref<DraftSourceOption | null>(null);

const title = computed(() => {
  const sysOrigin = getDisplaySysOriginText(props.sysOrigin || form.sysOrigin);
  const action = form.id ? '修改' : '添加';
  return sysOrigin ? `${action}（${sysOrigin}）` : action;
});

const rewardItems = computed(() => form.rewardConfigList);
const sourceSelectOptions = computed<DraftSourceOption[]>(
  () => sourceOptionsMap[draft.type]?.list || [],
);
const addTypeOptions = computed(() =>
  PROPS_SOURCE_GROUP_ADD_TYPES.map((type) => ({
    label: getAddTypeName(type),
    value: type as any,
  })),
);
const draftResourceOptions = computed(() =>
  sourceSelectOptions.value.map((item) => ({
    label: `${item.id} ${item.name}`,
    value: item.id as any,
  })),
);

function resetSourceOptionsMap() {
  Object.keys(sourceOptionsMap).forEach((key) => {
    delete sourceOptionsMap[key];
  });
}

function createTypeStore(type: string) {
  if (!sourceOptionsMap[type]) {
    sourceOptionsMap[type] = { list: [], loaded: false, loading: false };
  }
  return sourceOptionsMap[type];
}

function resetForm() {
  form.id = '';
  form.name = '';
  form.rewardConfigList = [];
  form.shelfStatus = true;
  form.sysOrigin = props.sysOrigin || '';
}

function resetDraft() {
  draft.content = '';
  draft.quantity = '';
  draft.remark = '';
  draft.type = '';
  selectedDraftResource.value = null;
}

watch(
  () => props.open,
  (open) => {
    if (!open) {
      return;
    }
    resetSourceOptionsMap();
    const record = props.record;
    if (!record) {
      resetForm();
      resetDraft();
      return;
    }
    form.id = record.id ?? '';
    form.name = record.name ?? '';
    form.rewardConfigList = (record.rewardConfigList || []).map((item: RewardGroupItem) => ({
      ...item,
    }));
    form.shelfStatus = Boolean(record.shelfStatus ?? true);
    form.sysOrigin = props.sysOrigin || record.sysOrigin || '';
    resetDraft();
  },
  { immediate: true },
);

watch(
  () => props.sysOrigin,
  (value) => {
    if (value) {
      if (form.sysOrigin && form.sysOrigin !== value) {
        resetSourceOptionsMap();
        resetDraft();
      }
      form.sysOrigin = value;
    }
  },
  { immediate: true },
);

function needsRemoteOptions(type: string) {
  return !(
    ['DIAMOND', 'GAME_COUPON', 'GOLD', 'PROP_COUPON', 'SPECIAL_ID'].includes(type)
  );
}

async function loadOptions(type: string) {
  if (!type || !form.sysOrigin || !needsRemoteOptions(type)) {
    return;
  }
  const store = createTypeStore(type);
  if (store.loaded || store.loading) {
    return;
  }
  store.loading = true;
  draftLoading.value = true;
  try {
    switch (type) {
      case 'BADGE': {
        const list = await listSysOriginTypeList(form.sysOrigin, 'BADGE');
        store.list = list.map((item) => ({
          badgeName: item.name || '',
          cover: item.cover || '',
          id: item.id ?? '',
          name: item.name || '',
          sourceUrl: item.sourceUrl || '',
        }));
        break;
      }
      case 'EMOJI': {
        const list = await listEmojiGroupsBySysOrigin(form.sysOrigin);
        store.list = list.map((item) => ({
          cover: item.cover || '',
          id: item.id ?? '',
          name: item.groupName || '',
          sourceUrl: '',
        }));
        break;
      }
      case 'GIFT': {
        const list = await listGiftBySysOrigin(form.sysOrigin);
        store.list = list.map((item) => ({
          cover: item.giftPhoto || '',
          id: item.id ?? '',
          name: item.giftName || '',
          sourceUrl: item.giftSourceUrl || '',
        }));
        break;
      }
      case 'NOBLE_VIP': {
        const list = await listNotFamilyBySysOriginType(form.sysOrigin, type);
        store.list = list.map((item) => ({
          cover: item.cover || '',
          id: item.id ?? '',
          name: item.name || '',
          sourceUrl: item.sourceUrl || '',
        }));
        break;
      }
      default: {
        if (isBadgeRewardType(type)) {
          const badgeType = getRewardBadgeType(type);
          const list = await listBadgePictureBySysOrigin(form.sysOrigin, badgeType);
          store.list = list.map((item) => ({
            badgeName: item.badgeName || '',
            cover: item.selectUrl || '',
            id: item.badgeConfigId ?? '',
            name: item.badgeName || '',
            sourceUrl: item.animationUrl || '',
          }));
          break;
        }
        const list = await listSysOriginTypeList(form.sysOrigin, type);
        store.list = list.map((item) => ({
          cover: item.cover || '',
          id: item.id ?? '',
          name: item.name || '',
          remark: item.remark || '',
          sourceUrl: item.sourceUrl || '',
        }));
      }
    }
    store.loaded = true;
  } finally {
    store.loading = false;
    draftLoading.value = false;
  }
}

async function handleDraftTypeChange(value: string) {
  resetDraft();
  draft.type = value;
  await loadOptions(value);
}

function handleDraftContentChange(value: number | string) {
  if (!draft.type || !needsRemoteOptions(draft.type)) {
    return;
  }
  const option = sourceSelectOptions.value.find(
    (item) => String(item.id) === String(value),
  );
  selectedDraftResource.value = option || null;
}

function buildRewardItem(): null | RewardGroupItem {
  if (!draft.type) {
    return null;
  }
  const mapping = PROPS_SOURCE_GROUP_TYPE_MAP[draft.type];
  if (!mapping) {
    return null;
  }
  const base: RewardGroupItem = {
    content: draft.content,
    cover: selectedDraftResource.value?.cover || '',
    detailType: draft.type,
    quantity: draft.quantity,
    remark: draft.remark,
    sourceUrl: selectedDraftResource.value?.sourceUrl || '',
    type: mapping.value,
  };
  if (isBadgeRewardType(draft.type)) {
    base.badgeName = selectedDraftResource.value?.name || '';
  }
  return base;
}

function getAddTypeName(type: string) {
  return PROPS_SOURCE_GROUP_TYPE_MAP[type]?.name || getPropsTypeName(type);
}

function validateDraft() {
  if (!draft.type) {
    message.warning('请选择奖励类型');
    return false;
  }
  if (draft.type === 'SPECIAL_ID') {
    if (!String(draft.content || '').trim()) {
      message.warning('请输入靓号类型');
      return false;
    }
    if (draft.quantity === '' || Number.isNaN(Number(draft.quantity))) {
      message.warning('请输入数量');
      return false;
    }
    return true;
  }
  if (isCurrencyRewardType(draft.type) || isGameCouponType(draft.type)) {
    if (draft.content === '' || Number.isNaN(Number(draft.content))) {
      message.warning('请输入数量');
      return false;
    }
    return true;
  }
  if (isPropsCouponType(draft.type)) {
    if (draft.content === '' || Number.isNaN(Number(draft.content))) {
      message.warning('请输入券数');
      return false;
    }
    if (draft.quantity === '' || Number.isNaN(Number(draft.quantity))) {
      message.warning('请输入数量');
      return false;
    }
    return true;
  }
  if (!draft.content) {
    message.warning('请选择资源');
    return false;
  }
  if (draft.type === 'CUSTOMIZE') {
    if (!String(draft.remark || '').trim()) {
      message.warning('请输入描述');
      return false;
    }
    return true;
  }
  if (draft.quantity === '' || Number.isNaN(Number(draft.quantity))) {
    message.warning('请输入数量/天数');
    return false;
  }
  return true;
}

function addDraftItem() {
  if (!validateDraft()) {
    return;
  }
  const item = buildRewardItem();
  if (!item) {
    return;
  }
  form.rewardConfigList.push(item);
  resetDraft();
}

function moveItem(index: number, direction: -1 | 1) {
  const target = index + direction;
  if (target < 0 || target >= form.rewardConfigList.length) {
    return;
  }
  const list = [...form.rewardConfigList];
  const current = list[index];
  const next = list[target];
  if (!current || !next) {
    return;
  }
  list[index] = next;
  list[target] = current;
  form.rewardConfigList = list;
}

function removeItem(index: number) {
  form.rewardConfigList.splice(index, 1);
}

async function handleSubmit() {
  if (!String(form.name || '').trim()) {
    message.warning('请输入类型名称');
    return;
  }
  if (form.rewardConfigList.length === 0) {
    message.warning('请先配置资源组内容');
    return;
  }
  saving.value = true;
  try {
    await saveOrUpdatePropsActivityRewardGroup({
      id: form.id || undefined,
      name: form.name.trim(),
      rewardConfigList: form.rewardConfigList.map((item: RewardGroupItem, index: number) => ({
        content: item.content,
        detailType: item.detailType,
        quantity: item.quantity,
        remark: item.remark,
        sort: index + 1,
        type: item.type,
      })),
      shelfStatus: form.shelfStatus,
      sysOrigin: form.sysOrigin,
    });
    message.success('保存成功');
    emit('success');
    emit('close');
  } finally {
    saving.value = false;
  }
}
</script>

<template>
  <Drawer
    :open="open"
    :title="title"
    width="980"
    @close="emit('close')"
  >
    <Form layout="vertical">
      <FormItem label="类型名称">
        <Input v-model:value="form.name" placeholder="类别名称" />
      </FormItem>
      <FormItem label="上架状态">
        <Switch
          v-model:checked="form.shelfStatus"
          checked-children="上架"
          un-checked-children="下架"
        />
      </FormItem>

      <div class="reward-list">
        <div
          v-for="(item, index) in rewardItems"
          :key="`${item.detailType}-${item.content}-${index}`"
          class="reward-list__item"
        >
          <div class="reward-list__order">{{ Number(index) + 1 }}</div>
          <RewardIcon :item="item" />
          <div class="reward-list__info">
            <div class="reward-list__title">
              {{ getPropsTypeName(item.detailType || item.type) }}
            </div>
            <div class="reward-list__desc">
              {{ formatRewardText(item) }}
            </div>
          </div>
          <Space>
            <Button size="small" @click="moveItem(Number(index), -1)">上移</Button>
            <Button size="small" @click="moveItem(Number(index), 1)">下移</Button>
            <Button danger size="small" @click="removeItem(Number(index))">删除</Button>
          </Space>
        </div>
      </div>

      <div class="draft-box">
        <div class="draft-box__title">添加配置</div>
        <FormItem label="奖励类型">
          <Select
            v-model:value="draft.type"
            :options="addTypeOptions"
            option-label-prop="label"
            placeholder="请选择奖励类型"
            @change="handleDraftTypeChange"
          />
        </FormItem>

        <template v-if="draft.type === 'SPECIAL_ID'">
          <FormItem label="靓号类型">
            <Input v-model:value="draft.content" placeholder="请输入靓号类型" />
          </FormItem>
          <FormItem label="数量">
            <Input v-model:value="draft.quantity" placeholder="请输入数量" />
          </FormItem>
        </template>

        <template v-else-if="isCurrencyRewardType(draft.type) || isGameCouponType(draft.type)">
          <FormItem label="数量">
            <Input v-model:value="draft.content" placeholder="请输入数量" />
          </FormItem>
        </template>

        <template v-else-if="isPropsCouponType(draft.type)">
          <FormItem label="券数">
            <Input v-model:value="draft.content" placeholder="请输入券数" />
          </FormItem>
          <FormItem label="数量">
            <Input v-model:value="draft.quantity" placeholder="请输入数量" />
          </FormItem>
        </template>

        <template v-else>
          <FormItem label="资源">
            <Select
              v-model:value="draft.content"
              :options="draftResourceOptions"
              :loading="draftLoading"
              option-filter-prop="label"
              option-label-prop="label"
              placeholder="请选择资源"
              show-search
              @change="handleDraftContentChange"
            />
          </FormItem>

          <div v-if="selectedDraftResource" class="draft-preview">
            <RewardIcon :item="selectedDraftResource" :size="56" />
            <div class="draft-preview__meta">
              <div>{{ selectedDraftResource.name }}</div>
              <div class="draft-preview__id">
                ID: {{ selectedDraftResource.id }}
              </div>
            </div>
          </div>

          <FormItem v-if="draft.type === 'CUSTOMIZE'" label="描述">
            <Input v-model:value="draft.remark" placeholder="请输入描述" />
          </FormItem>

          <FormItem v-else label="数量/天数">
            <Input
              v-model:value="draft.quantity"
              :placeholder="
                isBadgeRewardType(draft.type)
                  ? '请输入天数，0 表示永久'
                  : '请输入数量/天数'
              "
            />
          </FormItem>
        </template>

        <Button type="primary" @click="addDraftItem">加入配置</Button>
      </div>
    </Form>

    <template #footer>
      <Space>
        <Button @click="emit('close')">取消</Button>
        <Button :loading="saving" type="primary" @click="handleSubmit">
          保存
        </Button>
      </Space>
    </template>
  </Drawer>
</template>

<style scoped>
.draft-box {
  background: rgb(248 250 252);
  border: 1px solid rgb(226 232 240);
  border-radius: 16px;
  margin-top: 16px;
  padding: 16px;
}

.draft-box__title {
  color: rgb(15 23 42);
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 12px;
}

.draft-preview {
  align-items: center;
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}

.draft-preview__id {
  color: rgb(100 116 139);
  font-size: 12px;
}

.reward-list {
  display: grid;
  gap: 12px;
}

.reward-list__item {
  align-items: center;
  background: #fff;
  border: 1px solid rgb(226 232 240);
  border-radius: 16px;
  display: grid;
  gap: 12px;
  grid-template-columns: 40px 56px 1fr auto;
  padding: 12px;
}

.reward-list__info {
  min-width: 0;
}

.reward-list__order {
  align-items: center;
  background: rgb(241 245 249);
  border-radius: 999px;
  color: rgb(15 23 42);
  display: inline-flex;
  font-size: 12px;
  font-weight: 600;
  height: 32px;
  justify-content: center;
  width: 32px;
}

.reward-list__title {
  color: rgb(15 23 42);
  font-weight: 600;
}

.reward-list__desc {
  color: rgb(100 116 139);
  font-size: 13px;
  margin-top: 4px;
}
</style>
