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

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

import {
  getAccessImgUrl,
  OSS_FILE_BUCKETS,
  simpleUploadFile,
} from '#/api/legacy/oss';
import {
  addPropsSource,
  updatePropsSource,
} from '#/api/legacy/props';

import {
  BADGE_DISPLAY_TYPE_OPTIONS,
  NOBLE_VIP_OPTIONS,
  PROPS_RESOURCE_CONFIG_TYPES,
} from '../shared';

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

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

const saving = ref(false);
const coverUploading = ref(false);
const sourceUploading = ref(false);
const expandUploading = ref(false);
const notSelectUploading = ref(false);

const coverInputRef = ref<HTMLInputElement>();
const sourceInputRef = ref<HTMLInputElement>();
const expandInputRef = ref<HTMLInputElement>();
const notSelectInputRef = ref<HTMLInputElement>();

const form = reactive<Record<string, any>>({
  adminFree: false,
  amount: '',
  badgeDisplayType: 'SHORT',
  code: '',
  cover: '',
  expand: '',
  id: '',
  name: '',
  notSelectUrl: '',
  sourceUrl: '',
  sysOrigin: '',
  type: '',
});

const isUpdate = computed(() => Boolean(form.id));
const isImageSourceType = computed(() =>
  ['CHAT_BUBBLE', 'LAYOUT', 'THEME'].includes(form.type),
);
const isAmountRequired = computed(
  () => !['CUSTOMIZE', 'FRAGMENTS'].includes(form.type),
);
const showSourceUpload = computed(
  () => !['CUSTOMIZE', 'FRAGMENTS'].includes(form.type),
);
const isSourceRequired = computed(
  () => !['BADGE', 'CUSTOMIZE', 'FRAGMENTS'].includes(form.type),
);
const showExpandUpload = computed(() => form.type === 'CHAT_BUBBLE');
const sourceUploadLabel = computed(() => {
  if (form.type === 'BADGE') {
    return '动效资源(选填)';
  }
  if (showExpandUpload.value) {
    return 'iOS资源';
  }
  return isSourceRequired.value ? '资源' : '资源(选填)';
});
const title = computed(() => (isUpdate.value ? '修改资源' : '新增资源'));
const propsTypeOptions = PROPS_RESOURCE_CONFIG_TYPES.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const nobleVipNameOptions = NOBLE_VIP_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));
const badgeDisplayTypeOptions = BADGE_DISPLAY_TYPE_OPTIONS.map((item) => ({
  label: item.name,
  value: item.value as any,
}));

function parseBadgeExpand(value: unknown) {
  if (!value || typeof value !== 'string') {
    return {};
  }
  try {
    return JSON.parse(value) as Record<string, any>;
  } catch {
    return {};
  }
}

function applyBadgeExpand(value: unknown) {
  const expand = parseBadgeExpand(value);
  form.badgeDisplayType = normalizeBadgeDisplayType(
    expand.badgeDisplayType || expand.displayType,
    expand.badgeType,
  );
  form.notSelectUrl = expand.notSelectUrl ?? '';
}

function buildBadgeExpand() {
  const expand: Record<string, any> = {
    badgeDisplayType: normalizeBadgeDisplayType(form.badgeDisplayType),
  };
  if (String(form.notSelectUrl || '').trim()) {
    expand.notSelectUrl = String(form.notSelectUrl).trim();
  }
  return JSON.stringify(expand);
}

function normalizeBadgeDisplayType(value: unknown, badgeType?: unknown) {
  const displayType = String(value || '').trim().toUpperCase();
  if (displayType === 'LONG' || displayType === 'SHORT') {
    return displayType;
  }
  return String(badgeType || '').trim().toUpperCase() === 'VIP' ? 'LONG' : 'SHORT';
}

function resetForm() {
  form.adminFree = false;
  form.amount = '';
  form.badgeDisplayType = 'SHORT';
  form.code = '';
  form.cover = '';
  form.expand = '';
  form.id = '';
  form.name = '';
  form.notSelectUrl = '';
  form.sourceUrl = '';
  form.sysOrigin = props.sysOriginOptions[0]?.value ?? 'LIKEI';
  form.type = PROPS_RESOURCE_CONFIG_TYPES[0]?.value ?? '';
}

watch(
  () => props.open,
  (open) => {
    if (!open) {
      return;
    }
    const record = props.record;
    if (!record) {
      resetForm();
      return;
    }
    form.adminFree = Boolean(record.adminFree);
    form.amount = record.amount ?? '';
    form.code = record.code ?? '';
    form.cover = record.cover ?? '';
    form.expand = record.expand ?? '';
    form.id = record.id ?? '';
    form.name = record.name ?? '';
    form.sourceUrl = record.sourceUrl ?? '';
    form.sysOrigin = record.sysOrigin || props.sysOriginOptions[0]?.value || 'LIKEI';
    form.type = record.type ?? '';
    if (form.type === 'BADGE') {
      applyBadgeExpand(record.expand);
    } else {
      applyBadgeExpand('');
    }
  },
  { immediate: true },
);

watch(
  () => form.type,
  (value) => {
    if (!value) {
      return;
    }
    if (value === 'NOBLE_VIP' && !NOBLE_VIP_OPTIONS.some((item) => item.value === form.name)) {
      form.name = '';
    }
    if (['CUSTOMIZE', 'FRAGMENTS'].includes(value)) {
      form.amount = 0;
      form.sourceUrl = '';
      form.expand = '';
    }
    if (value === 'BADGE' && !form.badgeDisplayType) {
      form.badgeDisplayType = 'SHORT';
    }
    if (!['BADGE', 'CHAT_BUBBLE'].includes(value)) {
      form.expand = '';
    }
  },
);

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

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

function openExpandPicker() {
  expandInputRef.value?.click();
}

function openNotSelectPicker() {
  notSelectInputRef.value?.click();
}

function handleCoverInput(event: Event) {
  void uploadFile(event, 'cover', coverUploading, true);
}

function handleSourceInput(event: Event) {
  void uploadFile(event, 'sourceUrl', sourceUploading, isImageSourceType.value);
}

function handleExpandInput(event: Event) {
  void uploadFile(event, 'expand', expandUploading, true);
}

function handleNotSelectInput(event: Event) {
  void uploadFile(event, 'notSelectUrl', notSelectUploading, true);
}

function clearUpload(targetKey: 'cover' | 'expand' | 'notSelectUrl' | 'sourceUrl') {
  form[targetKey] = '';
}

function getAssetName(value: unknown) {
  const text = String(value || '').trim();
  if (!text) {
    return '';
  }
  return decodeURIComponent(text.split('/').pop() || text);
}

async function uploadFile(
  event: Event,
  targetKey: 'cover' | 'expand' | 'notSelectUrl' | 'sourceUrl',
  loadingRef: typeof coverUploading,
  imageBucket = false,
) {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  target.value = '';
  if (!file) {
    return;
  }
  loadingRef.value = true;
  try {
    const result = await simpleUploadFile(
      file,
      imageBucket ? OSS_FILE_BUCKETS.svgaCover : OSS_FILE_BUCKETS.svgasource,
    );
    form[targetKey] = getAccessImgUrl(result.name);
    message.success('上传成功');
  } finally {
    loadingRef.value = false;
  }
}

function validateForm() {
  if (!form.sysOrigin) {
    message.warning('请选择系统');
    return false;
  }
  if (!form.type) {
    message.warning('请选择类型');
    return false;
  }
  if (form.type === 'BADGE' && !form.badgeDisplayType) {
    message.warning('请选择徽章展示形态');
    return false;
  }
  if (!String(form.cover || '').trim()) {
    message.warning('请上传封面');
    return false;
  }
  if (isSourceRequired.value && !String(form.sourceUrl || '').trim()) {
    message.warning('请上传资源');
    return false;
  }
  if (showExpandUpload.value && !String(form.expand || '').trim()) {
    message.warning('请上传 Android 资源');
    return false;
  }
  if (!String(form.name || '').trim()) {
    message.warning(form.type === 'NOBLE_VIP' ? '请选择贵族类型' : '请输入名称');
    return false;
  }
  if (!isUpdate.value && !String(form.code || '').trim()) {
    message.warning('请输入编码');
    return false;
  }
  if (
    isAmountRequired.value &&
    (form.amount === '' ||
      form.amount === null ||
      form.amount === undefined ||
      Number.isNaN(Number(form.amount)))
  ) {
    message.warning('请输入底价');
    return false;
  }
  return true;
}

async function handleSubmit() {
  if (!validateForm()) {
    return;
  }
  saving.value = true;
  try {
    const payload = {
      adminFree: form.adminFree,
      amount: isAmountRequired.value ? Number(form.amount) : 0,
      code: form.code,
      cover: form.cover,
      expand: form.type === 'BADGE' ? buildBadgeExpand() : form.expand,
      id: form.id,
      name: form.name,
      sourceUrl: form.sourceUrl,
      sysOrigin: form.sysOrigin,
      type: form.type,
    };
    await (isUpdate.value ? updatePropsSource(payload) : addPropsSource(payload));
    message.success('保存成功');
    emit('success');
    emit('close');
  } finally {
    saving.value = false;
  }
}
</script>

<template>
  <section v-if="open" class="quick-editor">
    <input
      ref="coverInputRef"
      accept="image/*"
      class="hidden-input"
      type="file"
      @change="handleCoverInput"
    />
    <input
      ref="notSelectInputRef"
      accept="image/*"
      class="hidden-input"
      type="file"
      @change="handleNotSelectInput"
    />
    <input
      ref="sourceInputRef"
      :accept="isImageSourceType ? 'image/*' : '.svga,.pag,.mp4'"
      class="hidden-input"
      type="file"
      @change="handleSourceInput"
    />
    <input
      ref="expandInputRef"
      accept="image/*"
      class="hidden-input"
      type="file"
      @change="handleExpandInput"
    />

    <div class="quick-editor__bar">
      <div class="quick-editor__title">{{ title }}</div>
      <div class="quick-editor__actions">
        <Button @click="emit('close')">取消</Button>
        <Button :loading="saving" type="primary" @click="handleSubmit">
          保存
        </Button>
      </div>
    </div>

    <Form class="resource-form" layout="vertical">
      <section class="compact-section">
        <div class="section-title">基础配置</div>
        <div class="form-grid">
          <FormItem label="系统">
            <SysOriginSelect
              v-model:value="form.sysOrigin"
              :options="sysOriginOptions"
            />
          </FormItem>
          <FormItem label="类型">
            <Select
              v-model:value="form.type"
              option-label-prop="label"
              :options="propsTypeOptions"
            />
          </FormItem>
          <FormItem v-if="form.type === 'BADGE'" label="展示形态">
            <Select
              v-model:value="form.badgeDisplayType"
              option-label-prop="label"
              :options="badgeDisplayTypeOptions"
            />
          </FormItem>
          <FormItem v-if="isAmountRequired" label="底价">
            <InputNumber
              v-model:value="form.amount"
              :min="0"
              placeholder="请输入底价"
              style="width: 100%"
            />
          </FormItem>
          <FormItem label="Admin Free">
            <div class="switch-line">
              <Switch
                v-model:checked="form.adminFree"
                checked-children="是"
                un-checked-children="否"
              />
            </div>
          </FormItem>
          <FormItem class="form-grid__wide" label="名称">
            <Select
              v-if="form.type === 'NOBLE_VIP'"
              v-model:value="form.name"
              option-label-prop="label"
              :options="nobleVipNameOptions"
            />
            <Input v-else v-model:value="form.name" />
          </FormItem>
          <FormItem v-if="!isUpdate" label="编码">
            <Input v-model:value="form.code" placeholder="添加后不可修改" />
          </FormItem>
        </div>
      </section>

      <section class="compact-section">
        <div class="section-title">资源文件</div>
        <div class="asset-grid">
          <div class="asset-card">
            <div class="asset-preview">
              <Image
                v-if="form.cover"
                class="asset-preview__image"
                :src="form.cover"
              />
              <div v-else class="asset-empty">未上传</div>
            </div>
            <div class="asset-detail">
              <div class="asset-card__head">
                <span>封面</span>
                <span
                  class="asset-status"
                  :class="{ 'asset-status--ready': form.cover }"
                >
                  {{ form.cover ? '已上传' : '必填' }}
                </span>
              </div>
              <div class="asset-meta">{{ getAssetName(form.cover) || '-' }}</div>
            </div>
            <div class="asset-actions">
              <Button :loading="coverUploading" @click="openCoverPicker">
                {{ form.cover ? '替换' : '上传' }}
              </Button>
              <Button
                v-if="form.cover"
                danger
                type="text"
                @click="clearUpload('cover')"
              >
                删除
              </Button>
            </div>
          </div>

          <div v-if="showSourceUpload" class="asset-card">
            <div class="asset-preview">
              <Image
                v-if="form.sourceUrl && isImageSourceType"
                class="asset-preview__image"
                :src="form.sourceUrl"
              />
              <div v-else-if="form.sourceUrl" class="asset-file">
                {{ getAssetName(form.sourceUrl) }}
              </div>
              <div v-else class="asset-empty">未上传</div>
            </div>
            <div class="asset-detail">
              <div class="asset-card__head">
                <span>{{ sourceUploadLabel }}</span>
                <span
                  class="asset-status"
                  :class="{ 'asset-status--ready': form.sourceUrl }"
                >
                  {{ form.sourceUrl ? '已上传' : isSourceRequired ? '必填' : '选填' }}
                </span>
              </div>
              <div class="asset-meta">
                {{ getAssetName(form.sourceUrl) || '-' }}
              </div>
            </div>
            <div class="asset-actions">
              <Button :loading="sourceUploading" @click="openSourcePicker">
                {{ form.sourceUrl ? '替换' : '上传' }}
              </Button>
              <Button
                v-if="form.sourceUrl"
                danger
                type="text"
                @click="clearUpload('sourceUrl')"
              >
                删除
              </Button>
            </div>
          </div>

          <div v-if="showExpandUpload" class="asset-card">
            <div class="asset-preview">
              <Image
                v-if="form.expand"
                class="asset-preview__image"
                :src="form.expand"
              />
              <div v-else class="asset-empty">未上传</div>
            </div>
            <div class="asset-detail">
              <div class="asset-card__head">
                <span>Android资源</span>
                <span
                  class="asset-status"
                  :class="{ 'asset-status--ready': form.expand }"
                >
                  {{ form.expand ? '已上传' : '必填' }}
                </span>
              </div>
              <div class="asset-meta">{{ getAssetName(form.expand) || '-' }}</div>
            </div>
            <div class="asset-actions">
              <Button :loading="expandUploading" @click="openExpandPicker">
                {{ form.expand ? '替换' : '上传' }}
              </Button>
              <Button
                v-if="form.expand"
                danger
                type="text"
                @click="clearUpload('expand')"
              >
                删除
              </Button>
            </div>
          </div>

          <div v-if="form.type === 'BADGE'" class="asset-card">
            <div class="asset-preview">
              <Image
                v-if="form.notSelectUrl"
                class="asset-preview__image"
                :src="form.notSelectUrl"
              />
              <div v-else class="asset-empty">未上传</div>
            </div>
            <div class="asset-detail">
              <div class="asset-card__head">
                <span>未选中图</span>
                <span
                  class="asset-status"
                  :class="{ 'asset-status--ready': form.notSelectUrl }"
                >
                  {{ form.notSelectUrl ? '已上传' : '选填' }}
                </span>
              </div>
              <div class="asset-meta">
                {{ getAssetName(form.notSelectUrl) || '-' }}
              </div>
            </div>
            <div class="asset-actions">
              <Button :loading="notSelectUploading" @click="openNotSelectPicker">
                {{ form.notSelectUrl ? '替换' : '上传' }}
              </Button>
              <Button
                v-if="form.notSelectUrl"
                danger
                type="text"
                @click="clearUpload('notSelectUrl')"
              >
                删除
              </Button>
            </div>
          </div>
        </div>
      </section>
    </Form>
  </section>
</template>

<style scoped>
.hidden-input {
  display: none;
}

.quick-editor {
  background: #fff;
  border: 1px solid #d8dee8;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgb(16 24 40 / 4%);
  margin-bottom: 8px;
  padding: 12px;
}

.quick-editor__bar {
  align-items: center;
  border-bottom: 1px solid #eef0f3;
  display: flex;
  gap: 16px;
  justify-content: space-between;
  margin-bottom: 12px;
  padding-bottom: 10px;
}

.quick-editor__title {
  color: #111827;
  font-size: 16px;
  font-weight: 600;
  line-height: 24px;
}

.quick-editor__actions {
  align-items: center;
  display: flex;
  flex: 0 0 auto;
  gap: 8px;
}

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

.resource-form {
  display: grid;
  gap: 12px;
}

.resource-form :deep(.ant-form-item) {
  margin-bottom: 0;
}

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

.resource-form :deep(.ant-form-item-label > label) {
  color: #475467;
  font-size: 13px;
  height: 18px;
}

.compact-section {
  border-bottom: 1px solid #eef0f3;
  padding-bottom: 12px;
}

.compact-section:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

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

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

.switch-line {
  align-items: center;
  display: flex;
  gap: 8px;
  min-height: 32px;
}

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

.asset-card {
  align-items: center;
  background: #fbfdff;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  display: grid;
  gap: 12px;
  grid-template-columns: 96px minmax(0, 1fr) auto;
  min-width: 0;
  padding: 12px;
}

.asset-card__head,
.asset-actions {
  align-items: center;
  display: flex;
}

.asset-card__head {
  color: #344054;
  gap: 8px;
  font-weight: 600;
  min-width: 0;
}

.asset-card__head span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asset-status {
  background: #f3f4f6;
  border-radius: 999px;
  color: #667085;
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 500;
  line-height: 20px;
  padding: 0 8px;
}

.asset-status--ready {
  background: #e8f3ff;
  color: #1677ff;
}

.asset-preview {
  align-items: center;
  background: #f8fafc;
  border: 1px dashed #cbd5e1;
  border-radius: 6px;
  display: flex;
  height: 76px;
  justify-content: center;
  min-height: 0;
  overflow: hidden;
  padding: 6px;
}

.asset-preview__image {
  height: 64px;
  object-fit: contain;
  width: 100%;
}

.asset-empty {
  color: #98a2b3;
  font-size: 13px;
}

.asset-file {
  color: #344054;
  font-size: 12px;
  line-height: 1.35;
  max-width: 100%;
  overflow-wrap: anywhere;
  text-align: center;
}

.asset-meta {
  color: #667085;
  font-size: 12px;
  line-height: 18px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asset-actions {
  gap: 6px;
  justify-content: flex-end;
}

@media (max-width: 1120px) {
  .form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

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

@media (max-width: 720px) {
  .asset-grid,
  .form-grid {
    grid-template-columns: 1fr;
  }

  .form-grid__wide {
    grid-column: span 1;
  }

  .asset-card {
    grid-template-columns: 80px minmax(0, 1fr);
  }

  .asset-actions {
    grid-column: 1 / -1;
    justify-content: flex-start;
  }
}
</style>
