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

import { useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';

import { Button, Card, Descriptions, Image, Modal as AntdModal, Space, Tabs, Tag, message } from 'ant-design-vue';

import OrderTraceDrawer from '#/views/business/order/components/order-trace-drawer.vue';
import { retrySettleApi } from '#/views/business/order/api/order-ops';

import OrderPricePercentAdjustDrawer from '#/views/business/order/components/OrderPricePercentAdjustDrawer.vue';
import { getOrderPriceAdjustConfig, adjustOrderPercent } from '#/api/order/priceAdjust';
import type { QuickDiscountOption } from '#/utils/pricePercentAdjust';
import { formatPriceDiscountLabel, normalizeQuickOptions } from '#/utils/pricePercentAdjust';
import { expressDetailByOrderId, getOrderInfo, syncLegacyShipmentApi } from '../api';
import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';
import { formatDoctorOrderText } from '#/utils/prescriptionDoctorOrder';
import LogisticsModal from './logistics-modal.vue';

defineOptions({
  name: 'DetailModal',
});

const userStore = useUserStore();
const gridApi = ref();
// 订单信息
const data = ref();
// 快递信息
const expressDetail = ref({});
// 订单发货方式
const deliveryMethod = ref(-1);
const syncingLegacy = ref(false);
/** 重新结算请求中，防止重复点击 */
const retrySettling = ref(false);

/**
 * 超管可见：已支付且未取消/未退款时可重新结算（补齐残缺分账）
 * 与后端一致：仅 role_id=1（SUPPER_ADMIN）
 */
const canRetrySettle = computed(() => {
  const roleId = Number(
    userStore.userInfo?.role_id ?? userStore.userInfo?.roles?.id,
  );
  if (roleId !== 1) return false;
  const row = data.value;
  if (!row?.id) return false;
  return (
    Number(row.is_pay) === 1 &&
    Number(row.cancel_status) === 0 &&
    Number(row.refund_status) === 0
  );
});

/**
 * 超管可见：上门快递且订单有运单时，可手动把历史运单同步到 shipment
 * 与后端一致：仅 role_id=1（SUPPER_ADMIN）
 */
const canSyncLegacyShipment = computed(() => {
  const roleId = Number(
    userStore.userInfo?.role_id ?? userStore.userInfo?.roles?.id,
  );
  if (roleId !== 1) return false;
  if (Number(data.value?.delivery_method) !== 0) return false;
  return Number(data.value?.express_no_id) > 0;
});

const [TraceDrawer, traceDrawerApi] = useVbenDrawer({
  connectedComponent: OrderTraceDrawer,
});

const [PercentAdjustDrawer, percentAdjustDrawerApi] = useVbenDrawer({
  connectedComponent: OrderPricePercentAdjustDrawer,
});

/** 详情内「查看物流动态」：独立弹窗只拉物流接口 */
const [LogisticsModalComp, logisticsModalApi] = useVbenModal({
  connectedComponent: LogisticsModal,
});

const priceAdjustMeta = ref({
  scope: 'sale_only' as 'both' | 'sale_only',
  quickOptions: [] as QuickDiscountOption[],
});

const priceDiscountLabel = computed(() =>
  formatPriceDiscountLabel(Number(data.value?.price_discount ?? 100)),
);

const canPercentAdjust = computed(() => {
  return (
    Number(data.value?.is_pay) !== 1 &&
    Number(data.value?.store?.enable_order_price_percent_adjust) === 1
  );
});

async function reloadOrder() {
  if (!data.value?.id) return;
  data.value = await getOrderInfo(data.value.id);
}

async function openOrderPercentAdjust() {
  await reloadOrder();
  const discount = Number(data.value?.price_discount ?? 100);
  percentAdjustDrawerApi.setData({
    stage: 'post_order',
    priceDiscount: discount,
    price_discount: discount,
    productOrderId: data.value.id,
    quickOptions: normalizeQuickOptions(priceAdjustMeta.value.quickOptions),
    onSuccess: reloadOrder,
  });
  percentAdjustDrawerApi.open();
}

async function clearOrderPriceDiscount() {
  if (!data.value?.id) return;
  await adjustOrderPercent({
    product_order_id: data.value.id,
    price_discount: 100,
  });
  await reloadOrder();
}

async function loadPriceAdjustMeta() {
  const cfg = await getOrderPriceAdjustConfig();
  priceAdjustMeta.value = {
    scope: cfg?.order_price_adjust_scope === 'both' ? 'both' : 'sale_only',
    quickOptions: normalizeQuickOptions(cfg?.order_discount_quick_options),
  };
}

loadPriceAdjustMeta();

function openOrderTrace() {
  if (!data.value?.id) {
    return;
  }
  traceDrawerApi.setData({
    scene: 'product',
    order_id: data.value.id,
    order_no: data.value.order_no,
  });
  traceDrawerApi.open();
}

/**
 * 确认后触发后端重新结算：作废残缺分账并按规则重建入账，避免重复加钱
 */
function handleRetrySettle() {
  if (!data.value?.id || retrySettling.value) {
    return;
  }
  AntdModal.confirm({
    title: '重新结算',
    content: `确认为订单 ${data.value.order_no} 重新结算分账？将作废旧分账后按当前规则重建，已完整的订单不会重复加账。`,
    okText: '确认',
    cancelText: '取消',
    onOk: async () => {
      retrySettling.value = true;
      try {
        const res = await retrySettleApi({ order_id: Number(data.value.id) });
        message.success(res?.message || '重新结算成功');
        await reloadOrder();
      } finally {
        retrySettling.value = false;
      }
    },
  });
}

const [Modal, modalApi] = useVbenModal({
  fullscreenButton: false,
  draggable: true,
  onCancel() {
    modalApi.close();
  },
  onConfirm: async () => {
    modalApi.close();
  },
  onOpenChange(isOpen: boolean) {
    gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
    if (isOpen) {
      const modalData = modalApi.getData<Record<string, any>>() || {};
      const { values, id, onShipPackage: shipFn } = modalData;
      // 列表传入：按 warehouse_id 打开发货弹窗（平台包=0）
      onShipPackage.value = typeof shipFn === 'function' ? shipFn : null;
      if (id) {
        getOrderInfo(id).then((res) => {
          data.value = res;
          deliveryMethod.value = data.value.delivery_method;
          getExpressDetail();
        });
      }
      if (values) {
        data.value = values;
        deliveryMethod.value = data.value.delivery_method;
        getExpressDetail();
      }
    } else {
      onShipPackage.value = null;
    }
  },
});

async function getExpressDetail() {
  expressDetail.value = await expressDetailByOrderId({
    order_id: data.value.id,
  });
}

/**
 * 多包裹：优先物流接口 packages（门店角色已按开关抹仓名），
 * 避免订单详情未抹名数据盖过物流结果。
 */
const packageTabs = computed(() => {
  const fromExpress = Array.isArray((expressDetail.value as any)?.packages)
    ? (expressDetail.value as any).packages
    : [];
  if (fromExpress.length) return fromExpress;
  const fromOrder = Array.isArray(data.value?.packages) ? data.value.packages : [];
  return fromOrder;
});
const activePkg = ref('0');
/** 详情内「发本包」回调（由列表传入时仅平台包裹可发） */
const onShipPackage = ref<null | ((warehouseId: number) => void)>(null);

/**
 * Tab 文案：有仓名才拼括号；空串不兜底「平台/仓」
 */
function packageTabLabel(pkg: Record<string, any>, idx: number): string {
  const no = pkg.package_no || idx + 1;
  const name = String(pkg.warehouse_name || '').trim();
  return name ? `包裹${no}（${name}）` : `包裹${no}`;
}

/**
 * 收件人姓名脱敏：保留首字，其余用 *（与物流动态弹窗一致）
 */
function maskExpressName(name: unknown): string {
  const str = String(name || '').trim();
  if (!str) {
    return '-';
  }
  if (str.length === 1) {
    return `${str}*`;
  }
  return str.slice(0, 1) + '*'.repeat(str.length - 1);
}

/**
 * 打开独立物流动态弹窗（完整轨迹）
 */
function openLogisticsModal() {
  if (!data.value?.id) return;
  logisticsModalApi.setData({ order_id: data.value.id });
  logisticsModalApi.open();
}

/**
 * 超管手动同步历史运单到分包裹表，成功后刷新详情与物流
 */
async function syncLegacyShipment() {
  if (!data.value?.id || syncingLegacy.value) return;
  syncingLegacy.value = true;
  try {
    const res = await syncLegacyShipmentApi(Number(data.value.id));
    message.success(res?.message || '同步成功');
    await reloadOrder();
    deliveryMethod.value = data.value?.delivery_method;
    await getExpressDetail();
  } finally {
    syncingLegacy.value = false;
  }
}

const orderTypeMap = {
  1: '处方订单',
  2: '预约购药订单',
  3: '商城处方订单',
};

const prescriptionStatusMap: Record<number, string> = {
  0: '待审核',
  1: '已审核',
  2: '已驳回',
  3: '已过期',
};

const showPrescriptionStatus = computed(() => {
  const row = data.value;
  if (!row?.p_id || row.order_type === 2 || row.order_type === 3) {
    return false;
  }
  return row.prescription?.status != null;
});

function prescriptionStatusText() {
  const status = data.value?.prescription?.status;
  return prescriptionStatusMap[Number(status)] ?? '未知';
}

function prescriptionStatusColor() {
  const status = Number(data.value?.prescription?.status);
  if (status === 1) return 'green';
  if (status === 2) return 'red';
  if (status === 0) return 'orange';
  return 'default';
}
</script>
<template>
  <Modal class="h-[80%] w-[80%]" title="订单详情">
    <div v-if="data" class="flex flex-col gap-4">
      <Space>
        <Button type="primary" size="small" @click="openOrderTrace">
          查看溯源
        </Button>
        <Button
          v-if="canRetrySettle"
          size="small"
          :loading="retrySettling"
          @click="handleRetrySettle"
        >
          重新结算
        </Button>
      </Space>
      <h3 class="mt-4">订单信息</h3>
      <Descriptions
        :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
        bordered
        class="mt-4"
      >
        <Descriptions.Item label="订单号">
          {{ data.order_no }}
        </Descriptions.Item>
        <Descriptions.Item label="订单类型">
          {{ orderTypeMap[data.order_type] || '其他' }}
        </Descriptions.Item>
        <Descriptions.Item label="总支付价格">
          {{ data.total_pay_price }} 元
        </Descriptions.Item>
        <Descriptions.Item label="物品总价">
          药品：
          <Button
            v-if="canPercentAdjust"
            type="link"
            class="!p-0"
            @click="openOrderPercentAdjust"
          >
            {{ data.items_price }} 元
          </Button>
          <template v-else>{{ data.items_price }} 元</template>
          ， 加工费：{{ data.process_price }} 元
        </Descriptions.Item>
        <Descriptions.Item v-if="priceDiscountLabel" label="价格浮动">
          {{ priceDiscountLabel }}（{{ data.price_discount }}%）
          <Button
            v-if="canPercentAdjust && Number(data.price_discount) !== 100"
            type="link"
            size="small"
            @click="clearOrderPriceDiscount"
          >
            清除浮动
          </Button>
        </Descriptions.Item>
        <Descriptions.Item label="供货价">
          {{ data.market_price }} 元
        </Descriptions.Item>
        <Descriptions.Item label="运费">
          {{ data.trans_expenses }} 元
        </Descriptions.Item>
        <Descriptions.Item label="是否免邮">
          {{ data.free_ship === 0 ? '是' : '否' }}
        </Descriptions.Item>
        <Descriptions.Item label="状态">
          <Tag v-if="data.status === 0" color="red">待支付</Tag>
          <Tag v-else-if="data.status === 1" color="orange">待发货</Tag>
          <Tag v-else-if="data.status === 2" color="blue">待收货</Tag>
          <Tag v-else-if="data.status === 3" color="purple">待评价</Tag>
          <Tag v-else-if="data.status === 4" color="green">已退款</Tag>
          <Tag v-else-if="data.status === 5" color="pink">退款中</Tag>
          <Tag v-else-if="data.status === 6" color="cyan">已收货</Tag>
          <Tag v-else-if="data.status === 7" color="green">确认收货</Tag>
          <Tag v-else-if="data.status === 8" color="#B22222">拒绝退款</Tag>
          <Tag v-else-if="data.status === 9" color="gray">已取消</Tag>
          <Tag
            v-if="data.is_proxy_pay || Number(data.pay_user_type) === 2"
            color="magenta"
            class="ml-1"
          >
            代支付
          </Tag>
        </Descriptions.Item>
        <Descriptions.Item
          v-if="data.is_proxy_pay || Number(data.pay_user_type) === 2"
          label="付款方式"
        >
          医生代支付
        </Descriptions.Item>
        <Descriptions.Item label="配送方式">
          {{ deliveryMethod === 0 ? '快递到家' : '药店自提' }}
        </Descriptions.Item>
        <Descriptions.Item label="患者">{{ data.patient }}</Descriptions.Item>
        <Descriptions.Item label="医生">
          {{ data.doctor.name }}
        </Descriptions.Item>
        <Descriptions.Item label="处方来源">
          {{ data.store.name }}
        </Descriptions.Item>
        <Descriptions.Item label="订单来源">
          <Tag v-if="data.is_online === 1" color="blue">在线问诊</Tag>
          <Tag v-else-if="data.is_online === 2" color="green">在线复诊</Tag>
          <Tag v-else color="default">线下就诊</Tag>
        </Descriptions.Item>
        <Descriptions.Item label="处方类型">
          <Tag v-if="data.prescription_type === 1" color="orange">中药</Tag>
          <Tag v-else-if="data.prescription_type === 2" color="blue">西药</Tag>
          <Tag v-else-if="data.prescription_type === 3" color="purple">保健食品</Tag>
          <Tag v-else-if="data.prescription_type === 5" color="pink">产品服务包</Tag>
          <Tag v-else-if="data.prescription_type === 6" color="cyan">非药品</Tag>
          <Tag v-else-if="data.prescription_type === 7" color="geekblue">医疗器械</Tag>
          <Tag v-else>其他</Tag>
        </Descriptions.Item>
        <Descriptions.Item v-if="showPrescriptionStatus" label="处方状态">
          <Tag :color="prescriptionStatusColor()">
            {{ prescriptionStatusText() }}
          </Tag>
        </Descriptions.Item>
      </Descriptions>

      <div class="mt-4">
        <h3>{{ deliveryMethod === 0 ? '收货人' : '就诊人' }}信息</h3>
        <Descriptions
          :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
          bordered
          class="mt-4"
        >
          <Descriptions.Item
            :label="deliveryMethod === 0 ? '收货人' : '就诊人'"
          >
            <span v-if="deliveryMethod === 0">{{ data.address?.name }}</span>
            <span v-else>
              {{
                data.express_name || data.patient?.name || data.cancel_remark
              }}
            </span>
          </Descriptions.Item>
          <Descriptions.Item label="联系电话">
            <SensitiveText
              :record="data.address"
              field="mobile"
              :fallback="{ record: data, field: 'patient_mobile' }"
            />
          </Descriptions.Item>
          <Descriptions.Item v-if="deliveryMethod === 0" label="配送地址">
            {{
              `${data.address?.province || ''} ${data.address?.region || ''} ${data.address?.detail_address || ''}`
            }}
          </Descriptions.Item>
          <Descriptions.Item v-else label="自提地址">
            {{ `${data.store?.position || ''} ` }}
          </Descriptions.Item>
          <Descriptions.Item label="发货备注">
            {{ data.cancel_remark || '无' }}
          </Descriptions.Item>
        </Descriptions>
      </div>
      <div class="mt-4">
        <h3>订单商品</h3>
        <div v-if="data.prescription_type === 1">
          <span class="mb-3 block font-medium">药品明细</span>
          <div class="flex flex-wrap gap-3">
            <div
              v-for="(item, index) in data.product_order_items"
              :key="index"
              class="tcm-detail-chip w-[220px] max-w-full flex-shrink-0 rounded-lg border border-gray-200 bg-gray-50 p-3 text-sm dark:border-gray-600 dark:bg-gray-900"
            >
              <div class="font-medium">
                【{{ item.drug?.drug_number }}】{{ item.drug_name }}
              </div>
              <div class="mt-1 text-gray-600 dark:text-gray-400">
                数量：*{{ item.number * (item.dosage > 0 ? item.dosage : 1) }}
              </div>
              <div class="mt-1 text-gray-600 dark:text-gray-400">
                供货价：{{
                  item.buy_price != null && item.buy_price !== ''
                    ? `${item.buy_price} 元/${item.drug?.unit?.name || item.unit?.name || 'g'}`
                    : '—'
                }}
              </div>
              <div class="mt-1 text-gray-600 dark:text-gray-400">
                售价：{{
                  item.buy_price != null && item.buy_price !== ''
                    ? `${item.price} 元/${item.drug?.unit?.name || item.unit?.name || 'g'}`
                    : '—'
                }}
              </div>
            </div>
          </div>
        </div>
        <Card
          v-for="(item, index) in data.product_order_items"
          v-else
          :key="index"
          class="mb-4 mt-5"
        >
          <div class="flex items-center space-x-4">
            <div
              class="mr-6 h-32 w-32 overflow-hidden rounded-lg bg-gray-200 dark:bg-gray-800"
            >
              <Image
                :src="item.drug_image || '/img/empty.png'"
                alt="/img/empty.png"
                height="100%"
                width="100%"
              />
            </div>
            <div>
              <h4>{{ item.drug_name }}</h4>
              <p>规格: {{ item.drug.specification || item.drug?.unit?.name || 'g' }}</p>
              <p>数量: {{ item.number }}</p>
              <p>单价: {{ item.price }} 元</p>
              <p>
                厂家:
                {{
                  item.drug
                    ? item.drug.source_info != null
                      ? item.drug.source_info.name
                      : item.drug.source
                    : '暂无'
                }}
              </p>
              <!--              <p>总价: {{ item.total_price }} 元</p>-->
            </div>
          </div>
        </Card>
      </div>
      <div class="mt-4" v-if="data.order_type !== 2 && data.order_type !== 3 && data.prescription.content">
        <h3>处方信息</h3>
        <Descriptions
          :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
          bordered
          class="mt-4"
        >
          <Descriptions.Item label="处方编号">
            {{ data.prescription.content.prescription_no }}
          </Descriptions.Item>
          <Descriptions.Item label="诊断">
            {{ data.prescription.content.clinical_diagnose }}
          </Descriptions.Item>
          <Descriptions.Item label="医嘱">
            {{ formatDoctorOrderText(data.prescription) }}
          </Descriptions.Item>
          <Descriptions.Item label="开药医生">
            {{ data.prescription.content.doctor.name }}
          </Descriptions.Item>
          <Descriptions.Item label="科室">
            {{ data.prescription.content.doctor.depart.name }}
          </Descriptions.Item>
          <Descriptions.Item label="职称">
            {{ data.prescription.content.doctor.title.name }}
          </Descriptions.Item>
        </Descriptions>
      </div>
      <div v-if="deliveryMethod === 0" class="mt-4">
        <div class="flex items-center justify-between">
          <h3 class="mb-0">物流信息</h3>
          <Space>
            <Button
              v-if="canSyncLegacyShipment"
              type="link"
              size="small"
              :loading="syncingLegacy"
              @click="syncLegacyShipment"
            >
              同步物流包裹
            </Button>
            <Button type="link" size="small" @click="openLogisticsModal">
              查看物流动态
            </Button>
          </Space>
        </div>
        <!-- 详情内仅保留包裹发货状态；完整轨迹进独立「物流动态」弹窗 -->
        <Tabs
          v-if="packageTabs.length"
          v-model:active-key="activePkg"
          type="card"
          class="mt-4"
        >
          <Tabs.TabPane
            v-for="(pkg, idx) in packageTabs"
            :key="String(idx)"
            :tab="packageTabLabel(pkg, idx)"
          >
            <div
              class="mb-3 flex justify-end"
              v-if="Number(pkg.is_send) === 0 && Number(pkg.warehouse_id) === 0 && onShipPackage"
            >
              <Button
                type="primary"
                size="small"
                @click="onShipPackage(Number(pkg.warehouse_id) || 0)"
              >
                发本包裹
              </Button>
            </div>
            <template v-if="Number(pkg.is_send) === 1 && pkg.express">
              <Descriptions
                :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
                bordered
              >
                <Descriptions.Item label="收件人">
                  {{
                    maskExpressName(
                      (expressDetail as any).express_name || data?.express_name,
                    )
                  }}
                </Descriptions.Item>
                <Descriptions.Item label="手机号">
                  <SensitiveText :record="pkg.express" field="mobile" />
                </Descriptions.Item>
                <Descriptions.Item label="物流公司">
                  {{ pkg.express.express_company_name || '-' }}
                </Descriptions.Item>
                <Descriptions.Item label="运单号">
                  {{ pkg.express.express_no || '-' }}
                </Descriptions.Item>
                <Descriptions.Item label="最新状态">
                  {{ pkg.express.state_txt || '-' }}
                </Descriptions.Item>
              </Descriptions>
            </template>
            <div v-else class="text-gray-400 py-2">
              本包裹尚未发货
              <span v-if="Array.isArray(pkg.items) && pkg.items.length">
                （{{ pkg.items.map((p: any) => p.drug_name || p.name).filter(Boolean).join('、') }}）
              </span>
            </div>
          </Tabs.TabPane>
        </Tabs>
        <Descriptions
          v-else
          :column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
          bordered
          class="mt-4"
        >
          <Descriptions.Item label="收件人">
            {{
              maskExpressName(
                (expressDetail as any).express_name || data?.express_name,
              )
            }}
          </Descriptions.Item>
          <Descriptions.Item label="手机号">
            <SensitiveText :record="expressDetail" field="mobile" />
          </Descriptions.Item>
          <Descriptions.Item label="物流公司">
            {{ expressDetail.express_company_name || '-' }}
          </Descriptions.Item>
          <Descriptions.Item label="运单号">
            {{ expressDetail.express_no || '-' }}
          </Descriptions.Item>
          <Descriptions.Item label="最新状态">
            {{ expressDetail.state_txt || '-' }}
          </Descriptions.Item>
        </Descriptions>
      </div>
    </div>
  </Modal>
  <TraceDrawer />
  <PercentAdjustDrawer />
  <LogisticsModalComp />
</template>

<style scoped>
.tcm-detail-chip {
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%);
}

.ant-descriptions-item-label {
  font-weight: bold;
}

.mt-4 {
  margin-top: 1rem;
}

.mb-4 {
  margin-bottom: 1rem;
}

.flex {
  display: flex;
}

.items-center {
  align-items: center;
}

.justify-between {
  justify-content: space-between;
}

.mb-0 {
  margin-bottom: 0;
}

.space-x-4 > * + * {
  margin-left: 1rem;
}
</style>
