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

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

import {
  mapLuckyGiftStandard,
} from '#/api/legacy/game-lucky-gift';
import {
  addGift,
  updateGift,
} from '#/api/legacy/gift';
import {
  getAccessImgUrl,
  simpleUploadFile,
} from '#/api/legacy/oss';
import {
  regionConfigTable,
} from '#/api/legacy/system';

import {
  CP_RELATION_TYPE_OPTIONS,
  GIFT_CONFIG_TAB_OPTIONS,
  GIFT_SPECIAL_OPTIONS,
} from '../constants';

defineOptions({ name: 'OperateGiftFormModal' });

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

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

function createForm(sysOrigin = '') {
  return {
    account: '',
    explanationGift: false,
    expiredTime: '',
    giftCandy: '',
    giftCode: '',
    giftIntegral: '',
    giftName: '',
    giftPhoto: '',
    giftSourceUrl: '',
    giftTab: 'ORDINARY',
    id: '',
    cpRelationType: 'CP',
    regionList: [] as Array<number | string>,
    sort: '',
    specialList: [] as string[],
    standardId: '',
    sysOrigin,
    type: 'GOLD',
  };
}

const form = reactive(createForm());
const loading = ref(false);
const saving = ref(false);
const coverInputRef = ref<HTMLInputElement | null>(null);
const sourceInputRef = ref<HTMLInputElement | null>(null);
const coverUploading = ref(false);
const sourceUploading = ref(false);
const regions = ref<Array<Record<string, any>>>([]);
const standardOptions = ref<Array<Record<string, any>>>([]);
const previousStandardId = ref<number | string>('');

const previewCover = computed(() => getAccessImgUrl(form.giftPhoto));
const previewSource = computed(() => getAccessImgUrl(form.giftSourceUrl));
const title = computed(() => (form.id ? '编辑礼物' : '新增礼物'));
const regionOptions = computed(() =>
  regions.value.map((item) => ({
    label: String(item.regionName || item.name || item.id || '-'),
    value: item.id as any,
  })),
);
const giftTabOptions = GIFT_CONFIG_TAB_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const cpRelationTypeOptions = CP_RELATION_TYPE_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const chargeTypeOptions = [
  { label: '金币', value: 'GOLD' },
  { label: '钻石', value: 'DIAMOND' },
  { disabled: true, label: '免费', value: 'FREE' },
];
const specialOptions = GIFT_SPECIAL_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const standardSelectOptions = computed(() =>
  standardOptions.value.map((item) => ({
    label: String(item.name || item.label || item.value || item.id || '-'),
    value: (item.value || item.id) as any,
  })),
);
const isLuckyOrMagic = computed(
  () => form.giftTab === 'LUCKY_GIFT' || form.giftTab === 'MAGIC',
);

function normalizeMultiValue(value: any) {
  if (Array.isArray(value)) {
    return value.filter((item) => item !== '' && item !== null && item !== undefined);
  }
  if (value === '' || value === null || value === undefined) {
    return [];
  }
  return String(value)
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean);
}

function normalizeTimestampValue(value: any) {
  if (value === '' || value === null || value === undefined) {
    return '';
  }
  return String(value);
}

function resetForm() {
  Object.assign(form, createForm(props.sysOrigin));
  previousStandardId.value = '';
}

async function loadAuxiliary() {
  if (!form.sysOrigin) {
    return;
  }
  loading.value = true;
  try {
    regions.value = (await regionConfigTable({ sysOrigin: form.sysOrigin })) || [];
    standardOptions.value = (await mapLuckyGiftStandard(form.sysOrigin)) || [];
  } finally {
    loading.value = false;
  }
}

watch(
  () => props.open,
  async (open) => {
    if (!open) {
      return;
    }
    resetForm();
    if (props.row) {
      Object.assign(form, {
        ...props.row,
        explanationGift: Boolean(props.row.explanationGift),
        expiredTime: normalizeTimestampValue(props.row.expiredTime),
        cpRelationType: props.row.cpRelationType || 'CP',
        regionList: normalizeMultiValue(props.row.regions || props.row.regionList),
        specialList: normalizeMultiValue(props.row.special || props.row.specialList),
        sysOrigin: props.row.sysOrigin || props.sysOrigin,
      });
      previousStandardId.value = props.row.standardId || '';
    } else {
      form.sysOrigin = props.sysOrigin;
    }
    await loadAuxiliary();
  },
  { immediate: true },
);

watch(
  () => form.sysOrigin,
  () => {
    if (props.open) {
      void loadAuxiliary();
    }
  },
);

watch(
  () => form.giftTab,
  (giftTab) => {
    if (giftTab === 'CP' && !form.cpRelationType) {
      form.cpRelationType = 'CP';
    }
  },
);

function toggleAllRegions() {
  if (form.regionList.length === regions.value.length) {
    form.regionList = [];
    return;
  }
  form.regionList = regions.value.map((item) => item.id);
}

function openCoverUpload() {
  coverInputRef.value?.click();
}

function openSourceUpload() {
  sourceInputRef.value?.click();
}

async function handleCoverUpload(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  target.value = '';
  if (!file) {
    return;
  }
  coverUploading.value = true;
  try {
    const result = await simpleUploadFile(file, 'gifts');
    form.giftPhoto = result.name;
    message.success('上传成功');
  } finally {
    coverUploading.value = false;
  }
}

async function handleSourceUpload(event: Event) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  target.value = '';
  if (!file) {
    return;
  }
  sourceUploading.value = true;
  try {
    const result = await simpleUploadFile(file, 'gifts');
    form.giftSourceUrl = result.name;
    message.success('上传成功');
  } finally {
    sourceUploading.value = false;
  }
}

async function handleSubmit() {
  if (!form.sysOrigin) {
    message.warning('请选择平台');
    return;
  }
  if (!form.giftName.trim()) {
    message.warning('请输入礼物名称');
    return;
  }
  if (!form.giftCode.trim()) {
    message.warning('请输入礼物编码');
    return;
  }
  if (!form.giftPhoto) {
    message.warning('请上传封面');
    return;
  }
  if (!form.giftCandy && form.type !== 'FREE') {
    message.warning('请输入金币');
    return;
  }
  if (!form.giftIntegral && form.type !== 'FREE') {
    message.warning('请输入积分');
    return;
  }
  if (!form.sort) {
    message.warning('请输入排序');
    return;
  }
  if ((form.regionList || []).length <= 0) {
    message.warning('请至少选择一个区域');
    return;
  }
  if (form.giftTab === 'EXCLUSIVE' && !String(form.account || '').trim()) {
    message.warning('请输入归属人账号');
    return;
  }
  if (form.giftTab === 'CP' && !form.cpRelationType) {
    message.warning('请选择CP礼物类型');
    return;
  }
  if (isLuckyOrMagic.value && !form.standardId) {
    message.warning('幸运/魔法礼物必须选择规格');
    return;
  }
  if (
    form.giftTab === 'LUCKY_GIFT' &&
    previousStandardId.value &&
    previousStandardId.value !== form.standardId
  ) {
    const confirmed = window.confirm(
      '修改规格会立刻切换新规格和新抽奖数据，是否确定切换？',
    );
    if (!confirmed) {
      return;
    }
  }

  saving.value = true;
  try {
    const payload = {
      ...form,
      cpRelationType: form.giftTab === 'CP' ? form.cpRelationType : '',
      giftCandy: form.type === 'FREE' ? '' : form.giftCandy,
      giftIntegral: form.type === 'FREE' ? '' : form.giftIntegral,
    };
    await (payload.id ? updateGift(payload) : addGift(payload));
    message.success('保存成功');
    emit('success');
    emit('close');
  } finally {
    saving.value = false;
  }
}
</script>

<template>
  <Drawer
    :open="open"
    :title="title"
    destroy-on-close
    root-class="gift-form-drawer-root"
    width="1120"
    :styles="{
      body: { padding: '0', overflow: 'hidden' },
      footer: { padding: '10px 16px' },
    }"
    @close="emit('close')"
  >
    <Spin :spinning="loading" wrapper-class-name="gift-editor-spin">
      <div class="gift-editor">
        <aside class="media-panel">
          <div class="media-block">
            <div class="media-head">
              <span>封面</span>
              <span class="required-mark">必填</span>
            </div>
            <Image
              v-if="previewCover"
              :src="previewCover"
              class="preview-image"
            />
            <div v-else class="preview-image preview-image--empty">未上传</div>
            <div class="media-actions">
              <Button :loading="coverUploading" size="small" @click="openCoverUpload">
                上传封面
              </Button>
              <Button
                v-if="form.giftPhoto"
                danger
                size="small"
                @click="form.giftPhoto = ''"
              >
                清空
              </Button>
            </div>
          </div>

          <div class="media-block">
            <div class="media-head">
              <span>资源</span>
              <span class="optional-mark">可选</span>
            </div>
            <div class="source-value">{{ previewSource || '未上传' }}</div>
            <div class="media-actions">
              <Button :loading="sourceUploading" size="small" @click="openSourceUpload">
                上传资源
              </Button>
              <Button
                v-if="form.giftSourceUrl"
                danger
                size="small"
                @click="form.giftSourceUrl = ''"
              >
                清空
              </Button>
            </div>
          </div>
        </aside>

        <main class="editor-panel">
          <Form class="editor-form" layout="vertical">
            <div class="section-title">基础信息</div>
            <div class="form-grid">
              <FormItem label="礼物类型">
                <Select
                  v-model:value="form.giftTab"
                  :options="giftTabOptions"
                  option-label-prop="label"
                  placeholder="请选择礼物类型"
                />
              </FormItem>
              <FormItem label="收费类型">
                <Select
                  v-model:value="form.type"
                  :options="chargeTypeOptions"
                  option-label-prop="label"
                  placeholder="请选择收费类型"
                />
              </FormItem>
              <FormItem label="排序">
                <Input v-model:value="form.sort" />
              </FormItem>
              <FormItem class="span-2" label="名称">
                <Input v-model:value="form.giftName" />
              </FormItem>
              <FormItem label="Code">
                <Input v-model:value="form.giftCode" />
              </FormItem>
              <FormItem label="有效期">
                <DatePicker
                  v-model:value="form.expiredTime"
                  style="width: 100%"
                  value-format="x"
                />
              </FormItem>
              <FormItem label="金币">
                <Input v-model:value="form.giftCandy" :disabled="form.type === 'FREE'" />
              </FormItem>
              <FormItem label="积分">
                <Input v-model:value="form.giftIntegral" :disabled="form.type === 'FREE'" />
              </FormItem>
            </div>

            <div class="section-title section-title--spaced">范围与效果</div>
            <div class="form-grid">
              <FormItem class="span-3" label="区域">
                <div class="inline-field">
                  <Select
                    v-model:value="form.regionList"
                    :max-tag-count="4"
                    :options="regionOptions"
                    class="compact-multiple-select"
                    mode="multiple"
                    option-label-prop="label"
                    placeholder="请选择区域"
                    show-search
                  />
                  <Button size="small" @click="toggleAllRegions">
                    {{ form.regionList.length === regions.length ? '取消全选' : '全选' }}
                  </Button>
                </div>
              </FormItem>
              <FormItem class="span-3" label="特效">
                <Select
                  v-model:value="form.specialList"
                  :max-tag-count="4"
                  :options="specialOptions"
                  class="compact-multiple-select"
                  mode="multiple"
                  option-label-prop="label"
                  placeholder="请选择特效"
                />
              </FormItem>
              <FormItem v-if="form.giftTab === 'EXCLUSIVE'" label="归属人账号">
                <Input v-model:value="form.account" />
              </FormItem>
              <FormItem v-if="isLuckyOrMagic" label="幸运规格">
                <Select
                  v-model:value="form.standardId"
                  :options="standardSelectOptions"
                  option-label-prop="label"
                  placeholder="请选择幸运规格"
                />
              </FormItem>
              <FormItem v-if="form.giftTab === 'CP'" label="CP礼物类型">
                <Select
                  v-model:value="form.cpRelationType"
                  :options="cpRelationTypeOptions"
                  option-label-prop="label"
                  placeholder="请选择CP礼物类型"
                />
              </FormItem>
              <FormItem v-if="form.giftTab === 'CP'" label="告白礼物">
                <Switch v-model:checked="form.explanationGift" />
              </FormItem>
            </div>
          </Form>
        </main>
      </div>
    </Spin>

    <input
      ref="coverInputRef"
      accept="image/*"
      hidden
      type="file"
      @change="handleCoverUpload"
    />
    <input
      ref="sourceInputRef"
      accept=".svga,.pag,.mp4"
      hidden
      type="file"
      @change="handleSourceUpload"
    />

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

<style scoped>
.gift-editor {
  background: #f6f8fb;
  display: grid;
  gap: 12px;
  grid-template-columns: 260px minmax(0, 1fr);
  height: calc(100vh - 106px);
  min-height: 0;
  padding: 12px;
}

.media-panel,
.editor-panel {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  min-height: 0;
}

.media-panel {
  display: grid;
  align-content: start;
  gap: 12px;
  overflow: auto;
  padding: 12px;
}

.media-block {
  display: grid;
  gap: 8px;
}

.media-head {
  align-items: center;
  color: #111827;
  display: flex;
  font-size: 13px;
  font-weight: 600;
  justify-content: space-between;
}

.required-mark,
.optional-mark {
  border-radius: 999px;
  font-size: 12px;
  font-weight: 400;
  line-height: 18px;
  padding: 0 8px;
}

.required-mark {
  background: #fff1f2;
  color: #e11d48;
}

.optional-mark {
  background: #f1f5f9;
  color: #64748b;
}

.preview-image {
  background: #f8fafc;
  border: 1px solid #eef2f7;
  border-radius: 8px;
  height: 180px;
  object-fit: cover;
  width: 100%;
}

.preview-image--empty,
.source-value {
  align-items: center;
  background: #f8fafc;
  border: 1px dashed #cbd5e1;
  border-radius: 8px;
  color: #94a3b8;
  display: flex;
  font-size: 12px;
  min-height: 72px;
  padding: 10px;
  word-break: break-all;
}

.media-actions,
.drawer-footer-actions {
  display: flex;
  justify-content: flex-end;
}

.editor-panel {
  overflow: auto;
  padding: 14px 16px;
}

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

.editor-form :deep(.ant-form-item-label) {
  padding-bottom: 4px;
}

.editor-form :deep(.ant-form-item-label > label) {
  color: #475569;
  font-size: 12px;
  height: 18px;
}

.editor-form :deep(.ant-input),
.editor-form :deep(.ant-picker),
.editor-form :deep(.ant-select-selector) {
  border-radius: 6px;
}

.section-title {
  color: #111827;
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  margin-bottom: 8px;
}

.section-title--spaced {
  border-top: 1px solid #eef2f7;
  margin-top: 4px;
  padding-top: 12px;
}

.form-grid {
  display: grid;
  column-gap: 12px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

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

.span-3 {
  grid-column: 1 / -1;
}

.inline-field {
  align-items: center;
  display: grid;
  gap: 8px;
  grid-template-columns: minmax(0, 1fr) auto;
}

.compact-multiple-select :deep(.ant-select-selection-overflow) {
  flex-wrap: nowrap;
  overflow: hidden;
}

.compact-multiple-select :deep(.ant-select-selection-item) {
  max-width: 140px;
}

@media (max-width: 900px) {
  .gift-editor {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    overflow: auto;
  }

  .form-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .span-2,
  .span-3 {
    grid-column: auto;
  }
}
</style>
