<template>
  <div class="subject-info-page">
    <h1 class="page-title">主体信息</h1>

    <el-form
      ref="formRef"
      class="subject-form"
      :model="form"
      :rules="rules"
      label-width="140px"
      require-asterisk-position="right"
      label-position="right"
    >
      <!-- 主体身份 -->
      <section class="form-block">
        <h2 class="section-head">
          <span class="section-bar" aria-hidden="true" />
          主体身份 <span class="section-intro">请上传「营业执照」，需年检章齐全，当年注册除外</span>
        </h2>

        <!-- <el-form-item label="是否金融机构" prop="isFinancialInstitution">
          <div class="field-stack">
            <el-select v-model="form.isFinancialInstitution" placeholder="请选择" style="width: 260px">
              <el-option label="否" :value="0" />
              <el-option label="是" :value="1" />
            </el-select>
            <p class="field-tip">
              金融机构是指从事金融类业务的机构，如信贷、融资、理财、担保、信托、货币兑换等。
            </p>
          </div>
        </el-form-item> -->

        <el-form-item prop="businessLicenseUrl">
          <template #label>
            <span class="label-with-icon">
              营业执照照片
              <el-tooltip placement="top" content="请上传清晰、完整的营业执照照片，需与后续填写信息一致。">
                <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
              </el-tooltip>
            </span>
          </template>
          <div class="license-upload-wrap">
            <el-upload
              v-model:file-list="form.businessLicenseFileList"
              list-type="picture-card"
              :limit="1"
              accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
              :before-upload="beforeLicenseUpload"
              :http-request="handleLicenseUpload"
              :on-remove="onLicenseRemove"
            >
              <el-icon><Plus /></el-icon>
            </el-upload>
            <!-- <div class="license-example" aria-hidden="true" style="border:1px solid red;">
              <div class="license-example-thumb">
                <span class="license-example-placeholder">营业执照</span>
              </div>
            </div> -->
          </div>
          <div class="upload-rules">
            <p>
              1.
              请上传彩色照片或彩色扫描件或加盖公章鲜章的复印件，要求正面拍摄，露出证件四角且清晰、完整，所有字符清晰可识别，不得反光或遮挡。不得翻拍、截图、镜像、PS。
            </p>
            <p>2. 图片只支持 JPG、BMP、PNG 格式，文件大小不能超过 5M。</p>
          </div>
        </el-form-item>
        <div v-if="hasBusinessLicenseOcr" class="license-ocr-result">
          <div v-if="businessLicenseOcr.creditCode" class="license-ocr-row">
            <span class="license-ocr-label">统一社会信用代码</span>
            <span class="license-ocr-value">{{ businessLicenseOcr.creditCode }}</span>
          </div>
          <div v-if="businessLicenseOcr.companyName" class="license-ocr-row">
            <span class="license-ocr-label">企业名称</span>
            <span class="license-ocr-value">{{ businessLicenseOcr.companyName }}</span>
          </div>
          <div v-if="businessLicenseOcr.legalPerson" class="license-ocr-row">
            <span class="license-ocr-label">法定代表人</span>
            <span class="license-ocr-value">{{ businessLicenseOcr.legalPerson }}</span>
          </div>
        </div>
      </section>

      <!-- 法定代表人证件 -->
      <section class="form-block">
        <h2 class="section-head">
          <span class="section-bar" aria-hidden="true" />
          法定代表人证件
          <span class="section-intro">请上传法定代表人的证件信息</span>
        </h2>

        <el-form-item label="证件类型" prop="legalIdType">
          <div class="field-stack">
            <el-select v-model="form.legalIdType" placeholder="请选择" clearable style="width: 260px">
              <el-option label="居民身份证" value="id_card" />
              <el-option label="护照" value="passport" />
              <el-option label="港澳居民来往内地通行证" value="hk_macau_pass" />
              <el-option label="台湾居民来往大陆通行证" value="taiwan_pass" />
            </el-select>
          </div>
        </el-form-item>

        <!-- 居民身份证：人像面 / 国徽面 -->
        <template v-if="form.legalIdType === 'id_card'">
          <el-form-item prop="idPortraitUrl">
            <template #label>
              <span class="label-with-icon">
                身份证人像面照片
                <el-tooltip placement="top" content="请上传身份证人像面（带头像一面）清晰彩色照片。">
                  <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
                </el-tooltip>
              </span>
            </template>
            <div class="license-upload-wrap">
              <el-upload
                v-model:file-list="form.idPortraitFileList"
                list-type="picture-card"
                :limit="1"
                accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
                :before-upload="beforeLicenseUpload"
                :http-request="opt => handleIdCardUpload(opt, 'portrait')"
                :on-remove="(_f, fl) => onIdCardRemove(fl, 'portrait')"
              >
                <el-icon><Plus /></el-icon>
              </el-upload>
              <!-- <div class="license-example" aria-hidden="true">
                <div class="license-example-thumb id-example-thumb">
                  <span class="license-example-badge">示例</span>
                  <span class="license-example-placeholder">人像面</span>
                </div>
              </div> -->
            </div>
            <div class="upload-rules">
              <p>
                1. 请上传彩色照片 or 彩色扫描件 or
                加盖公章鲜章的复印件，要求正面拍摄，露出证件四角且清晰、完整，所有字符清晰可识别，不得反光或遮挡。不得翻拍、截图、镜像、PS。
              </p>
              <p>2. 图片只支持 JPG、BMP、PNG 格式，文件大小不能超过 5M。</p>
            </div>
          </el-form-item>

          <el-form-item prop="idEmblemUrl">
            <template #label>
              <span class="label-with-icon">
                身份证国徽面照片
                <el-tooltip placement="top" content="请上传身份证国徽面清晰彩色照片。">
                  <el-icon class="info-icon" :size="16"><InfoFilled /></el-icon>
                </el-tooltip>
              </span>
            </template>
            <div class="license-upload-wrap">
              <el-upload
                v-model:file-list="form.idEmblemFileList"
                list-type="picture-card"
                :limit="1"
                accept=".jpg,.jpeg,.png,.bmp,image/jpeg,image/png,image/bmp"
                :before-upload="beforeLicenseUpload"
                :http-request="opt => handleIdCardUpload(opt, 'emblem')"
                :on-remove="(_f, fl) => onIdCardRemove(fl, 'emblem')"
              >
                <el-icon><Plus /></el-icon>
              </el-upload>
              <!-- <div class="license-example" aria-hidden="true">
                <div class="license-example-thumb id-example-thumb">
                  <span class="license-example-badge">示例</span>
                  <span class="license-example-placeholder">国徽面</span>
                </div>
              </div> -->
            </div>
            <div class="upload-rules">
              <p>
                1. 请上传彩色照片 or 彩色扫描件 or
                加盖公章鲜章的复印件，要求正面拍摄，露出证件四角且清晰、完整，所有字符清晰可识别，不得反光或遮挡。不得翻拍、截图、镜像、PS。
              </p>
              <p>2. 图片只支持 JPG、BMP、PNG 格式，文件大小不能超过 5M。</p>
            </div>

            <div v-if="showIdPortraitOcrBlock" class="ocr-result-container">
              <div v-if="isIdPortraitOcrProcessing" class="ocr-result-item">
                <span class="label">识别中：</span>
                <span class="value">正在识别身份证信息，请稍候...</span>
              </div>
              <template v-else>
                <div v-if="idPortraitOcr.name" class="ocr-result-item">
                  <span class="label">姓名：</span>
                  <span class="value">{{ idPortraitOcr.name }}</span>
                </div>
                <div v-if="idPortraitOcr.idNumber" class="ocr-result-item">
                  <span class="label">身份证号：</span>
                  <span class="value">{{ idPortraitOcr.idNumber }}</span>
                </div>
                <div v-if="idCardValidityDisplay" class="ocr-result-item">
                  <span class="label">身份证有效期：</span>
                  <span class="value">{{ idCardValidityDisplay }}</span>
                </div>
                <div v-if="!idPortraitOcr.name && !idPortraitOcr.idNumber && !idCardValidityDisplay" class="ocr-result-tip">
                  请等待身份证识别完成
                </div>
              </template>
            </div>
          </el-form-item>

          <p class="ubo-footer-tip">
            平台将通过外部渠道核验该法人是否为受益人，若通过，将使用法人信息作为该主体的受益人(UBO)信息
          </p>
        </template>
      </section>
    </el-form>

    <div class="footer-actions">
      <el-button @click="onBack"> 返回 </el-button>
      <el-button type="primary" class="btn-next" :loading="nextLoading" @click="onNext"> 确定 </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import type { UploadRequestOptions, UploadUserFile } from "element-plus";
import { Plus, InfoFilled } from "@element-plus/icons-vue";
import { getOcrRequestByBase64, getUpload } from "@/api/modules/businessInfo";
import { localGet, localSet } from "@/utils/index";

const BUSINESS_DATA_CACHE_KEY = "businessData";

const formRef = ref<FormInstance>();
const nextLoading = ref(false);
const route = useRoute();
const router = useRouter();

const businessLicenseOcr = reactive({
  creditCode: "",
  companyName: "",
  legalPerson: ""
});

const hasBusinessLicenseOcr = computed(
  () => !!(businessLicenseOcr.creditCode || businessLicenseOcr.companyName || businessLicenseOcr.legalPerson)
);

function clearBusinessLicenseOcr() {
  businessLicenseOcr.creditCode = "";
  businessLicenseOcr.companyName = "";
  businessLicenseOcr.legalPerson = "";
}

/** 从 ocrRequestByBase64 成功响应中取出 creditCode / companyName / legalPerson */
function pickBusinessLicenseOcrFields(res: any) {
  const raw = res?.data ?? res;
  let node: any = raw;
  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
    node = node.data;
  }
  const item = Array.isArray(node) ? node[0] : node;
  if (!item || typeof item !== "object") {
    return { creditCode: "", companyName: "", legalPerson: "" };
  }
  return {
    creditCode: String(item.creditCode ?? item.credit_code ?? "").trim(),
    companyName: String(item.companyName ?? item.company_name ?? "").trim(),
    legalPerson: String(item.legalPerson ?? item.legal_person ?? "").trim()
  };
}

/** 身份证有效期文案 → YYYY-MM-DD */
function splitIdCardValidPeriod(raw: string): { begin: string; end: string } {
  const s = (raw || "").trim();
  if (!s) return { begin: "", end: "" };
  if (/长期|长期有效/.test(s)) return { begin: "", end: "长期" };
  const norm = s
    .replace(/年|月|日/g, ".")
    .replace(/\.+/g, ".")
    .trim();
  const parts = norm.split(/[-至~～]/);
  const normOne = (p: string) => {
    const m = p.trim().match(/(\d{4})\D*(\d{1,2})\D*(\d{1,2})/);
    if (m) return `${m[1]}-${m[2].padStart(2, "0")}-${m[3].padStart(2, "0")}`;
    return p.trim();
  };
  if (parts.length >= 2) {
    return { begin: normOne(parts[0]), end: normOne(parts[1]) };
  }
  return { begin: "", end: "" };
}

/** 人像面 getOcrRequestByBase64(ID_CARD) 成功响应 */
function pickIdCardPortraitOcrFields(res: any): {
  name: string;
  idNumber: string;
  idCardAddress: string;
  cardPeriodBegin: string;
  cardPeriodEnd: string;
} {
  const raw = res?.data ?? res;
  let node: any = raw;
  if (node && typeof node === "object" && "data" in node && node.data !== undefined) {
    node = node.data;
  }
  const arr = Array.isArray(node) ? node : [node];
  const item = arr[0];
  const item2 = arr[1];
  if (!item || typeof item !== "object") {
    return { name: "", idNumber: "", idCardAddress: "", cardPeriodBegin: "", cardPeriodEnd: "" };
  }
  let name = String(item.name ?? item.userName ?? "").trim();
  let idNumber = String(item.idNumber ?? item.id_number ?? item.idCard ?? item.id_card ?? "").trim();
  const faceData = item.face?.data || item2?.face?.data;
  const backData = item.back?.data || item2?.back?.data;
  if (faceData && typeof faceData === "object") {
    if (!name) name = String(faceData.name ?? "").trim();
    if (!idNumber) idNumber = String(faceData.idNumber ?? faceData.id_number ?? "").trim();
  }
  let idCardAddress = "";
  if (backData && typeof backData === "object") {
    idCardAddress = String(backData.address ?? backData.registeredAddress ?? backData.issueAuthority ?? "").trim();
  }
  if (faceData && typeof faceData === "object" && !idCardAddress) {
    idCardAddress = String(faceData.address ?? "").trim();
  }
  const faceKv = item.face?.prism_keyValueInfo || item2?.face?.prism_keyValueInfo;
  if (Array.isArray(faceKv)) {
    for (const row of faceKv) {
      if (row?.key === "name" && row?.value && !name) name = String(row.value).trim();
      if (row?.key === "idNumber" && row?.value && !idNumber) idNumber = String(row.value).trim();
      if (row?.key === "address" && row?.value && !idCardAddress) {
        idCardAddress = String(row.value).trim();
      }
    }
  }
  const backKv = item.back?.prism_keyValueInfo || item2?.back?.prism_keyValueInfo;
  let validPeriodFromKv = "";
  if (Array.isArray(backKv)) {
    for (const row of backKv) {
      if (row?.key === "address" && row?.value && !idCardAddress) {
        idCardAddress = String(row.value).trim();
      }
      if (row?.value) {
        const keyRaw = String(row.key || "");
        if (/有效期限|有效期|失效日期|签发日期|validPeriod|validDate|valid_period/i.test(keyRaw)) {
          const v = String(row.value).trim();
          if (v && !validPeriodFromKv) validPeriodFromKv = v;
        }
      }
    }
  }
  let vp = String(
    (backData && (backData.validPeriod ?? backData.validDate)) ||
      (faceData && (faceData.validPeriod ?? faceData.validDate)) ||
      (item && (item.validPeriod ?? item.validDate)) ||
      (item2 && (item2.validPeriod ?? item2.validDate)) ||
      ""
  ).trim();
  if (!vp && validPeriodFromKv) vp = validPeriodFromKv;
  const { begin: cardPeriodBegin, end: cardPeriodEnd } = splitIdCardValidPeriod(vp);
  return { name, idNumber, idCardAddress, cardPeriodBegin, cardPeriodEnd };
}

const form = reactive<{
  isFinancialInstitution: number;
  businessLicenseFileList: UploadUserFile[];
  businessLicenseUrl: string;
  legalIdType: string;
  idPortraitFileList: UploadUserFile[];
  idEmblemFileList: UploadUserFile[];
  idPortraitUrl: string;
  idEmblemUrl: string;
}>({
  isFinancialInstitution: 0,
  businessLicenseFileList: [],
  businessLicenseUrl: "",
  legalIdType: "id_card",
  idPortraitFileList: [],
  idEmblemFileList: [],
  idPortraitUrl: "",
  idEmblemUrl: ""
});

const idPortraitOcr = reactive({
  name: "",
  idNumber: "",
  idCardAddress: "",
  cardPeriodBegin: "",
  cardPeriodEnd: ""
});

const isIdPortraitOcrProcessing = ref(false);

const hasPortraitUploadSuccess = computed(() => {
  const f = form.idPortraitFileList[0];
  return f?.status === "success";
});

const hasEmblemUploadSuccess = computed(() => {
  const f = form.idEmblemFileList[0];
  return f?.status === "success";
});

/** 身份证有效期展示（国徽面 OCR 主要提供） */
const idCardValidityDisplay = computed(() => {
  const b = (idPortraitOcr.cardPeriodBegin || "").trim();
  const e = (idPortraitOcr.cardPeriodEnd || "").trim();
  if (b && e) return e === "长期" ? `${b} 至 长期` : `${b} 至 ${e}`;
  if (e === "长期" && !b) return "长期";
  if (b && !e) return b;
  if (!b && e) return e;
  return "";
});

const hasIdPortraitOcrDisplay = computed(() => !!(idPortraitOcr.name || idPortraitOcr.idNumber || idCardValidityDisplay.value));

const showIdPortraitOcrBlock = computed(
  () =>
    form.legalIdType === "id_card" &&
    (hasPortraitUploadSuccess.value ||
      hasEmblemUploadSuccess.value ||
      isIdPortraitOcrProcessing.value ||
      hasIdPortraitOcrDisplay.value)
);

function clearIdPortraitOcr() {
  idPortraitOcr.name = "";
  idPortraitOcr.idNumber = "";
  idPortraitOcr.idCardAddress = "";
  idPortraitOcr.cardPeriodBegin = "";
  idPortraitOcr.cardPeriodEnd = "";
}

function buildSubjectInfoForBusinessData(): {
  contact_type: "LEGAL";
  subject_type: "SUBJECT_TYPE_ENTERPRISE" | "SUBJECT_TYPE_INDIVIDUAL";
  business_license_info: {
    license_copy: string;
    license_number: string;
    merchant_name: string;
    legal_person: string;
  };
  identity_info: {
    id_doc_type: string;
    id_holder_type: "LEGAL";
    id_card_info: {
      id_card_copy: string;
      id_card_national: string;
      id_card_name: string;
      id_card_number: string;
      id_card_address: string;
      card_period_begin: string;
      card_period_end: string;
    };
  };
} {
  const cached = localGet(BUSINESS_DATA_CACHE_KEY) as { entityType?: string } | null | undefined;
  const entityType = String(
    (cached && typeof cached === "object" && cached.entityType) ||
      (typeof route.query.entityType === "string" ? route.query.entityType : "") ||
      ""
  ).trim();
  /** 企业 → SUBJECT_TYPE_ENTERPRISE；个体工商户（entityType=individual）及其他默认 → SUBJECT_TYPE_INDIVIDUAL */
  const subject_type = entityType === "enterprise" ? ("SUBJECT_TYPE_ENTERPRISE" as const) : ("SUBJECT_TYPE_INDIVIDUAL" as const);

  return {
    contact_type: "LEGAL" as const,
    subject_type,
    business_license_info: {
      license_copy: (form.businessLicenseUrl || "").trim(),
      license_number: (businessLicenseOcr.creditCode || "").trim(),
      merchant_name: (businessLicenseOcr.companyName || "").trim(),
      legal_person: (businessLicenseOcr.legalPerson || "").trim()
    },
    identity_info: {
      id_doc_type: "IDENTIFICATION_TYPE_IDCARD",
      id_holder_type: "LEGAL" as const,
      id_card_info: {
        id_card_copy: (form.idPortraitUrl || "").trim(),
        id_card_national: (form.idEmblemUrl || "").trim(),
        id_card_name: (idPortraitOcr.name || "").trim(),
        id_card_number: (idPortraitOcr.idNumber || "").trim(),
        id_card_address: (idPortraitOcr.idCardAddress || "").trim(),
        card_period_begin: (idPortraitOcr.cardPeriodBegin || "").trim(),
        card_period_end: (idPortraitOcr.cardPeriodEnd || "").trim()
      }
    }
  };
}

function mergeSubjectInfoIntoBusinessDataCache() {
  const prev = localGet(BUSINESS_DATA_CACHE_KEY);
  const base = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...(prev as Record<string, unknown>) } : {};
  base.subject_info = buildSubjectInfoForBusinessData();
  localSet(BUSINESS_DATA_CACHE_KEY, base);
}

function mapApiIdDocTypeToLegalId(apiType: unknown): string {
  const s = String(apiType || "").trim();
  switch (s) {
    case "IDENTIFICATION_TYPE_IDCARD":
      return "id_card";
    case "IDENTIFICATION_TYPE_OVERSEA_PASSPORT":
      return "passport";
    case "IDENTIFICATION_TYPE_HONGKONG_PASSPORT":
    case "IDENTIFICATION_TYPE_MACAO_PASSPORT":
      return "hk_macau_pass";
    case "IDENTIFICATION_TYPE_TAIWAN_PASSPORT":
      return "taiwan_pass";
    default:
      if (/IDCARD|ID_CARD/i.test(s)) return "id_card";
      return "id_card";
  }
}

/** 从 localStorage businessData.subject_info 回显本页表单与 OCR 展示 */
function hydrateSubjectFormFromBusinessDataCache() {
  const raw = localGet(BUSINESS_DATA_CACHE_KEY) as Record<string, unknown> | null | undefined;
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
  const si = raw.subject_info as Record<string, unknown> | undefined;
  if (!si || typeof si !== "object" || Array.isArray(si)) return;

  const bli = si.business_license_info as Record<string, unknown> | undefined;
  if (bli && typeof bli === "object" && !Array.isArray(bli)) {
    const lic = String(bli.license_copy ?? "").trim();
    if (lic) {
      form.businessLicenseUrl = lic;
      form.businessLicenseFileList = [{ name: "license.jpg", url: lic, status: "success" } as UploadUserFile];
    } else {
      form.businessLicenseUrl = "";
      form.businessLicenseFileList = [];
    }
    businessLicenseOcr.creditCode = String(bli.license_number ?? "").trim();
    businessLicenseOcr.companyName = String(bli.merchant_name ?? "").trim();
    businessLicenseOcr.legalPerson = String(bli.legal_person ?? "").trim();
  }

  const ii = si.identity_info as Record<string, unknown> | undefined;
  if (ii && typeof ii === "object" && !Array.isArray(ii)) {
    if (String(ii.id_doc_type ?? "").trim()) {
      form.legalIdType = mapApiIdDocTypeToLegalId(ii.id_doc_type);
    }
    const ici = ii.id_card_info as Record<string, unknown> | undefined;
    if (ici && typeof ici === "object" && !Array.isArray(ici)) {
      const copy = String(ici.id_card_copy ?? "").trim();
      const nat = String(ici.id_card_national ?? "").trim();
      if (copy) {
        form.idPortraitUrl = copy;
        form.idPortraitFileList = [{ name: "id-portrait.jpg", url: copy, status: "success" } as UploadUserFile];
      } else {
        form.idPortraitUrl = "";
        form.idPortraitFileList = [];
      }
      if (nat) {
        form.idEmblemUrl = nat;
        form.idEmblemFileList = [{ name: "id-emblem.jpg", url: nat, status: "success" } as UploadUserFile];
      } else {
        form.idEmblemUrl = "";
        form.idEmblemFileList = [];
      }
      idPortraitOcr.name = String(ici.id_card_name ?? "").trim();
      idPortraitOcr.idNumber = String(ici.id_card_number ?? "").trim();
      idPortraitOcr.idCardAddress = String(ici.id_card_address ?? "").trim();
      idPortraitOcr.cardPeriodBegin = String(ici.card_period_begin ?? "").trim();
      idPortraitOcr.cardPeriodEnd = String(ici.card_period_end ?? "").trim();
    }
  }

  nextTick(() => {
    formRef.value?.clearValidate();
  });
}

const rules: FormRules = {
  businessLicenseUrl: [
    {
      required: true,
      validator: (_r, _v, cb) => {
        if (!form.businessLicenseUrl?.trim()) {
          cb(new Error("请上传营业执照照片"));
        } else {
          cb();
        }
      },
      trigger: "change"
    }
  ],
  legalIdType: [{ required: true, message: "请选择证件类型", trigger: "change" }],
  idPortraitUrl: [
    {
      validator: (_r, _v, cb) => {
        if (form.legalIdType === "id_card" && !form.idPortraitUrl?.trim()) {
          cb(new Error("请上传身份证人像面照片"));
        } else {
          cb();
        }
      },
      trigger: "change"
    }
  ],
  idEmblemUrl: [
    {
      validator: (_r, _v, cb) => {
        if (form.legalIdType === "id_card" && !form.idEmblemUrl?.trim()) {
          cb(new Error("请上传身份证国徽面照片"));
        } else {
          cb();
        }
      },
      trigger: "change"
    }
  ]
};

watch(
  () => form.legalIdType,
  v => {
    if (v !== "id_card") {
      form.idPortraitUrl = "";
      form.idEmblemUrl = "";
      form.idPortraitFileList = [];
      form.idEmblemFileList = [];
      clearIdPortraitOcr();
    }
  }
);

const MAX_LICENSE_MB = 5;

function beforeLicenseUpload(file: File) {
  const name = file.name?.toLowerCase() || "";
  const okExt = /\.(jpe?g|png|bmp)$/i.test(name);
  const okMime = ["image/jpeg", "image/png", "image/bmp"].includes(file.type);
  if (!okExt && !okMime) {
    ElMessage.error("图片只支持 JPG、BMP、PNG 格式");
    return false;
  }
  const sizeMb = file.size / 1024 / 1024;
  if (sizeMb > MAX_LICENSE_MB) {
    ElMessage.error(`文件大小不能超过 ${MAX_LICENSE_MB}M`);
    return false;
  }
  return true;
}

/** 与 getUpload（微信 media/upload）返回结构对齐 */
function parseMediaUploadResult(res: any): { fileUrl: string; mediaId: string; errMsg: string } {
  const envelope = res?.data ?? res;
  const body = envelope?.data !== undefined ? envelope.data : envelope;
  const fileUrl =
    body?.url ??
    body?.fileUrl ??
    envelope?.url ??
    envelope?.data?.url ??
    envelope?.data?.fileUrl ??
    body?.mediaUrl ??
    body?.data?.mediaUrl ??
    "";
  const mediaId =
    body?.media_id ?? body?.mediaId ?? envelope?.media_id ?? envelope?.data?.media_id ?? envelope?.data?.mediaId ?? "";
  const errMsg = envelope?.msg ?? body?.msg ?? res?.msg ?? "";
  return { fileUrl, mediaId, errMsg };
}

function mergeIdCardOcrFromFields(fields: ReturnType<typeof pickIdCardPortraitOcrFields>, mode: "portrait" | "emblem") {
  if (mode === "portrait") {
    if (fields.name) idPortraitOcr.name = fields.name;
    if (fields.idNumber) idPortraitOcr.idNumber = fields.idNumber;
    if (fields.idCardAddress) idPortraitOcr.idCardAddress = fields.idCardAddress;
    if (fields.cardPeriodBegin) idPortraitOcr.cardPeriodBegin = fields.cardPeriodBegin;
    if (fields.cardPeriodEnd) idPortraitOcr.cardPeriodEnd = fields.cardPeriodEnd;
  } else {
    if (fields.cardPeriodBegin) idPortraitOcr.cardPeriodBegin = fields.cardPeriodBegin;
    if (fields.cardPeriodEnd) idPortraitOcr.cardPeriodEnd = fields.cardPeriodEnd;
    if (fields.idCardAddress) idPortraitOcr.idCardAddress = fields.idCardAddress;
  }
}

async function requestIdCardPortraitOcr(file: File) {
  const formData = new FormData();
  formData.append("imageFile", file, file.name || "id-portrait.jpg");
  formData.append("ocrType", "ID_CARD");
  isIdPortraitOcrProcessing.value = true;
  try {
    const res: any = await getOcrRequestByBase64(formData);
    if (res?.code === 200 || res?.code === "200") {
      const fields = pickIdCardPortraitOcrFields(res);
      mergeIdCardOcrFromFields(fields, "portrait");
      ElMessage.success("身份证人像面识别成功");
    } else {
      clearIdPortraitOcr();
      ElMessage.warning(res?.msg || "身份证人像面识别未通过，请核对照片清晰度");
    }
  } finally {
    isIdPortraitOcrProcessing.value = false;
  }
}

/** 国徽面单独 OCR，合并有效期限（及背面地址等），不清空人像面已识别字段 */
async function requestIdCardEmblemOcr(file: File) {
  const formData = new FormData();
  formData.append("imageFile", file, file.name || "id-emblem.jpg");
  formData.append("ocrType", "ID_CARD");
  isIdPortraitOcrProcessing.value = true;
  try {
    const res: any = await getOcrRequestByBase64(formData);
    if (res?.code === 200 || res?.code === "200") {
      const fields = pickIdCardPortraitOcrFields(res);
      mergeIdCardOcrFromFields(fields, "emblem");
      if (fields.cardPeriodBegin || fields.cardPeriodEnd) {
        ElMessage.success("身份证国徽面识别成功");
      } else {
        ElMessage.warning("未识别到有效期限，请确认国徽面照片清晰完整");
      }
    } else {
      ElMessage.warning(res?.msg || "身份证国徽面识别未通过，请核对照片清晰度");
    }
  } finally {
    isIdPortraitOcrProcessing.value = false;
  }
}

async function requestBusinessLicenseOcr(file: File) {
  const formData = new FormData();
  formData.append("imageFile", file, file.name || "license.jpg");
  formData.append("ocrType", "BUSINESS_LICENSE");
  const res: any = await getOcrRequestByBase64(formData);
  if (res?.code === 200 || res?.code === "200") {
    const fields = pickBusinessLicenseOcrFields(res);
    businessLicenseOcr.creditCode = fields.creditCode;
    businessLicenseOcr.companyName = fields.companyName;
    businessLicenseOcr.legalPerson = fields.legalPerson;
    ElMessage.success("营业执照识别成功");
  } else {
    clearBusinessLicenseOcr();
    ElMessage.warning(res?.msg || "营业执照识别未通过，请核对照片清晰度");
  }
}

async function handleLicenseUpload(options: UploadRequestOptions) {
  const uploadFileItem = options.file as UploadUserFile;
  const raw = uploadFileItem.raw || uploadFileItem;
  const file = raw instanceof File ? raw : null;
  if (!file) return;

  uploadFileItem.status = "uploading";
  try {
    const formData = new FormData();
    formData.append("file", file);
    const res: any = await getUpload(formData);
    const { fileUrl, mediaId, errMsg } = parseMediaUploadResult(res);

    if (fileUrl || mediaId) {
      uploadFileItem.status = "success";
      if (fileUrl) {
        uploadFileItem.url = fileUrl;
      }
      uploadFileItem.response = { media_id: mediaId, url: fileUrl };
      form.businessLicenseUrl = fileUrl || mediaId;
      try {
        await requestBusinessLicenseOcr(file);
      } catch {
        clearBusinessLicenseOcr();
        ElMessage.warning("营业执照识别服务暂时不可用，请稍后重试");
      }
    } else {
      uploadFileItem.status = "fail";
      ElMessage.error(errMsg || "上传失败，未返回可用结果");
    }
  } catch {
    uploadFileItem.status = "fail";
  }
  formRef.value?.validateField("businessLicenseUrl").catch(() => {});
}

function onLicenseRemove(_file: UploadUserFile, fileList: UploadUserFile[]) {
  if (!fileList.length) {
    form.businessLicenseUrl = "";
    clearBusinessLicenseOcr();
  } else {
    const first = fileList[0] as UploadUserFile & { url?: string; response?: { url?: string } };
    form.businessLicenseUrl = first?.url || first?.response?.url || "";
  }
  formRef.value?.validateField("businessLicenseUrl").catch(() => {});
}

type IdCardSide = "portrait" | "emblem";

async function handleIdCardUpload(options: UploadRequestOptions, side: IdCardSide) {
  const uploadFileItem = options.file as UploadUserFile;
  const raw = uploadFileItem.raw || uploadFileItem;
  const file = raw instanceof File ? raw : null;
  if (!file) return;

  uploadFileItem.status = "uploading";
  try {
    const formData = new FormData();
    formData.append("file", file);
    const res: any = await getUpload(formData);
    const { fileUrl, mediaId, errMsg } = parseMediaUploadResult(res);

    if (fileUrl || mediaId) {
      uploadFileItem.status = "success";
      if (fileUrl) {
        uploadFileItem.url = fileUrl;
      }
      uploadFileItem.response = { media_id: mediaId, url: fileUrl };
      const stored = fileUrl || mediaId;
      if (side === "portrait") {
        form.idPortraitUrl = stored;
        try {
          await requestIdCardPortraitOcr(file);
        } catch {
          clearIdPortraitOcr();
          ElMessage.warning("身份证识别服务暂时不可用，请稍后重试");
        }
      } else {
        form.idEmblemUrl = stored;
        try {
          await requestIdCardEmblemOcr(file);
        } catch {
          ElMessage.warning("身份证国徽面识别服务暂时不可用，请稍后重试");
        }
      }
    } else {
      uploadFileItem.status = "fail";
      ElMessage.error(errMsg || "上传失败，未返回可用结果");
    }
  } catch {
    uploadFileItem.status = "fail";
  }
  const field = side === "portrait" ? "idPortraitUrl" : "idEmblemUrl";
  formRef.value?.validateField(field).catch(() => {});
}

function onIdCardRemove(fileList: UploadUserFile[], side: IdCardSide) {
  if (!fileList.length) {
    if (side === "portrait") {
      form.idPortraitUrl = "";
      clearIdPortraitOcr();
    } else {
      form.idEmblemUrl = "";
      idPortraitOcr.cardPeriodBegin = "";
      idPortraitOcr.cardPeriodEnd = "";
    }
  } else {
    const first = fileList[0] as UploadUserFile & {
      url?: string;
      response?: { url?: string; media_id?: string; mediaId?: string };
    };
    const r = first?.response;
    const stored = first?.url || r?.url || r?.media_id || r?.mediaId || "";
    if (side === "portrait") form.idPortraitUrl = stored;
    else form.idEmblemUrl = stored;
  }
  const field = side === "portrait" ? "idPortraitUrl" : "idEmblemUrl";
  formRef.value?.validateField(field).catch(() => {});
}

/** 从草稿/详情接口 URL 还原身份证上传展示（可在外部拉取数据后调用） */
function restoreIdCardFromUrls(portraitUrl?: string | null, emblemUrl?: string | null) {
  if (portraitUrl) {
    form.idPortraitUrl = portraitUrl;
    form.idPortraitFileList = [{ name: "id-portrait.jpg", url: portraitUrl, status: "success" } as UploadUserFile];
  }
  if (emblemUrl) {
    form.idEmblemUrl = emblemUrl;
    form.idEmblemFileList = [{ name: "id-emblem.jpg", url: emblemUrl, status: "success" } as UploadUserFile];
  }
}

onMounted(() => {
  hydrateSubjectFormFromBusinessDataCache();
  const q = route.query as Record<string, string | string[] | undefined>;
  const pu = typeof q.idPortraitUrl === "string" ? q.idPortraitUrl : undefined;
  const eu = typeof q.idEmblemUrl === "string" ? q.idEmblemUrl : undefined;
  if (pu && !form.idPortraitUrl?.trim()) {
    form.legalIdType = "id_card";
    restoreIdCardFromUrls(pu, undefined);
  }
  if (eu && !form.idEmblemUrl?.trim()) {
    form.legalIdType = "id_card";
    restoreIdCardFromUrls(undefined, eu);
  }
});

defineExpose({ restoreIdCardFromUrls, hydrateSubjectFormFromBusinessDataCache });

function onModifyUbo() {
  ElMessage.info("受益人信息修改入口可在此对接");
}

function onBack() {
  router.push({
    path: "/businessInfo/dataEntry",
    query: { ...route.query }
  });
}

function onSaveDraft() {
  ElMessage.success("草稿已保存（可对接接口）");
}

async function onNext() {
  if (!formRef.value) return;
  nextLoading.value = true;
  try {
    await formRef.value.validate();
    mergeSubjectInfoIntoBusinessDataCache();
    await router.push({
      path: "/businessInfo/manageInfo",
      query: { ...route.query }
    });
  } catch {
    ElMessage.warning("请完善必填信息");
  } finally {
    nextLoading.value = false;
  }
}
</script>

<style scoped lang="scss">
$wechat-green: #07c160;
.subject-info-page {
  box-sizing: border-box;
  min-height: 100%;
  padding: 24px 32px 40px;
  margin: 0 auto;
  background: #ffffff;
}
.page-title {
  margin: 0 0 24px;
  font-size: 20px;
  font-weight: 600;
  color: #303133;
}
.subject-form {
  :deep(.el-form-item__label) {
    font-weight: 500;
    color: #606266;
  }
}
.form-block {
  padding-bottom: 8px;
  margin-bottom: 28px;
  border-bottom: 1px solid #ebeef5;
  &:last-of-type {
    border-bottom: none;
  }
}
.section-head {
  display: flex;
  align-items: center;
  margin: 0 0 16px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}
.section-bar {
  display: inline-block;
  flex-shrink: 0;
  width: 4px;
  height: 16px;
  margin-right: 8px;
  background: $wechat-green;
  border-radius: 2px;
}
.section-intro {
  padding-left: 20px;
  font-size: 13px;
  line-height: 1.65;
  color: #909399;
}
.field-stack {
  width: 100%;
}
.field-tip {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.65;
  color: #909399;
}
.label-with-icon {
  display: inline-flex;
  gap: 4px;
  align-items: center;
}
.info-icon {
  color: #909399;
  cursor: help;
}
.license-upload-wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: flex-start;
}
.license-example {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.license-example-label {
  font-size: 12px;
  color: #909399;
}
.license-example-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 148px;
  height: 148px;
  background: #f5f7fa;
  border: 1px dashed #dcdfe6;
  border-radius: 6px;
}
.license-example-placeholder {
  font-size: 12px;
  color: #c0c4cc;
}
.id-example-thumb {
  position: relative;
}
.license-example-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  padding: 2px 6px;
  font-size: 11px;
  color: #ffffff;
  background: rgb(0 0 0 / 45%);
  border-radius: 4px;
}
.ubo-footer-tip {
  padding: 12px 0 0;
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.65;
  color: #909399;
  border-top: 1px dashed #ebeef5;
}
:deep(.el-form-item__content) {
  display: block;
}
.upload-rules {
  margin-top: 12px;
  font-size: 12px;
  line-height: 1.65;
  color: #909399;
  p {
    margin: 0 0 6px;
    &:last-child {
      margin-bottom: 0;
    }
  }
}
.ocr-result-container {
  max-width: 640px;
  padding: 14px 16px;
  margin-top: 12px;
  background: #f5f7fa;
  border: 1px solid #ebeef5;
  border-radius: 6px;
}
.ocr-result-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 10px;
  font-size: 13px;
  line-height: 1.5;
  &:last-child {
    margin-bottom: 0;
  }
  .label {
    flex-shrink: 0;
    min-width: 88px;
    font-weight: 600;
    color: #606266;
  }
  .value {
    flex: 1;
    color: #303133;
    word-break: break-all;
  }
}
.ocr-result-tip {
  font-size: 13px;
  line-height: 1.5;
  color: #909399;
}
.license-ocr-result {
  max-width: 640px;
  padding: 14px 16px;
  margin-top: 12px;
  margin-left: 140px;
  background: #f5f7fa;
  border: 1px solid #ebeef5;
  border-radius: 6px;
}
.license-ocr-row {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 10px;
  font-size: 13px;
  line-height: 1.5;
  &:last-child {
    margin-bottom: 0;
  }
}
.license-ocr-label {
  flex-shrink: 0;
  width: 132px;
  font-weight: 600;
  color: #606266;
}
.license-ocr-value {
  flex: 1;
  color: #303133;
  word-break: break-all;
}
:deep(.el-upload--picture-card) {
  --el-upload-picture-card-size: 148px;
}
:deep(.el-upload-list--picture-card .el-upload-list__item) {
  width: 148px;
  height: 148px;
}
.footer-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: 24px;
  margin-top: 8px;
  border-top: 1px solid #ebeef5;
}
.footer-center {
  display: flex;
  flex: 1;
  justify-content: center;
}
.btn-next {
  min-width: 100px;
  background: $wechat-green;
  border-color: $wechat-green;
  &:hover {
    background: #06ad56;
    border-color: #06ad56;
  }
}
</style>
