<script lang="ts" setup>
/**
 * 消息中心 · 门店录入快捷审核
 * 拉详情展示门店资料/合同/关联医生，支持 ERP/MES + 一并审医生
 */
import { computed, onMounted, ref, watch } from 'vue';

import {
  Avatar,
  Button,
  Descriptions,
  DescriptionsItem,
  Image,
  Input,
  Radio,
  RadioGroup,
  Spin,
  Textarea,
  Tag,
  message,
} from 'ant-design-vue';

import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';
import { emitNoticeRefresh } from '#/views/notice/action/bus';
import {
  auditStoreInput,
  getStoreInputDetail,
} from '#/views/system/store-input/api';
import DoctorInputCardGrid from '#/views/system/store-input/components/DoctorInputCardGrid.vue';
import {
  getLinkedDoctors,
  isDoctorPending,
} from '#/views/system/store-input/utils/doctorInputDisplay';
import {
  inputUserDisplayName,
  normalizeInputUser,
  resolveAvatarUrl,
} from '#/views/system/store-input/utils/inputUser';

const props = defineProps<{
  notice: Record<string, any>;
}>();

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

const loading = ref(false);
const submitting = ref(false);
const detail = ref<Record<string, any> | null>(null);
const auditStatus = ref(1);
const auditRemark = ref('');
const erpId = ref('');
const mesId = ref('');
const selectedDoctorIds = ref<number[]>([]);

const bizId = computed(() => Number(props.notice?.action_payload?.biz_id || 0));
const canAudit = computed(() => Number(detail.value?.status) === 0);
const doctors = computed(() =>
  detail.value ? getLinkedDoctors(detail.value) : [],
);
const pendingDoctorIds = computed(() =>
  doctors.value
    .filter((d) => isDoctorPending(d))
    .map((d) => Number(d.id))
    .filter((id) => id > 0),
);
const carousel = computed(() => {
  const url = detail.value?.url;
  return Array.isArray(url) ? url.filter(Boolean) : [];
});
const contracts = computed(() => {
  const files = detail.value?.contract_files;
  return Array.isArray(files) ? files : [];
});

function statusMeta(status: number) {
  if (status === 0) return { color: 'orange', text: '待审核' };
  if (status === 1) return { color: 'success', text: '审核通过' };
  if (status === 2) return { color: 'error', text: '审核拒绝' };
  return { color: 'default', text: '-' };
}

async function loadDetail() {
  const id = bizId.value;
  if (id <= 0) {
    detail.value = null;
    return;
  }
  loading.value = true;
  detail.value = null;
  try {
    const res = await getStoreInputDetail(id);
    detail.value = res || null;
    normalizeInputUser(detail.value);
    erpId.value =
      res?.erp_id != null && String(res.erp_id) !== ''
        ? String(res.erp_id)
        : '';
    mesId.value =
      res?.mes_id != null && String(res.mes_id) !== ''
        ? String(res.mes_id)
        : '';
    selectedDoctorIds.value = getLinkedDoctors(detail.value)
      .filter((d) => isDoctorPending(d))
      .map((d) => Number(d.id))
      .filter((id) => id > 0);
  } catch {
    message.error('加载门店录入详情失败');
    detail.value = null;
  } finally {
    loading.value = false;
  }
}

watch(auditStatus, (v) => {
  if (v !== 1) {
    selectedDoctorIds.value = [];
  } else {
    selectedDoctorIds.value = [...pendingDoctorIds.value];
  }
});

async function submitAudit(forceStatus?: number) {
  const id = Number(detail.value?.id || bizId.value || 0);
  if (id <= 0) {
    message.error('缺少录入 ID');
    return;
  }
  if (!canAudit.value) {
    message.warning('该录入已审核');
    return;
  }
  if (typeof forceStatus === 'number') {
    auditStatus.value = forceStatus;
  }
  if (auditStatus.value === 1 && !erpId.value.trim()) {
    message.error('审核通过时请填写 ERP ID');
    return;
  }
  submitting.value = true;
  try {
    const payload: Parameters<typeof auditStoreInput>[0] = {
      id,
      status: auditStatus.value,
      audit_remark: auditRemark.value,
      erp_id: auditStatus.value === 1 ? erpId.value.trim() : undefined,
      mes_id:
        auditStatus.value === 1 && mesId.value.trim()
          ? mesId.value.trim()
          : undefined,
    };
    if (auditStatus.value === 1 && selectedDoctorIds.value.length > 0) {
      payload.doctor_input_ids = [...selectedDoctorIds.value];
    }
    await auditStoreInput(payload);
    const n = auditStatus.value === 1 ? selectedDoctorIds.value.length : 0;
    message.success(
      n > 0 ? `审核成功，已一并通过 ${n} 位医生预填` : '审核成功',
    );
    emitNoticeRefresh();
    emit('done');
  } catch {
    message.error('审核失败，请稍后重试');
  } finally {
    submitting.value = false;
  }
}

watch(() => bizId.value, loadDetail);
onMounted(loadDetail);
</script>

<template>
  <div class="store-quick">
    <div class="head">
      <div>
        <div class="kicker">门店录入待审</div>
        <div class="title">{{ detail?.name || notice.title || '门店录入' }}</div>
        <p class="desc">{{ notice.detail || '请核对门店资料后完成审核' }}</p>
      </div>
      <Tag v-if="detail" :color="statusMeta(Number(detail.status)).color">
        {{ statusMeta(Number(detail.status)).text }}
      </Tag>
    </div>

    <Spin :spinning="loading">
      <div v-if="!bizId" class="empty">消息未携带录入 ID</div>
      <div v-else-if="!loading && !detail" class="empty">未找到录入记录</div>
      <template v-else-if="detail">
        <Descriptions
          :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
          bordered
          size="small"
        >
          <DescriptionsItem label="录入 ID">#{{ detail.id }}</DescriptionsItem>
          <DescriptionsItem label="类型">
            {{ Number(detail.type) === 1 ? '药店' : '诊所' }}
          </DescriptionsItem>
          <DescriptionsItem label="诊所类型">
            {{
              Number(detail.clinic_type) === 1
                ? '西医诊所'
                : Number(detail.clinic_type) === 2
                  ? '中医诊所'
                  : '未设置'
            }}
          </DescriptionsItem>
          <DescriptionsItem label="联系人">{{ detail.contact || '-' }}</DescriptionsItem>
          <DescriptionsItem label="联系电话">
            <SensitiveText :record="detail" field="mobile" />
          </DescriptionsItem>
          <DescriptionsItem label="省市区">
            {{ detail.province?.name || '' }} {{ detail.city?.name || '' }}
          </DescriptionsItem>
          <DescriptionsItem label="地址" :span="2">
            {{ detail.position || '-' }}
          </DescriptionsItem>
          <DescriptionsItem label="录入人">
            <div class="input-user">
              <Avatar
                v-if="resolveAvatarUrl(detail.inputUser?.avatar)"
                :src="resolveAvatarUrl(detail.inputUser?.avatar)"
                :size="28"
              />
              <span>{{ inputUserDisplayName(detail.inputUser) }}</span>
            </div>
          </DescriptionsItem>
        </Descriptions>

        <div v-if="carousel.length || detail.see_rate || contracts.length" class="media">
          <div v-if="detail.see_rate" class="media-item">
            <div class="media-label">公章</div>
            <Image
              :src="resolveAvatarUrl(detail.see_rate) || detail.see_rate"
              :width="88"
              :height="88"
              :preview="true"
            />
          </div>
          <div v-for="(img, idx) in carousel" :key="idx" class="media-item">
            <div class="media-label">轮播 {{ idx + 1 }}</div>
            <Image
              :src="resolveAvatarUrl(img) || img"
              :width="88"
              :height="88"
              :preview="true"
            />
          </div>
          <div v-for="(f, idx) in contracts" :key="`c-${idx}`" class="media-item file">
            <div class="media-label">合同</div>
            <a :href="f.file_url" target="_blank" rel="noreferrer">{{
              f.file_name || '查看文件'
            }}</a>
          </div>
        </div>

        <div v-if="doctors.length" class="doctors">
          <div class="section-title">关联医生预填</div>
          <DoctorInputCardGrid
            v-model:selected-ids="selectedDoctorIds"
            :doctors="doctors"
            :selectable="canAudit && auditStatus === 1"
            only-pending-selectable
          />
        </div>

        <div v-if="canAudit" class="audit-box">
          <div class="section-title">快捷审核</div>
          <RadioGroup v-model:value="auditStatus" class="mb-3">
            <Radio :value="1">审核通过</Radio>
            <Radio :value="2">审核拒绝</Radio>
          </RadioGroup>
          <div v-if="auditStatus === 1" class="field">
            <div class="field-label">ERP ID（必填）</div>
            <Input v-model:value="erpId" placeholder="审核通过必填" />
          </div>
          <div v-if="auditStatus === 1" class="field">
            <div class="field-label">MES ID（可选）</div>
            <Input v-model:value="mesId" placeholder="煎药中心编码" />
          </div>
          <div class="field">
            <div class="field-label">审核备注</div>
            <Textarea v-model:value="auditRemark" :rows="3" placeholder="可选" />
          </div>
          <div class="actions">
            <Button
              danger
              size="large"
              :loading="submitting && auditStatus === 2"
              :disabled="submitting"
              @click="submitAudit(2)"
            >
              拒绝
            </Button>
            <Button
              type="primary"
              size="large"
              :loading="submitting && auditStatus === 1"
              :disabled="submitting"
              @click="submitAudit(1)"
            >
              通过审核
            </Button>
          </div>
        </div>
        <div v-else class="done-tip">该录入已处理</div>
      </template>
    </Spin>
  </div>
</template>

<style scoped>
.store-quick {
  padding: 2px 0 4px;
}

.head {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding: 14px 16px;
  border-radius: 14px;
  background:
    radial-gradient(
      70% 120% at 0% 0%,
      hsl(var(--primary) / 0.14),
      transparent 55%
    ),
    hsl(var(--muted) / 0.35);
}

.kicker {
  font-size: 12px;
  font-weight: 650;
  color: hsl(var(--primary));
}

.title {
  margin-top: 4px;
  font-size: 17px;
  font-weight: 700;
  color: hsl(var(--foreground));
}

.desc {
  margin: 6px 0 0;
  font-size: 13px;
  color: hsl(var(--muted-foreground));
}

.empty,
.done-tip {
  padding: 28px 0;
  text-align: center;
  color: hsl(var(--muted-foreground));
}

.input-user {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.media {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}

.media-item {
  padding: 8px;
  border-radius: 10px;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--card, var(--background)));
}

.media-item.file {
  min-width: 120px;
}

.media-label,
.field-label,
.section-title {
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 650;
  color: hsl(var(--muted-foreground));
}

.section-title {
  margin-top: 16px;
  margin-bottom: 10px;
  font-size: 14px;
  color: hsl(var(--foreground));
}

.doctors {
  margin-top: 4px;
}

.audit-box {
  margin-top: 16px;
  padding: 14px;
  border-radius: 12px;
  border: 1px solid hsl(var(--border));
  background: hsl(var(--muted) / 0.28);
}

.field {
  margin-bottom: 10px;
}

.actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 12px;
}
</style>
