<template>
  <a-modal
    v-model:open="visible"
    title="维护合同方信息"
    width="96vw"
    :footer="null"
    :mask-closable="false"
    :style="{ top: '12px' }"
    :body-style="{
      padding: 0,
      height: 'calc(100vh - 120px)',
      overflow: 'hidden',
    }"
  >
    <div class="contract-main-editor">
      <div class="editor-header">
        <div><h3>合同主信息</h3></div>
        <a-space>
          <a-tag :color="creationMode === 'manual' ? 'orange' : 'blue'">
            {{ creationMode === "manual" ? "手动创建" : "模板创建" }}
          </a-tag>
          <a-tag v-if="templateName" color="geekblue">
            {{ templateName }}
          </a-tag>
        </a-space>
      </div>

      <div class="editor-body">
        <a-form layout="vertical" :disabled="isViewMode" class="editor-form">
          <section class="main-grid">
          <div class="left-column">
            <div class="section-card">
              <div class="section-title-row">
                <div class="section-title">合同主信息</div>
              </div>

              <div class="party-block">
                <div class="field-label required">我方</div>
                <a-input
                  :value="detailState.partyState.partyA.companyName"
                  readonly
                  disabled
                />
                <div class="party-info-box">
                  <div class="info-line">
                    <span>我方</span
                    ><strong>{{
                      detailState.partyState.partyA.companyName || "/"
                    }}</strong>
                  </div>
                  <div class="info-line">
                    <span>电话</span
                    ><strong>{{
                      detailState.partyState.partyA.contactPhone || "/"
                    }}</strong>
                  </div>
                  <div class="info-line">
                    <span>公司地址</span
                    ><strong>{{
                      detailState.partyState.partyA.registeredAddress || "/"
                    }}</strong>
                  </div>
                  <div class="info-line">
                    <span>银行/账号</span
                    ><strong>{{
                      detailState.partyState.partyA.bankAccount || "/"
                    }}</strong>
                  </div>
                  <a-button
                    class="mini-search-btn"
                    type="text"
                    @click="showSearchTip('我方详情')"
                  >
                    <SearchOutlined />
                  </a-button>
                </div>
                <a-button
                  class="invoice-btn"
                  @click="showInvoiceTitles(detailState.partyState.partyA, '我方')"
                >
                  <PlusOutlined />
                  备选开票抬头选择
                </a-button>
              </div>

              <div class="section-title-row counterparty-toolbar">
                <div class="section-title">相对方</div>
                <a-button
                  v-if="!isViewMode"
                  type="link"
                  class="text-action-btn"
                  @click="handleAddCounterparty"
                >
                  添加
                </a-button>
              </div>

              <div
                v-for="(party, index) in counterpartyParties"
                :key="party.roleKey"
                class="party-block"
              >
                <div class="party-block-header">
                  <div class="field-label required">{{ party.displayName }}</div>
                  <a-button
                    v-if="!isViewMode"
                    type="link"
                    danger
                    class="text-action-btn"
                    @click="handleRemoveCounterparty(party.roleKey)"
                  >
                    删除
                  </a-button>
                </div>
                <div class="search-input-row">
                  <a-select
                    v-model:value="party.companyName"
                    :options="contractCompanyOptions"
                    show-search
                    :placeholder="`请选择${party.displayName}`"
                    @change="handleCompanySelect(party.roleKey, $event)"
                  />
                  <a-button
                    class="icon-btn"
                    @click="showSearchTip(`${party.displayName}`)"
                  >
                    <SearchOutlined />
                  </a-button>
                </div>
                <div class="party-info-box">
                  <div class="info-line">
                    <span>{{ party.displayName }}</span
                    ><strong>{{
                      party.companyName || "/"
                    }}</strong>
                  </div>
                  <div class="info-line">
                    <span>电话</span
                    ><strong>{{ party.contactPhone || "/" }}</strong>
                  </div>
                  <div class="info-line">
                    <span>公司地址</span
                    ><strong>{{ party.registeredAddress || "/" }}</strong>
                  </div>
                  <div class="info-line">
                    <span>银行/账号</span
                    ><strong>{{ party.bankAccount || "/" }}</strong>
                  </div>
                  <a-button
                    class="mini-search-btn"
                    type="text"
                    @click="showSearchTip(`${party.displayName}详情`)"
                  >
                    <SearchOutlined />
                  </a-button>
                </div>
              </div>

              <div v-if="!counterpartyParties.length" class="party-empty-state">
                暂无相对方，请点击右上角“添加”
              </div>

              <div class="field-grid field-grid-2">
                <a-form-item class="tight-item" label="合同名称" required>
                  <a-input
                    v-model:value="detailState.contractName"
                    placeholder="请输入"
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="合同号" required>
                  <a-input
                    v-model:value="detailState.contractCode"
                    placeholder="请输入"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="合同类型"
                  required
                >
                  <a-select
                    v-model:value="detailState.contractType"
                    :options="contractTypeOptions"
                    placeholder="请选择"
                  />
                </a-form-item>
              </div>

              <div class="period-block">
                <div class="field-label required">合同起止时间</div>
                <a-radio-group v-model:value="detailState.contractPeriodType">
                  <a-radio value="0">固定期限</a-radio>
                  <a-radio value="1">无固定期限</a-radio>
                </a-radio-group>
                <div
                  class="period-row"
                  v-if="detailState.contractPeriodType === '0'"
                >
                  <a-date-picker
                    v-model:value="detailState.effectiveStart"
                    value-format="YYYY-MM-DD"
                    placeholder="开始日期"
                    style="width: 48%"
                  />
                  <a-date-picker
                    v-model:value="detailState.effectiveEnd"
                    value-format="YYYY-MM-DD"
                    placeholder="结束日期"
                    style="width: 48%"
                  />
                </div>
                <a-input
                  v-else
                  v-model:value="detailState.periodExplain"
                  placeholder="期限说明"
                  class="period-explain-input"
                />
              </div>

              <div class="field-grid field-grid-2">
                <a-form-item class="tight-item" label="计价方式" required>
                  <a-select
                    v-model:value="detailState.valuationMode"
                    :options="valuationModeOptions"
                    placeholder="请选择"
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="币种" required>
                  <a-select
                    v-model:value="detailState.currencyName"
                    :options="currencyOptions"
                    placeholder="请选择"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="签订方式"
                  required
                >
                  <a-select
                    v-model:value="detailState.sealType"
                    :options="sealTypeOptions"
                    placeholder="请选择"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="委托类型"
                  required
                >
                  <a-select
                    v-model:value="detailState.mandateType"
                    :options="mandateTypeOptions"
                    placeholder="委托类型"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="货种"
                  required
                >
                  <a-select
                    v-model:value="detailState.cargoType"
                    :options="cargoTypeOptions"
                    placeholder="货种"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="付款方式"
                  required
                >
                  <a-select
                    v-model:value="detailState.paymentMethod"
                    :options="paymentMethodOptions"
                    placeholder="请选择付款方式"
                  />
                </a-form-item>
              </div>
            </div>
          </div>

          <div class="right-column">
            <div class="section-card">
              <div class="basic-header">
                <div class="basic-title">
                  <span class="dot"></span>
                  基本信息
                </div>
              </div>

              <div class="summary-grid">
                <div class="summary-line">
                  <span>合同名称</span
                  ><strong>{{ detailState.contractName || "未填写" }}</strong>
                </div>
                <div class="summary-line">
                  <span>我方</span
                  ><strong>{{
                    detailState.partyState.partyA.companyName || "未填写"
                  }}</strong>
                </div>
                <div class="summary-line">
                  <span>合同编号</span
                  ><strong>{{ detailState.contractCode || "未填写" }}</strong>
                </div>
                <div class="summary-line">
                  <span>相对方</span
                  ><strong>{{ counterpartySummaryText }}</strong>
                </div>
              </div>

              <div class="upload-block">
                <div class="upload-label">合同正文</div>
                <div
                  class="readonly-upload-box contract-body-entry"
                  :class="{ 'is-clickable': !isViewMode }"
                  @click="openBodyConfigModal"
                >
                  <div class="contract-body-entry-name">
                    {{ contractBodyDisplayText }}
                  </div>
                  <div class="contract-body-entry-hint">
                    {{ contractBodyHint }}
                  </div>
                </div>
              </div>

              <div class="upload-block">
                <div class="upload-label">其他附件</div>
                <a-upload-dragger
                  :file-list="otherAttachmentList"
                  :before-upload="handleOtherAttachmentUpload"
                  @remove="handleRemoveOtherAttachment"
                  :disabled="isViewMode"
                  :show-upload-list="{ showRemoveIcon: !isViewMode }"
                  multiple
                >
                  <div class="other-upload-text">其他附件(可上传多个文件)</div>
                </a-upload-dragger>
              </div>

              <a-form-item class="tight-item" label="主要内容">
                <a-textarea
                  v-model:value="detailState.primaryContent"
                  :rows="2"
                  placeholder="选填"
                />
              </a-form-item>

              <a-form-item class="tight-item" label="金额说明" required>
                <a-textarea
                  v-model:value="detailState.amountExplain"
                  :rows="2"
                  placeholder="选填"
                />
              </a-form-item>

              <div class="basic-title contract-attr-title">
                <span class="dot"></span>
                合同属性
              </div>

              <div class="field-grid field-grid-2">
                <a-form-item class="tight-item" label="计价方式">
                  <a-input
                    :value="
                      getOptionLabel(
                        valuationModeOptions,
                        detailState.valuationMode,
                      )
                    "
                    readonly
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="标的额">
                  <a-input-number
                    v-model:value="detailState.contractAmount"
                    :min="0"
                    :precision="2"
                    :controls="false"
                    style="width: 100%"
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="币种">
                  <a-input
                    :value="
                      getOptionLabel(currencyOptions, detailState.currencyName)
                    "
                    readonly
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="签订方式">
                  <a-input
                    :value="
                      getOptionLabel(sealTypeOptions, detailState.sealType)
                    "
                    readonly
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="协助部门">
                  <a-input
                    v-model:value="detailState.assistDept"
                    placeholder="协助部门"
                  />
                </a-form-item>
                <a-form-item class="tight-item" label="合同类型" required>
                  <a-select
                    v-model:value="detailState.contractTypeCode"
                    :options="contractTypeOptions"
                    placeholder="合同类型"
                  />
                </a-form-item>
                <a-form-item
                  class="tight-item field-span-2"
                  label="合同执行人"
                  required
                >
                  <a-input
                    v-model:value="detailState.executorAccount"
                    placeholder="合同执行人手机号"
                  />
                </a-form-item>
              </div>

              <div class="boolean-grid">
                <div class="boolean-row">
                  <span>是否涉及港澳台</span>
                  <a-radio-group
                    v-model:value="detailState.isInvolveHongKongMacaoTaiwan"
                  >
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
                <div class="boolean-row">
                  <span>是否公开招标</span>
                  <a-radio-group v-model:value="detailState.isPublicTender">
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
                <div class="boolean-row">
                  <span>签约主体是否涉外</span>
                  <a-radio-group
                    v-model:value="detailState.isForeignRelatedSubject"
                  >
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
                <div class="boolean-row">
                  <span>是否列入当年预算</span>
                  <a-radio-group
                    v-model:value="detailState.isIncludedInCurrentYearBudget"
                  >
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
                <div class="boolean-row">
                  <span>是否共享</span>
                  <a-radio-group v-model:value="detailState.isShared">
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
                <div class="boolean-row">
                  <span>是否重大合同</span>
                  <a-radio-group v-model:value="detailState.isMajorContract">
                    <a-radio :value="true">是</a-radio>
                    <a-radio :value="false">否</a-radio>
                  </a-radio-group>
                </div>
              </div>

              <div class="extra-amount-section">
                <div class="extra-label">额外金额</div>
                <div class="extra-check-row">
                  <label
                    v-for="item in extraAmountFieldOptions"
                    :key="item.key"
                    class="extra-check-item"
                  >
                    <a-checkbox
                      v-model:checked="
                        detailState.extraAmounts[`${item.key}Enabled`]
                      "
                    >
                      {{ item.label }}
                    </a-checkbox>
                  </label>
                </div>
                <div class="extra-input-row">
                  <a-input-number
                    v-for="item in extraAmountFieldOptions"
                    :key="`${item.key}_input`"
                    v-model:value="detailState.extraAmounts[item.key]"
                    :disabled="!detailState.extraAmounts[`${item.key}Enabled`]"
                    :min="0"
                    :controls="false"
                    :precision="2"
                    style="width: 24%"
                  />
                </div>
              </div>

              <div class="plan-section">
                <div class="basic-title contract-attr-title">
                  <span class="dot"></span>
                  履行计划
                </div>
                <div class="plan-toolbar">
                  <a-button
                    type="dashed"
                    size="small"
                    @click="addPerformancePlan"
                  >
                    <PlusOutlined />
                    新增履行计划
                  </a-button>
                </div>
                <a-table
                  :data-source="detailState.performancePlans"
                  :pagination="false"
                  size="small"
                  :scroll="{ x: 820 }"
                  row-key="id"
                  class="plan-table"
                >
                  <a-table-column title="履行事项" key="planMatter">
                    <template #default="{ record }">
                      <a-input v-model:value="record.planMatter" />
                    </template>
                  </a-table-column>
                  <a-table-column title="履约条件" key="planWhere">
                    <template #default="{ record }">
                      <a-input v-model:value="record.planWhere" />
                    </template>
                  </a-table-column>
                  <a-table-column title="节点日期" key="planTime" width="140">
                    <template #default="{ record }">
                      <a-date-picker
                        v-model:value="record.planTime"
                        value-format="YYYY-MM-DD"
                        style="width: 100%"
                      />
                    </template>
                  </a-table-column>
                  <a-table-column
                    title="提醒提前天数"
                    key="planDay"
                    width="130"
                  >
                    <template #default="{ record }">
                      <a-input-number
                        v-model:value="record.planDay"
                        :min="0"
                        :controls="false"
                        style="width: 100%"
                      />
                    </template>
                  </a-table-column>
                  <a-table-column title="款项金额" key="planMoney" width="130">
                    <template #default="{ record }">
                      <a-input-number
                        v-model:value="record.planMoney"
                        :min="0"
                        :controls="false"
                        style="width: 100%"
                      />
                    </template>
                  </a-table-column>
                  <a-table-column title="备注" key="planDetail">
                    <template #default="{ record }">
                      <a-input v-model:value="record.planDetail" />
                    </template>
                  </a-table-column>
                  <a-table-column
                    title="操作"
                    key="action"
                    width="80"
                    fixed="right"
                  >
                    <template #default="{ record }">
                      <a-button
                        type="link"
                        danger
                        size="small"
                        @click="removePerformancePlan(record.id)"
                      >
                        删除
                      </a-button>
                    </template>
                  </a-table-column>
                  <template #emptyText>
                    <div class="empty-plan-text">暂无数据</div>
                  </template>
                </a-table>
              </div>
            </div>
          </div>
        </section>

          <a-collapse class="detail-collapse">
          <a-collapse-panel
            v-for="party in displayedParties"
            :key="party.roleKey"
            :header="`${party.displayName}详细字段维护`"
          >
            <div class="field-grid field-grid-3">
              <a-form-item class="tight-item" label="公司类型">
                <a-select
                  v-model:value="party.companyType"
                  :options="companyTypeOptions"
                />
              </a-form-item>
              <a-form-item class="tight-item" label="公司性质">
                <a-select
                  v-model:value="party.companyNature"
                  :options="companyNatureOptions"
                />
              </a-form-item>
              <a-form-item class="tight-item" label="组织性质">
                <a-select
                  v-model:value="party.organizationNature"
                  :options="organizationNatureOptions"
                />
              </a-form-item>
              <a-form-item class="tight-item" label="组织性质企业二级">
                <a-select
                  v-model:value="party.enterpriseNatureLevel2"
                  :options="enterpriseNatureLevel2Options"
                />
              </a-form-item>
              <a-form-item class="tight-item" label="统一社会信用代码">
                <a-input v-model:value="party.creditCode" />
              </a-form-item>
              <a-form-item class="tight-item" label="TIN号">
                <a-input v-model:value="party.tinNo" />
              </a-form-item>
              <a-form-item class="tight-item" label="国家/地区">
                <a-select
                  v-model:value="party.countryCode"
                  :options="countryOptions"
                />
              </a-form-item>
              <a-form-item class="tight-item" label="法定代表人">
                <a-input v-model:value="party.legalRepresentative" />
              </a-form-item>
              <a-form-item class="tight-item field-span-3" label="注册地址">
                <a-input v-model:value="party.registeredAddress" />
              </a-form-item>
              <a-form-item class="tight-item" label="注册资本">
                <a-input v-model:value="party.registeredCapital" />
              </a-form-item>
              <a-form-item class="tight-item" label="联系电话">
                <a-input v-model:value="party.contactPhone" />
              </a-form-item>
              <a-form-item class="tight-item" label="电子邮箱">
                <a-input v-model:value="party.contactEmail" />
              </a-form-item>
              <a-form-item class="tight-item field-span-3" label="通讯地址">
                <a-input v-model:value="party.contactAddress" />
              </a-form-item>
              <a-form-item class="tight-item" label="开户行">
                <a-input v-model:value="party.bankName" />
              </a-form-item>
              <a-form-item class="tight-item field-span-2" label="银行账号">
                <a-input v-model:value="party.bankAccount" />
              </a-form-item>
              <a-form-item class="tight-item field-span-3" label="备选开票抬头">
                <a-select
                  v-model:value="party.invoiceTitleOptions"
                  mode="tags"
                  :token-separators="[',', '，']"
                />
              </a-form-item>
            </div>
          </a-collapse-panel>
          </a-collapse>
        </a-form>
      </div>

      <div class="editor-footer">
        <a-space>
          <a-button v-if="!isViewMode" @click="resetCurrentState">重置</a-button>
          <a-button @click="visible = false">{{ isViewMode ? "关闭" : "取消" }}</a-button>
          <a-button v-if="!isViewMode" type="primary" @click="handleSave">保存</a-button>
        </a-space>
      </div>
    </div>

    <ContractTemplateFillDemoModal
      ref="bodyConfigModalRef"
      @save="handleBodyConfigSave"
    />
  </a-modal>
</template>

<script setup>
import { computed, ref } from "vue";
import { message } from "ant-design-vue";
import { PlusOutlined, SearchOutlined } from "@ant-design/icons-vue";
import ContractTemplateFillDemoModal from "./ContractTemplateFillDemoModal.vue";

// ========================================================================
// 以下为表单模型 + 字典 + 工具函数，直接内联在此文件中。
// 接入后端时，保留这些函数，替换入参/出参为真实接口即可。
// ========================================================================

// ========== 合同方相关字典 ==========

const partyCharacterOptions = [
  { label: "企业", value: "QY" },
  { label: "自然人", value: "ZZR" },
];

const companyTypeOptions = [
  { label: "客户", value: "客户" },
  { label: "供应商", value: "供应商" },
  { label: "合作伙伴", value: "合作伙伴" },
  { label: "客户及供应商", value: "客户及供应商" },
  { label: "其他", value: "其他" },
];

const companyNatureOptions = [
  { label: "境内组织", value: "境内组织" },
  { label: "境内个人", value: "境内个人" },
  { label: "境外组织", value: "境外组织" },
  { label: "境外个人", value: "境外个人" },
];

const organizationNatureOptions = [
  { label: "政府", value: "政府" },
  { label: "企业", value: "企业" },
  { label: "其他组织", value: "其他组织" },
];

const enterpriseNatureLevel2Options = [
  { label: "国有企业", value: "国有企业" },
  { label: "民营企业", value: "民营企业" },
  { label: "外资企业", value: "外资企业" },
  { label: "合资企业", value: "合资企业" },
  { label: "国有全资和控股企业", value: "国有全资和控股企业" },
];

const countryOptions = [
  { label: "中国", value: "GJ156" },
  { label: "中国香港", value: "GJ344" },
  { label: "中国澳门", value: "GJ446" },
  { label: "中国台湾", value: "GJ158" },
  { label: "新加坡", value: "GJ702" },
  { label: "美国", value: "GJ840" },
  { label: "英国", value: "GJ826" },
  { label: "日本", value: "GJ392" },
];

const contractCompanyOptions = [
  { label: "扬州宏富特种材料有限公司", value: "扬州宏富特种材料有限公司" },
  { label: "宁波港船务货运代理有限公司", value: "宁波港船务货运代理有限公司" },
  { label: "宁波浙港供应链科技有限公司", value: "宁波浙港供应链科技有限公司" },
  { label: "上海远洋能源有限公司", value: "上海远洋能源有限公司" },
  { label: "宁波保税区港航设备有限公司", value: "宁波保税区港航设备有限公司" },
  { label: "浙江临港数智科技有限公司", value: "浙江临港数智科技有限公司" },
  { label: "杭州智云实施服务有限公司", value: "杭州智云实施服务有限公司" },
  { label: "浙港物流平台有限公司", value: "浙港物流平台有限公司" },
];

// ========== 合同相关字典 ==========

const contractTypeOptions = [
  { label: "采购合同", value: "采购合同" },
  { label: "销售合同", value: "销售合同" },
  { label: "服务合同", value: "服务合同" },
  { label: "框架合同", value: "框架合同" },
];

const valuationModeOptions = [
  { label: "无金额", value: "0" },
  { label: "固定总价", value: "1" },
  { label: "预估总价", value: "2" },
  { label: "无法预估总价", value: "3" },
  { label: "固定单价", value: "4" },
];

const currencyOptions = [
  { label: "人民币", value: "RMB" },
  { label: "美元", value: "USD" },
  { label: "港币", value: "HKD" },
  { label: "欧元", value: "EUR" },
  { label: "印尼盾", value: "IDR" },
];

const sealTypeOptions = [
  { label: "公章", value: "GZ" },
  { label: "合同专用章", value: "HTZYZ" },
  { label: "公章+法定代表人私章", value: "GZFDDBRSZ" },
  { label: "公章+法定代表人签字", value: "GZFDDBRQZ" },
  { label: "公章+被授权人签字", value: "GZBSQRQZ" },
  { label: "合同专用章+被授权人签字", value: "HTZYZBSQRQZ" },
  { label: "合同专用章+法定代表人签字", value: "HTZYZFDDBRQZ" },
  { label: "其他", value: "QT" },
];

const mandateTypeOptions = [
  { label: "海铁联运委托", value: "海铁联运委托" },
  { label: "一站式物流委托", value: "一站式物流委托" },
  { label: "采购执行委托", value: "采购执行委托" },
  { label: "销售执行委托", value: "销售执行委托" },
];

const cargoTypeOptions = [
  { label: "燃料油", value: "燃料油" },
  { label: "港口设备", value: "港口设备" },
  { label: "软件服务", value: "软件服务" },
  { label: "综合物流", value: "综合物流" },
];

const paymentMethodOptions = [
  {
    label: "银行转账（30%预付款，70%验收后支付）",
    value: "银行转账（30%预付款，70%验收后支付）",
  },
  { label: "银行转账（按月结算）", value: "银行转账（按月结算）" },
  { label: "银行转账（一次性结清）", value: "银行转账（一次性结清）" },
];

const extraAmountFieldOptions = [
  { key: "deposit", label: "定金" },
  { key: "pledge", label: "押金" },
  { key: "advance", label: "预付款" },
  { key: "guarantee", label: "保证金" },
];

const SELF_COMPANY_NAME = "浙港物流平台有限公司";
const MAX_COUNTERPARTY_COUNT = 2;

function getOptionLabel(options, value) {
  return options.find((item) => item.value === value)?.label || value || "";
}

// ========== 工具函数 ==========

/** 深拷贝合同方状态 */
function copyPartyState(input) {
  const source = input || {};
  const sourcePartyA = source.partyA || source.parties?.A || {};
  const sourcePartyB = source.partyB || source.parties?.B || {};
  const sourcePartyC = source.partyC || source.parties?.C || {};
  return {
    isThreePartyContract: Boolean(source.isThreePartyContract),
    partyA: {
      roleKey: "A",
      roleName: "我方",
      displayName: "我方",
      ...sourcePartyA,
      companyName: sourcePartyA.companyName || SELF_COMPANY_NAME,
    },
    partyB: {
      roleKey: "B",
      roleName: "相对方",
      displayName: "相对方1",
      companyName: "",
      ...sourcePartyB,
    },
    partyC: {
      roleKey: "C",
      roleName: "相对方",
      displayName: "相对方2",
      companyName: "",
      ...sourcePartyC,
    },
  };
}

function createEmptyCounterparty(roleKey) {
  const blankState = copyPartyState({});
  return roleKey === "C" ? blankState.partyC : blankState.partyB;
}

function isPartyFilled(party = {}) {
  const ignoreKeys = new Set(["roleKey", "roleName", "displayName"]);
  return Object.entries(party).some(([key, value]) => {
    if (ignoreKeys.has(key)) return false;
    if (Array.isArray(value)) return value.length > 0;
    if (typeof value === "number") return !Number.isNaN(value);
    return String(value ?? "").trim() !== "";
  });
}

function buildCounterpartyRoleKeys(partyState) {
  const state = copyPartyState(partyState);
  const keys = [];
  if (isPartyFilled(state.partyB)) keys.push("B");
  if (isPartyFilled(state.partyC)) keys.push("C");
  return keys;
}

function normalizePartyState(partyState) {
  const state = copyPartyState(partyState);
  if (!isPartyFilled(state.partyB) && isPartyFilled(state.partyC)) {
    state.partyB = {
      ...createEmptyCounterparty("B"),
      ...state.partyC,
      roleKey: "B",
      roleName: "相对方",
      displayName: "相对方1",
    };
    state.partyC = createEmptyCounterparty("C");
  }
  state.partyA.companyName = state.partyA.companyName || SELF_COMPANY_NAME;
  state.isThreePartyContract =
    isPartyFilled(state.partyB) && isPartyFilled(state.partyC);
  return state;
}

function getPartyByRoleKey(partyState, roleKey) {
  if (roleKey === "A") return partyState.partyA;
  if (roleKey === "C") return partyState.partyC;
  return partyState.partyB;
}

/** 创建一条空的履行计划 */
function createPerformancePlan() {
  return {
    id: `plan_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
    planMatter: "",
    planWhere: "",
    planTime: "",
    planDay: 0,
    planMoney: "",
    planDetail: "",
  };
}

/** 创建空白的合同表单数据 */
function createContractFormData() {
  return {
    contractName: "",
    contractCode: "",
    contractType: "",
    contractTypeCode: "",
    contractAmount: null,
    effectiveStart: "",
    effectiveEnd: "",
    contractPeriodType: "0",
    periodExplain: "",
    paymentMethod: "",
    valuationMode: "",
    currencyName: "",
    sealType: "",
    mandateType: "",
    cargoType: "",
    primaryContent: "",
    amountExplain: "",
    assistDept: "",
    executorAccount: "",

    contractBodyFileName: "",
    contractBodyArrayBuffer: null,
    otherAttachmentList: [],
    partyState: {
      isThreePartyContract: false,
      partyA: { companyName: SELF_COMPANY_NAME },
      partyB: { companyName: "" },
      partyC: { companyName: "" },
    },
    isInvolveHongKongMacaoTaiwan: false,
    isPublicTender: false,
    isForeignRelatedSubject: false,
    isIncludedInCurrentYearBudget: false,
    isShared: false,
    isMajorContract: false,
    extraAmounts: {
      depositEnabled: false,
      deposit: 0,
      pledgeEnabled: false,
      pledge: 0,
      advanceEnabled: false,
      advance: 0,
      guaranteeEnabled: false,
      guarantee: 0,
    },
    performancePlans: [],
    signDate: "",
  };
}

/** 深拷贝合同表单数据 */
function copyContractFormData(data = {}) {
  const form = createContractFormData();
  const source = data || {};
  Object.keys(form).forEach((key) => {
    if (key === "extraAmounts") {
      form.extraAmounts = {
        ...form.extraAmounts,
        ...(source.extraAmounts || {}),
      };
    } else if (key === "performancePlans") {
      form.performancePlans = (source.performancePlans || []).map((item) => ({
        ...createPerformancePlan(),
        ...item,
      }));
    } else if (key === "partyState") {
      form.partyState = normalizePartyState(source.partyState);
    } else if (key === "otherAttachmentList") {
      form.otherAttachmentList = [
        ...(source.otherAttachmentList || source.attachmentList || []),
      ];
    } else if (key === "contractBodyArrayBuffer") {
      form.contractBodyArrayBuffer = source.contractBodyArrayBuffer
        ? source.contractBodyArrayBuffer instanceof ArrayBuffer
          ? source.contractBodyArrayBuffer.slice(0)
          : null
        : null;
    } else {
      form[key] = source[key] ?? form[key];
    }
  });
  return form;
}

const emit = defineEmits(["save"]);

const visible = ref(false);
const modalMode = ref("create");
const creationMode = ref("template");
const templateKey = ref("");
const templateName = ref("");
const detailState = ref(createContractFormData());
const otherAttachmentList = ref([]);
const bodyConfigModalRef = ref(null);
const counterpartyRoleKeys = ref([]);

const companyProfileMap = {
  扬州宏富特种材料有限公司: {
    contactPhone: "13800000001",
    registeredAddress: "江苏省扬州市邗江区江阳中路88号",
    bankAccount: "622202100000000001",
    bankName: "中国工商银行扬州分行",
    contactName: "王经理",
    legalRepresentative: "张三",
    creditCode: "91321000MA1X111111",
  },
  宁波港船务货运代理有限公司: {
    contactPhone: "15757460062",
    registeredAddress: "宁波市北仑区明州西路188号",
    bankAccount: "39011600192100006088",
    bankName: "中国工商银行股份有限公司宁波市支行",
    contactName: "周经理",
    legalRepresentative: "李四",
    creditCode: "91330201MA2ABCDE9X",
  },
  宁波浙港供应链科技有限公司: {
    contactPhone: "13900000088",
    registeredAddress: "宁波市江北区长兴路689号",
    bankAccount: "621700000000000088",
    bankName: "中国银行宁波分行",
    contactName: "陈经理",
    legalRepresentative: "陈总",
    creditCode: "91330200MA2SUPPLY01",
  },
  上海远洋能源有限公司: {
    contactPhone: "13600000015",
    registeredAddress: "上海市浦东新区临港大道188号",
    bankAccount: "621483000000000015",
    bankName: "招商银行上海分行",
    contactName: "吴经理",
    legalRepresentative: "孙先生",
    creditCode: "91310115MAOCEAN001",
  },
};

const isViewMode = computed(() => modalMode.value === "view");

const counterpartyParties = computed(() =>
  counterpartyRoleKeys.value.map((roleKey) =>
    getPartyByRoleKey(detailState.value.partyState, roleKey),
  ),
);

const displayedParties = computed(() => [
  detailState.value.partyState.partyA,
  ...counterpartyParties.value,
]);

const counterpartySummaryText = computed(() =>
  counterpartyParties.value.length
    ? counterpartyParties.value
        .map((party) => party.companyName || party.displayName)
        .join("；")
    : "未填写",
);

const contractBodyDisplayText = computed(() =>
  detailState.value.contractBodyFileName ||
  (creationMode.value === "manual"
    ? "点击上传合同正文 Word 文件"
    : templateName.value || "点击配置合同正文"),
);

const contractBodyHint = computed(() =>
  creationMode.value === "manual"
    ? "当前为手动创建，支持上传并预览 .docx 正文"
    : templateName.value
      ? `当前模板：${templateName.value}，点击继续维护模板信息和预览`
      : "当前为模板创建，点击维护模板信息和正文预览",
);

function syncUploadLists() {
  otherAttachmentList.value = (detailState.value.otherAttachmentList || []).map(
    (item, index) => ({
      uid: item.uid || `other_${index + 1}`,
      name: item.name,
      size: item.size,
      status: item.status || "done",
    }),
  );
}

function syncCounterpartyState() {
  detailState.value.partyState = normalizePartyState(detailState.value.partyState);
  counterpartyRoleKeys.value = buildCounterpartyRoleKeys(
    detailState.value.partyState,
  );
  detailState.value.partyState.isThreePartyContract =
    counterpartyRoleKeys.value.length > 1;
  refreshPartyDisplayMeta();
}

function refreshPartyDisplayMeta() {
  detailState.value.partyState.partyA.roleKey = "A";
  detailState.value.partyState.partyA.roleName = "我方";
  detailState.value.partyState.partyA.displayName = "我方";

  counterpartyRoleKeys.value.forEach((roleKey, index) => {
    const party = getPartyByRoleKey(detailState.value.partyState, roleKey);
    party.roleKey = roleKey;
    party.roleName = "相对方";
    party.displayName = `相对方${index + 1}`;
  });
}

function resetCurrentState() {
  creationMode.value = "template";
  templateKey.value = "";
  templateName.value = "";
  detailState.value = createContractFormData();
  syncCounterpartyState();
  syncUploadLists();
}

function showSearchTip(title) {
  message.info(
    `${title}查询接口当前未接入，这里先保留与原型一致的搜索入口样式。`,
  );
}

function showInvoiceTitles(party, roleName) {
  const titles = party.invoiceTitleOptions || [];
  message.info(
    titles.length
      ? `${roleName}备选开票抬头：${titles.join("；")}`
      : `${roleName}暂无备选开票抬头`,
  );
}

function handleCompanySelect(roleKey, companyName) {
  const party =
    roleKey === "A"
      ? detailState.value.partyState.partyA
      : roleKey === "B"
        ? detailState.value.partyState.partyB
        : detailState.value.partyState.partyC;
  const profile = companyProfileMap[companyName];
  if (!party || !profile) return;

  Object.assign(party, {
    companyName,
    contactPhone: party.contactPhone || profile.contactPhone,
    registeredAddress: party.registeredAddress || profile.registeredAddress,
    bankAccount: party.bankAccount || profile.bankAccount,
    bankName: party.bankName || profile.bankName,
    contactName: party.contactName || profile.contactName,
    legalRepresentative:
      party.legalRepresentative || profile.legalRepresentative,
    creditCode: party.creditCode || profile.creditCode,
  });
}

function handleAddCounterparty() {
  if (counterpartyRoleKeys.value.length >= MAX_COUNTERPARTY_COUNT) {
    message.warning(`最多支持添加 ${MAX_COUNTERPARTY_COUNT} 个相对方`);
    return;
  }

  const nextRoleKey = counterpartyRoleKeys.value.includes("B") ? "C" : "B";
  detailState.value.partyState[nextRoleKey === "C" ? "partyC" : "partyB"] =
    createEmptyCounterparty(nextRoleKey);
  counterpartyRoleKeys.value = [...counterpartyRoleKeys.value, nextRoleKey];
  detailState.value.partyState.isThreePartyContract =
    counterpartyRoleKeys.value.length > 1;
  refreshPartyDisplayMeta();
}

function handleRemoveCounterparty(roleKey) {
  if (roleKey === "B" && counterpartyRoleKeys.value.includes("C")) {
    detailState.value.partyState.partyB = {
      ...createEmptyCounterparty("B"),
      ...detailState.value.partyState.partyC,
      roleKey: "B",
      roleName: "相对方",
      displayName: "相对方1",
    };
    detailState.value.partyState.partyC = createEmptyCounterparty("C");
    counterpartyRoleKeys.value = ["B"];
  } else {
    detailState.value.partyState[roleKey === "C" ? "partyC" : "partyB"] =
      createEmptyCounterparty(roleKey);
    counterpartyRoleKeys.value = counterpartyRoleKeys.value.filter(
      (key) => key !== roleKey,
    );
  }

  detailState.value.partyState.isThreePartyContract =
    counterpartyRoleKeys.value.length > 1;
  refreshPartyDisplayMeta();
}

function handleOtherAttachmentUpload(file) {
  const item = {
    uid: `other_${Date.now()}_${Math.random().toString(16).slice(2, 8)}`,
    name: file.name,
    size: file.size,
    status: "done",
  };
  detailState.value.otherAttachmentList.push(item);
  otherAttachmentList.value.push(item);
  message.success(`已添加附件：${file.name}`);
  return false;
}

function handleRemoveOtherAttachment(file) {
  detailState.value.otherAttachmentList =
    detailState.value.otherAttachmentList.filter(
      (item) => item.uid !== file.uid && item.name !== file.name,
    );
  otherAttachmentList.value = otherAttachmentList.value.filter(
    (item) => item.uid !== file.uid && item.name !== file.name,
  );
}

function openBodyConfigModal() {
  bodyConfigModalRef.value?.showModal(
    {
      detailState: copyContractFormData(detailState.value),
      creationMode: creationMode.value,
      templateKey: templateKey.value,
      templateName: templateName.value,
    },
    isViewMode.value ? "view" : "edit",
  );
}

function handleBodyConfigSave(payload = {}) {
  creationMode.value = payload.creationMode || "template";
  templateKey.value = payload.templateKey || "";
  templateName.value = payload.templateName || "";
  detailState.value = copyContractFormData(payload.detailState);
  syncCounterpartyState();
  syncUploadLists();
}

function addPerformancePlan() {
  detailState.value.performancePlans.push(createPerformancePlan());
}

function removePerformancePlan(id) {
  detailState.value.performancePlans =
    detailState.value.performancePlans.filter((item) => item.id !== id);
}

function validateState() {
  if (!detailState.value.partyState.partyA.companyName?.trim())
    return "请确认我方信息";
  if (!counterpartyRoleKeys.value.length) return "请至少添加一个相对方";
  if (
    counterpartyParties.value.some((party) => !party.companyName?.trim())
  )
    return "请选择相对方";
  if (!detailState.value.contractName?.trim()) return "请填写合同名称";
  if (!detailState.value.contractCode?.trim()) return "请填写合同号";
  if (!detailState.value.contractType) return "请选择合同类型";
  if (
    detailState.value.contractPeriodType === "0" &&
    (!detailState.value.effectiveStart || !detailState.value.effectiveEnd)
  )
    return "请选择固定期限起止日期";
  if (
    detailState.value.contractPeriodType === "1" &&
    !detailState.value.periodExplain?.trim()
  )
    return "请填写期限说明";
  if (!detailState.value.valuationMode) return "请选择计价方式";
  if (!detailState.value.currencyName) return "请选择币种";
  if (!detailState.value.sealType) return "请选择签订方式";
  if (!detailState.value.mandateType) return "请选择委托类型";
  if (!detailState.value.cargoType) return "请选择货种";
  if (!detailState.value.contractTypeCode) return "请选择合同属性中的合同类型";
  if (!detailState.value.executorAccount?.trim()) return "请填写合同执行人";
  return "";
}

function handleSave() {
  const errorMessage = validateState();
  if (errorMessage) {
    message.warning(errorMessage);
    return;
  }

  syncCounterpartyState();
  detailState.value.contractAmount =
    detailState.value.contractAmount === null ||
    detailState.value.contractAmount === undefined ||
    detailState.value.contractAmount === ""
      ? null
      : Number(detailState.value.contractAmount);

  emit("save", {
    detailState: copyContractFormData(detailState.value),
    creationMode: creationMode.value,
    templateKey: templateKey.value,
    templateName: templateName.value,
  });
  visible.value = false;
  message.success("合同方信息已保存");
}

function showModal(context = {}, mode = "create") {
  modalMode.value = mode || "create";
  const source = context.detailState ||
    (Object.keys(context || {}).length ? context : createContractFormData());

  creationMode.value =
    context.creationMode ||
    (source.contractBodyArrayBuffer ? "manual" : "template");
  templateKey.value = context.templateKey || "";
  templateName.value = context.templateName || "";
  detailState.value = copyContractFormData(source);
  syncCounterpartyState();
  syncUploadLists();
  visible.value = true;
}

defineExpose({
  showModal,
});
</script>

<style scoped>
.contract-main-editor {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #f6f8fb;
}

.editor-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 24px 14px;
  background: #fff;
  border-bottom: 1px solid #e5e7eb;
}

.editor-header h3 {
  font-size: 20px;
  font-weight: 700;
  color: #0f172a;
  margin-bottom: 6px;
}

.editor-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
}

.editor-form {
  height: 100%;
}

.main-grid {
  display: grid;
  grid-template-columns: 470px minmax(0, 1fr);
  gap: 18px;
}

.section-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 16px 18px;
}

.section-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}

.counterparty-toolbar {
  margin-top: 18px;
  margin-bottom: 10px;
}

.section-title,
.basic-title {
  font-size: 16px;
  font-weight: 700;
  color: #111827;
}

.basic-header {
  border-bottom: 1px solid #eef2f7;
  padding-bottom: 10px;
  margin-bottom: 14px;
}

.basic-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.dot {
  width: 10px;
  height: 10px;
  background: #2563eb;
  border-radius: 2px;
}

.party-block + .party-block {
  margin-top: 14px;
}

.party-block-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.field-label {
  font-size: 13px;
  color: #334155;
  margin-bottom: 6px;
}

.required::before {
  content: "*";
  color: #ef4444;
  margin-right: 4px;
}

.search-input-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 34px;
  gap: 6px;
  margin-bottom: 8px;
}

.icon-btn,
.mini-search-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #2563eb;
}

.text-action-btn {
  padding-inline: 0;
}

.party-info-box {
  position: relative;
  background: #fafbff;
  border: 1px solid #edf2f7;
  border-radius: 6px;
  padding: 10px 38px 10px 12px;
  margin-bottom: 8px;
}

.info-line {
  display: flex;
  gap: 10px;
  font-size: 12px;
  line-height: 1.8;
}

.info-line span {
  width: 62px;
  flex-shrink: 0;
  color: #475569;
}

.info-line strong {
  color: #0f172a;
  font-weight: 500;
}

.mini-search-btn {
  position: absolute;
  top: 8px;
  right: 8px;
}

.invoice-btn {
  width: 100%;
  justify-content: flex-start;
}

.party-empty-state {
  padding: 10px 12px;
  border: 1px dashed #dbe3ee;
  border-radius: 8px;
  background: #f8fbff;
  color: #64748b;
  font-size: 13px;
}

.field-grid {
  display: grid;
  gap: 10px 14px;
}

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

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

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

.field-span-3 {
  grid-column: span 3;
}

.tight-item {
  margin-bottom: 4px;
}

.period-block {
  margin-top: 10px;
  margin-bottom: 12px;
}

.period-row {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
}

.period-explain-input {
  margin-top: 8px;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 18px;
  margin-bottom: 16px;
}

.summary-line {
  display: flex;
  gap: 10px;
  font-size: 13px;
}

.summary-line span {
  width: 62px;
  flex-shrink: 0;
  color: #475569;
}

.summary-line strong {
  color: #0f172a;
  font-weight: 600;
}

.upload-block {
  margin-bottom: 14px;
}

.upload-label {
  font-size: 13px;
  color: #334155;
  margin-bottom: 6px;
}

.readonly-upload-box {
  min-height: 44px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-direction: column;
  padding: 10px 12px;
  border: 1px dashed #dbe3ee;
  border-radius: 8px;
  background: #f8fbff;
  color: #475569;
  font-size: 13px;
}

.contract-body-entry {
  gap: 4px;
  transition: all 0.2s ease;
}

.contract-body-entry.is-clickable {
  cursor: pointer;
}

.contract-body-entry.is-clickable:hover {
  border-color: #91caff;
  background: #eef6ff;
}

.contract-body-entry-name {
  color: #0f172a;
  font-weight: 600;
  word-break: break-all;
}

.contract-body-entry-hint {
  color: #64748b;
  line-height: 1.6;
}

.other-upload-text {
  font-size: 13px;
  color: #475569;
}

.contract-attr-title {
  margin-top: 14px;
  margin-bottom: 10px;
}

.boolean-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 18px;
  margin-top: 6px;
}

.boolean-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 32px;
  font-size: 13px;
  color: #334155;
}

.extra-amount-section {
  margin-top: 16px;
}

.extra-label {
  font-size: 13px;
  font-weight: 600;
  color: #334155;
  margin-bottom: 8px;
}

.extra-check-row,
.extra-input-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

.extra-check-item {
  width: 24%;
  font-size: 13px;
}

.plan-section {
  margin-top: 18px;
}

.plan-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 8px;
}

.plan-table :deep(.ant-table-cell) {
  vertical-align: top;
}

.empty-plan-text {
  padding: 12px 0;
  color: #94a3b8;
}

.detail-collapse {
  margin-top: 16px;
  background: transparent;
}

.editor-footer {
  display: flex;
  justify-content: flex-end;
  padding: 14px 20px 18px;
  background: #fff;
  border-top: 1px solid #e5e7eb;
}

@media (max-width: 1280px) {
  .main-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) {
  .field-grid-2,
  .field-grid-3,
  .summary-grid,
  .boolean-grid {
    grid-template-columns: 1fr;
  }

  .field-span-2,
  .field-span-3 {
    grid-column: span 1;
  }

  .extra-check-row,
  .extra-input-row {
    flex-direction: column;
  }

  .extra-check-item,
  .extra-input-row :deep(.ant-input-number) {
    width: 100% !important;
  }
}
</style>
