'use client'

import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
import { useEffect, useMemo, useState } from 'react'
import type { CartItem, OrderRecord } from '@/components/providers/AppProvider'
import { useApp } from '@/components/providers/AppProvider'
import { QrCodeSvg } from '@/components/shared/QrCodeSvg'
import { backend, defaultPaymentChannel, mapBackendExpert, yuan, type BackendCheckoutPreview, type BackendConsultingRequest, type BackendDataServiceRequest, type BackendMembershipCatalog, type BackendPaymentOrder, type BackendSiteAgreement } from '@/lib/backend'
import type { Expert } from '@/types'

const typeLabel = {
  course: '课程',
  event: '活动',
  data: '数据服务',
  agent: '智能体',
  expert: '专家',
  consulting: '咨询',
  membership: '会员',
}

function paymentLabel(method: OrderRecord['paymentMethod']) {
  if (method === 'wechat') return '微信支付'
  if (method === 'alipay') return '支付宝'
  return '线下确认'
}

function isPhoneLike(value: string) {
  return /^1\d{10}$|^0\d{2,3}-?\d{7,8}$/.test(value.trim())
}

function isEmailLike(value: string) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim())
}

function isTaxNumberLike(value: string) {
  const normalized = value.trim()
  return normalized.length === 0 || /^[A-Z0-9]{15,20}$/i.test(normalized)
}

function navigateReliably(target: string, replace: (href: string) => void) {
  replace(target)
  window.setTimeout(() => {
    const current = `${window.location.pathname}${window.location.search}`
    if (current !== target) window.location.assign(target)
  }, 800)
}

type PaymentPanelState = {
  paymentNo: string
  orderId: string
  codeUrl: string
  expiresAt: string
  status: 'waiting' | 'checking' | 'expired' | 'failed'
}

export function CheckoutPageClient() {
  const router = useRouter()
  const searchParams = useSearchParams()
  const { hydrated, user, token, cartItems, previewCheckout, createOrder, clearCart, refreshAccount } = useApp()
  const [checkoutStep, setCheckoutStep] = useState<0 | 1>(0)
  const [needInvoice, setNeedInvoice] = useState(false)
  const [invoiceTitle, setInvoiceTitle] = useState('')
  const [taxNumber, setTaxNumber] = useState('')
  const [invoiceEmail, setInvoiceEmail] = useState('')
  const [contact, setContact] = useState('')
  const [couponCode, setCouponCode] = useState('')
  const [acceptedTerms, setAcceptedTerms] = useState(false)
  const [showTerms, setShowTerms] = useState(false)
  const [checkoutError, setCheckoutError] = useState('')
  const [preview, setPreview] = useState<BackendCheckoutPreview | null>(null)
  const [membershipCatalog, setMembershipCatalog] = useState<BackendMembershipCatalog | null>(null)
  const [membershipCatalogLoading, setMembershipCatalogLoading] = useState(false)
  const [membershipCatalogError, setMembershipCatalogError] = useState('')
  const [previewError, setPreviewError] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [paymentPanel, setPaymentPanel] = useState<PaymentPanelState | null>(null)
  const [closingPayment, setClosingPayment] = useState(false)
  const [submittedOrderId, setSubmittedOrderId] = useState('')
  const [directExpertData, setDirectExpertData] = useState<Expert | null>(null)
  const [dataServiceRequest, setDataServiceRequest] = useState<BackendDataServiceRequest | null>(null)
  const [consultingRequest, setConsultingRequest] = useState<BackendConsultingRequest | null>(null)
  const [purchaseAgreement, setPurchaseAgreement] = useState<BackendSiteAgreement | null>(null)
  const expertSlug = searchParams.get('expert') || ''
  const expertBookingId = searchParams.get('bookingId') || ''
  const dataServiceRequestId = searchParams.get('dataServiceRequestId') || ''
  const consultingRequestId = searchParams.get('consultingRequestId') || ''

  useEffect(() => {
    if (searchParams.get('type') !== 'membership') {
      setMembershipCatalog(null)
      setMembershipCatalogError('')
      setMembershipCatalogLoading(false)
      return
    }
    let cancelled = false
    setMembershipCatalogLoading(true)
    setMembershipCatalogError('')
    void backend.membershipCatalog()
      .then((catalog) => {
        if (cancelled) return
        setMembershipCatalog(catalog)
        setMembershipCatalogError('')
      })
      .catch((error) => {
        if (cancelled) return
        setMembershipCatalog(null)
        setMembershipCatalogError(error instanceof Error ? error.message : '会员方案加载失败，请稍后重试。')
      })
      .finally(() => {
        if (!cancelled) setMembershipCatalogLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [searchParams])

  useEffect(() => {
    void backend.siteAgreement('purchase-terms').then(setPurchaseAgreement).catch(() => setPurchaseAgreement(null))
  }, [])

  const directMembership = useMemo<CartItem | null>(() => {
    if (searchParams.get('type') !== 'membership') return null
    const planKey = searchParams.get('plan')
    const normalizedPlan = planKey === 'pro' ? 'junior' : planKey === 'max' ? 'senior' : planKey
    if (!membershipCatalog) return null
    const backendPlan = membershipCatalog?.plans.find((item) => item.level === normalizedPlan)
    if (!backendPlan) return null
    const plan = {
      id: backendPlan.productId,
      title: backendPlan.name,
      monthlyPrice: yuan(backendPlan.monthlyPriceAmount),
      yearlyPrice: yuan(backendPlan.yearlyPriceAmount),
      meta: backendPlan.groups.flatMap((group) => group.items).slice(0, 3).join(' · '),
      level: backendPlan.level === 'senior' ? 2 : 1,
    }
    const cycle = searchParams.get('cycle') === 'yearly' ? 'yearly' : 'monthly'
    const isUpgrade = searchParams.get('change') === 'upgrade' && plan.level === 2
    const price = cycle === 'yearly' ? plan.yearlyPrice : plan.monthlyPrice
    return {
      id: plan.id,
      type: 'membership',
      title: `${plan.title}${isUpgrade ? '升级' : ''}（${cycle === 'yearly' ? '年付' : '月付'}）`,
      price,
      href: '/membership',
      meta: `${isUpgrade ? '升级补差价由系统试算' : cycle === 'yearly' ? '按年开通' : '按月开通'} · ${plan.meta}`,
      billingCycle: cycle,
    }
  }, [membershipCatalog, searchParams])
  const membershipCheckoutError = useMemo(() => {
    if (searchParams.get('type') !== 'membership') return ''
    if (membershipCatalogError) return membershipCatalogError
    if (membershipCatalogLoading) return '正在加载会员方案...'
    if (membershipCatalog && !directMembership) return '未找到可购买的会员方案，请返回会员页重新选择。'
    return ''
  }, [directMembership, membershipCatalog, membershipCatalogError, membershipCatalogLoading, searchParams])

  const directExpert = useMemo<CartItem | null>(() => {
    if (searchParams.get('type') !== 'expert') return null
    const expert = directExpertData
    if (!expert || expert.slug !== expertSlug) return null
    const date = searchParams.get('date')
    const slot = searchParams.get('slot')
    return {
      id: expert.id,
      type: 'expert',
      title: `${expert.name}专家咨询 1 小时`,
      price: expert.pricePerHour,
      href: `/experts/${expert.slug}`,
      meta: `${date && slot ? `${date} ${slot} · ` : ''}${expert.title} · ${expert.organization}`,
      expertId: expert.id,
      expertName: expert.name,
      expertBookingId,
    }
  }, [directExpertData, expertBookingId, expertSlug, searchParams])

  useEffect(() => {
    if (searchParams.get('type') !== 'expert' || !expertSlug) {
      return
    }
    let cancelled = false
    void backend.expertDetail(expertSlug)
      .then((item) => {
        if (!cancelled) setDirectExpertData(mapBackendExpert(item))
      })
      .catch(() => {
        if (!cancelled) setDirectExpertData(null)
      })
    return () => {
      cancelled = true
    }
  }, [expertSlug, searchParams])

  useEffect(() => {
    if (!token || !dataServiceRequestId) {
      queueMicrotask(() => setDataServiceRequest(null))
      return
    }
    let cancelled = false
    void backend.accountDataServiceRequest(token, dataServiceRequestId)
      .then((item) => {
        if (!cancelled) setDataServiceRequest(item)
      })
      .catch(() => {
        if (!cancelled) setDataServiceRequest(null)
      })
    return () => {
      cancelled = true
    }
  }, [dataServiceRequestId, token])

  const directDataService = useMemo<CartItem | null>(() => {
    if (!dataServiceRequestId || !dataServiceRequest || !['quoted', 'pending_payment'].includes(dataServiceRequest.status)) return null
    return {
      id: 'data-service-custom',
      type: 'data',
      title: dataServiceRequest.quotedTitle || `${dataServiceRequest.dataTopic}数据服务包`,
      price: yuan(dataServiceRequest.quotedAmount),
      href: `/account/data/${dataServiceRequest.id}`,
      meta: `${dataServiceRequest.requestNo} · ${dataServiceRequest.serviceType} · ${dataServiceRequest.expectedFormat || '按约定格式交付'}`,
      dataServiceRequestId: dataServiceRequest.id,
    }
  }, [dataServiceRequest, dataServiceRequestId])

  useEffect(() => {
    if (!token || !consultingRequestId) {
      queueMicrotask(() => setConsultingRequest(null))
      return
    }
    let cancelled = false
    void backend.accountConsultingRequests(token)
      .then((result) => {
        if (cancelled) return
        setConsultingRequest(result.items.find((item) => item.id === consultingRequestId || item.requestNo === consultingRequestId) || null)
      })
      .catch(() => {
        if (!cancelled) setConsultingRequest(null)
      })
    return () => {
      cancelled = true
    }
  }, [consultingRequestId, token])

  const directConsulting = useMemo<CartItem | null>(() => {
    if (!consultingRequestId || !consultingRequest || !['proposal_ready', 'pending_payment'].includes(consultingRequest.status)) return null
    return {
      id: 'consulting-service-custom',
      type: 'consulting',
      title: consultingRequest.quotedTitle || consultingRequest.direction || '规划咨询服务',
      price: yuan(consultingRequest.quotedAmount || 0),
      href: `/account/consulting/${consultingRequest.requestNo || consultingRequest.id}`,
      meta: `${consultingRequest.requestNo} · 规划咨询报价`,
      consultingRequestId: consultingRequest.id,
    }
  }, [consultingRequest, consultingRequestId])

  const directItem = directMembership ?? directExpert ?? directDataService ?? directConsulting
  const cartCheckoutItems = useMemo(() => cartItems.filter((item) => item.type !== 'expert'), [cartItems])
  const items = useMemo(() => directItem ? [directItem] : cartCheckoutItems, [cartCheckoutItems, directItem])
  const normalizedCoupon = couponCode.trim().toUpperCase()
  const couponTouched = couponCode.trim().length > 0
  const subtotal = preview ? yuan(preview.subtotalAmount) : items.reduce((sum, item) => sum + item.price, 0)
  const memberDiscount = preview ? yuan(preview.memberDiscountAmount) : 0
  const upgradeCredit = preview?.membershipChange?.type === 'upgrade' ? yuan(preview.membershipChange.upgradeCreditAmount) : 0
  const couponValid = !couponTouched || Boolean(preview?.couponPreview)
  const couponDiscount = preview ? yuan(preview.couponDiscountAmount) : 0
  const discount = memberDiscount + couponDiscount
  const total = preview ? yuan(preview.totalAmount) : Math.max(subtotal - discount, 0)
  const paymentMethod: OrderRecord['paymentMethod'] = total > 0 ? 'wechat' : 'offline'
  const checkoutFingerprint = useMemo(() => JSON.stringify({
    coupon: normalizedCoupon,
    items: items.map((item) => ({
      id: item.id,
      type: item.type,
      price: item.price,
      billingCycle: item.billingCycle || '',
      expertBookingId: item.expertBookingId || '',
      dataServiceRequestId: item.dataServiceRequestId || '',
      consultingRequestId: item.consultingRequestId || '',
    })),
  }), [items, normalizedCoupon])
  const checkoutRedirect = encodeURIComponent(`/checkout${searchParams.toString() ? `?${searchParams.toString()}` : ''}`)
  const loginRequiredHref = `/login-required?redirect=${checkoutRedirect}&action=checkout`
  const expertAppointment = directExpert ? {
    contactName: searchParams.get('contactName') || '未填写',
    contactPhone: searchParams.get('contactPhone') || '未填写',
    date: searchParams.get('date') || '未选择',
    slot: searchParams.get('slot') || '未选择',
    message: searchParams.get('message') || '未填写',
  } : null

  function successHref(orderId: string) {
    return `/checkout/success?orderId=${orderId}${directDataService?.dataServiceRequestId ? `&dataServiceRequestId=${encodeURIComponent(directDataService.dataServiceRequestId)}` : ''}`
  }

  useEffect(() => {
    if (!paymentPanel || !token || paymentPanel.status === 'expired' || paymentPanel.status === 'failed') return
    let cancelled = false
    const activePayment = paymentPanel
    const expiresAt = new Date(activePayment.expiresAt).getTime()
    async function poll() {
      if (cancelled) return
      if (Number.isFinite(expiresAt) && Date.now() > expiresAt) {
        try {
          const result = await backend.paymentStatus(token, activePayment.paymentNo)
          if (cancelled) return
          if (result.canRedirect || result.order.status === 'paid') {
            if (!directItem) clearCart()
            navigateReliably(successHref(result.order.id), (href) => router.replace(href))
            return
          }
        } catch {}
        setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'expired' } : current)
        return
      }
      setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'checking' } : current)
      try {
        const result = await backend.paymentStatus(token, activePayment.paymentNo)
        if (cancelled) return
        if (result.canRedirect || result.order.status === 'paid') {
          if (!directItem) clearCart()
          navigateReliably(successHref(result.order.id), (href) => router.replace(href))
          return
        }
        if (result.paymentOrder.status === 'expired') {
          setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'expired' } : current)
          return
        }
        if (result.paymentOrder.status === 'failed' || result.paymentOrder.status === 'closed') {
          setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'failed' } : current)
          return
        }
        setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'waiting' } : current)
      } catch {
        if (!cancelled) {
          setPaymentPanel((current) => current && current.paymentNo === activePayment.paymentNo ? { ...current, status: 'waiting' } : current)
        }
      }
    }
    void poll()
    const timer = window.setInterval(() => void poll(), 2000)
    return () => {
      cancelled = true
      window.clearInterval(timer)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [paymentPanel?.paymentNo, paymentPanel?.expiresAt, paymentPanel?.status, token])

  async function closePaymentPanel() {
    const current = paymentPanel
    if (!current) return
    if (!token || current.status === 'expired' || current.status === 'failed') {
      setPaymentPanel(null)
      return
    }
    setClosingPayment(true)
    try {
      const result = await backend.cancelPaymentOrder(token, current.paymentNo)
      if (result.canRedirect || result.order.status === 'paid') {
        if (!directItem) clearCart()
        navigateReliably(successHref(result.order.id), (href) => router.replace(href))
        return
      }
      setPaymentPanel(null)
      setCheckoutError('已取消本次扫码支付，订单仍保留待支付，可重新发起支付。')
    } catch (error) {
      setCheckoutError(error instanceof Error ? error.message : '支付取消失败，请稍后重试。')
    } finally {
      setClosingPayment(false)
    }
  }

  useEffect(() => {
    if (hydrated && !user) navigateReliably(loginRequiredHref, (href) => router.replace(href))
  }, [hydrated, loginRequiredHref, router, user])

  useEffect(() => {
    if (hydrated && user && !user.onboardingCompleted) navigateReliably(`/onboarding?redirect=${checkoutRedirect}`, (href) => router.replace(href))
  }, [checkoutRedirect, hydrated, router, user])

  useEffect(() => {
    setSubmittedOrderId('')
  }, [checkoutFingerprint])

  useEffect(() => {
    if (!hydrated || !user || items.length === 0) {
      const timeout = window.setTimeout(() => {
        setPreview(null)
        setPreviewError('')
      }, 0)
      return () => window.clearTimeout(timeout)
    }
    let cancelled = false
    const timeout = window.setTimeout(() => {
      void previewCheckout(items, normalizedCoupon || undefined)
        .then((result) => {
          if (cancelled) return
          setPreview(result)
          setPreviewError('')
        })
        .catch((error) => {
          if (cancelled) return
          setPreview(null)
          setPreviewError(error instanceof Error ? error.message : '优惠码或订单试算失败')
        })
    }, 240)
    return () => {
      cancelled = true
      window.clearTimeout(timeout)
    }
  }, [hydrated, items, normalizedCoupon, previewCheckout, user])

  async function handlePay() {
    if (!user) {
      router.push(loginRequiredHref)
      return
    }
    const effectiveContact = contact || user.contactPhone || user.phone || ''
    const effectiveInvoiceTitle = invoiceTitle || user.invoiceTitle || user.organization || user.name || ''
    const effectiveTaxNumber = taxNumber || user.taxNumber || ''
    const effectiveInvoiceEmail = invoiceEmail || user.invoiceEmail || user.email || ''
    const errors: string[] = []
    if (!isPhoneLike(effectiveContact)) errors.push('请填写有效联系电话')
    if (couponTouched && (!couponValid || previewError)) errors.push(previewError || '优惠码无效')
    if (needInvoice) {
      if (!effectiveInvoiceTitle.trim()) errors.push('请填写发票抬头')
      if (!isTaxNumberLike(effectiveTaxNumber)) errors.push('税号需为 15-20 位字母或数字')
      if (!isEmailLike(effectiveInvoiceEmail)) errors.push('请填写有效发票接收邮箱')
    }
    if (!acceptedTerms) errors.push('请先阅读并同意线上购买条款')
    if (errors.length > 0) {
      setCheckoutError(errors.join('；'))
      return
    }
    const invoiceRequest = needInvoice ? {
      requested: true as const,
      title: effectiveInvoiceTitle.trim(),
      taxNumber: effectiveTaxNumber.trim(),
      email: effectiveInvoiceEmail.trim(),
      remark: '结算页勾选自动申请发票',
    } : undefined
    setCheckoutError('')

    setSubmitting(true)
    setPaymentPanel(null)
    setClosingPayment(false)
    try {
      let orderIdForPayment = submittedOrderId
      if (!orderIdForPayment) {
        const order = await createOrder({
          items,
          paymentMethod,
          clearCartAfter: false,
          status: '已支付',
          couponCode: normalizedCoupon || undefined,
          expertBookingId: directExpert?.expertBookingId,
          dataServiceRequestId: directDataService?.dataServiceRequestId,
          consultingRequestId: directConsulting?.consultingRequestId,
          invoiceRequest,
          note: `联系人：${effectiveContact}；发票：${needInvoice ? `${effectiveInvoiceTitle || '未填写抬头'}，税号：${effectiveTaxNumber || '未填写'}，邮箱：${effectiveInvoiceEmail || '未填写'}` : '暂不开票'}；优惠码：${couponCode || '未使用'}；支付方式：${paymentLabel(paymentMethod)}${expertAppointment ? `；预约联系人：${expertAppointment.contactName}；预约电话：${expertAppointment.contactPhone}；预约时间：${expertAppointment.date} ${expertAppointment.slot}；咨询留言：${expertAppointment.message}` : ''}`,
        })
        if (!order) {
          setCheckoutError('订单提交失败，请稍后重试。')
          return
        }

        if (order.status !== '待支付' || total <= 0) {
          if (!directItem) clearCart()
          if (directMembership) await refreshAccount()
          navigateReliably(successHref(order.id), (href) => router.replace(href))
          return
        }
        orderIdForPayment = order.id
        setSubmittedOrderId(order.id)
      }

      const payment = await backend.createPaymentOrder(token, orderIdForPayment, defaultPaymentChannel)
      if (defaultPaymentChannel === 'dev') {
        const paid = await backend.succeedDevPayment(payment.paymentOrder.paymentNo)
        if (!directItem) clearCart()
        if (directMembership) await refreshAccount()
        navigateReliably(successHref(paid.order.id), (href) => router.replace(href))
        return
      }

      const paymentOrder = payment.paymentOrder as BackendPaymentOrder
      if (!paymentOrder.codeUrl) {
        setCheckoutError('微信支付二维码生成失败，请稍后重试。')
        return
      }
      setPaymentPanel({
        paymentNo: paymentOrder.paymentNo,
        orderId: payment.order.id,
        codeUrl: paymentOrder.codeUrl,
        expiresAt: paymentOrder.expiresAt,
        status: 'waiting',
      })
    } catch (error) {
      setCheckoutError(error instanceof Error ? error.message : '支付发起失败，请稍后重试。')
    } finally {
      setSubmitting(false)
    }
  }

  if (!hydrated || !user) {
    return (
      <section className="grid min-h-[calc(100vh-70px)] place-items-center bg-bg px-6 md:min-h-[calc(100vh-106px)]">
        <div className="text-sm font-bold text-muted">正在打开登录提醒...</div>
      </section>
    )
  }

  const defaultContact = user.contactPhone || user.phone || ''
  const defaultInvoiceTitle = user.invoiceTitle || user.organization || user.name || ''
  const defaultTaxNumber = user.taxNumber || ''
  const defaultInvoiceEmail = user.invoiceEmail || user.email || ''

  return (
    <>
      <section className="min-h-[calc(100vh-70px)] bg-bg py-8 md:min-h-[calc(100vh-106px)]">
        <div className="mx-auto max-w-[1280px] px-6 lg:pr-[436px]">
          <div className="mb-7">
            <h1 className="text-3xl font-extrabold text-ink">确认订单</h1>
            <p className="mt-2 text-sm text-muted">先核对订单内容，再补充联系人、发票和优惠码，最后提交支付。</p>
          </div>

          <div className="space-y-5">
            <div className="overflow-hidden rounded-[4px] border border-line bg-white shadow-[0_16px_45px_rgba(15,23,42,0.06)]">
              <div className="flex items-center justify-between border-b border-line px-6 py-4">
                <div className="text-lg font-extrabold text-ink">订单内容</div>
              </div>
              {items.length === 0 ? (
                <div className="px-6 py-12 text-center">
                  <div className="font-bold text-ink">{membershipCheckoutError || '暂无可结算商品'}</div>
                  <Link href="/courses" className="mt-4 inline-flex rounded-[4px] bg-brand px-5 py-2.5 text-sm font-bold text-white">去浏览服务</Link>
                </div>
              ) : (
                <div className="divide-y divide-line">
                  {items.map((item, index) => {
                    const previewItem = preview?.items[index]
                    const linePrice = previewItem ? yuan(previewItem.unitPriceAmount) : item.price
                    const listPrice = previewItem?.listPriceAmount !== undefined ? yuan(previewItem.listPriceAmount) : item.price
                    return (
                    <div key={`${item.type}-${item.id}`} className="px-6 py-5">
                      <div className="grid gap-4 md:grid-cols-[88px_1fr_auto] md:items-start">
                        <div className="grid h-12 w-20 place-items-center rounded-[4px] bg-brand-light text-xs font-extrabold text-brand">{typeLabel[item.type]}</div>
                        <div>
                          <Link href={item.href} className="font-bold text-ink hover:text-brand">{item.title}</Link>
                          {item.meta && <div className="mt-1 text-sm text-muted">{item.meta}</div>}
                          {previewItem?.pricingSource && previewItem.pricingSource !== 'list_price' && (
                            <div className="mt-2 text-xs font-bold text-green">
                              {previewItem.pricingSource === 'membership_plan' && preview?.membershipChange?.type === 'upgrade'
                                ? `升级抵扣 ¥${upgradeCredit.toLocaleString()}`
                                : previewItem.pricingSource === 'expert_discount'
                                  ? '已按有效会员权益计算专家折扣'
                                  : previewItem.pricingSource === 'manual_quote'
                                    ? previewItem.membershipDiscountNote || '按后台报价结算'
                                    : '已按会员价矩阵结算'}
                            </div>
                          )}
                          {item.type === 'expert' && expertAppointment && (
                            <div className="mt-3 space-y-1 text-xs leading-5 text-muted">
                              <div>联系人：{expertAppointment.contactName} / {expertAppointment.contactPhone}</div>
                              <div>备注：{expertAppointment.message}</div>
                            </div>
                          )}
                        </div>
                        <div className="text-right">
                          {listPrice > linePrice && <div className="text-xs font-bold text-muted line-through">¥{listPrice.toLocaleString()}</div>}
                          <div className="text-lg font-extrabold text-brand">{linePrice === 0 ? '免费' : `¥${linePrice.toLocaleString()}`}</div>
                        </div>
                      </div>
                    </div>
                    )
                  })}
                </div>
              )}
            </div>

            {checkoutStep >= 1 && (
              <div className="rounded-[4px] border border-line bg-white p-6">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div>
                    <div className="text-lg font-extrabold text-ink">其他信息</div>
                    <div className="mt-1 text-sm text-muted">联系人、发票和优惠码。</div>
                  </div>
                </div>
                <div className="mt-5 grid gap-4 md:grid-cols-2">
                  <label className="block">
                    <span className="mb-2 block text-sm font-bold text-ink">联系电话</span>
                    <input value={contact || defaultContact} onChange={(event) => setContact(event.target.value)} className="h-11 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
                    {(contact || defaultContact) && !isPhoneLike(contact || defaultContact) && (
                      <span className="mt-2 block text-xs font-bold text-[#b45309]">请输入手机号或固定电话。</span>
                    )}
                  </label>
                  <label className="block">
                    <span className="mb-2 block text-sm font-bold text-ink">优惠码</span>
                    <input value={couponCode} onChange={(event) => setCouponCode(event.target.value)} placeholder="输入后台配置的优惠码" className="h-11 w-full rounded-[4px] border border-line px-3 text-sm uppercase outline-none focus:border-brand" />
                    {couponTouched && (
                      <span className={`mt-2 block text-xs font-bold ${couponValid && !previewError ? 'text-green' : 'text-[#b45309]'}`}>
                        {couponValid && !previewError ? `已应用：减免 ¥${couponDiscount.toLocaleString()}，剩余 ${preview?.couponPreview?.remainingQuantity ?? '-'} 张` : previewError || '优惠码无效，请检查后重试。'}
                      </span>
                    )}
                  </label>
                </div>
                <div className="mt-5 border-t border-line pt-5">
                  <button
                    type="button"
                    onClick={() => setNeedInvoice((current) => !current)}
                    className="text-sm font-extrabold text-brand hover:text-brand-dark"
                  >
                    {needInvoice ? '暂不填写发票信息' : '填写发票信息'}
                  </button>
                  <p className="mt-2 text-xs leading-5 text-muted">支付完成后将自动提交普通电子发票申请；如暂不填写，后续仍可在订单详情中申请。</p>
                  <div className={`overflow-hidden transition-all duration-300 ${needInvoice ? 'mt-4 max-h-[320px] opacity-100' : 'max-h-0 opacity-0'}`}>
                    <div className="grid gap-4 bg-bg p-5 md:grid-cols-2">
                      <label className="block">
                        <span className="mb-2 block text-sm font-bold text-ink">发票抬头</span>
                        <input value={invoiceTitle || defaultInvoiceTitle} onChange={(event) => setInvoiceTitle(event.target.value)} className="h-11 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
                      </label>
                      <label className="block">
                        <span className="mb-2 block text-sm font-bold text-ink">纳税人识别号</span>
                        <input value={taxNumber || defaultTaxNumber} onChange={(event) => setTaxNumber(event.target.value)} placeholder="选填" className="h-11 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
                        {(taxNumber || defaultTaxNumber) && !isTaxNumberLike(taxNumber || defaultTaxNumber) && (
                          <span className="mt-2 block text-xs font-bold text-[#b45309]">税号需为 15-20 位字母或数字。</span>
                        )}
                      </label>
                      <label className="block md:col-span-2">
                        <span className="mb-2 block text-sm font-bold text-ink">接收邮箱</span>
                        <input value={invoiceEmail || defaultInvoiceEmail} onChange={(event) => setInvoiceEmail(event.target.value)} placeholder="用于接收电子发票" className="h-11 w-full rounded-[4px] border border-line px-3 text-sm outline-none focus:border-brand" />
                        {(invoiceEmail || defaultInvoiceEmail) && !isEmailLike(invoiceEmail || defaultInvoiceEmail) && (
                          <span className="mt-2 block text-xs font-bold text-[#b45309]">请输入有效邮箱地址。</span>
                        )}
                      </label>
                    </div>
                  </div>
                </div>
                {checkoutError && (
                  <div className="mt-5 rounded-[4px] bg-bg px-4 py-3 text-sm font-bold text-[#b45309]">
                    {checkoutError}
                  </div>
                )}
              </div>
            )}

          </div>

          <aside className="mt-6 h-fit rounded-[4px] border border-line bg-white p-6 lg:fixed lg:right-[max(1.5rem,calc((100vw-1280px)/2+1.5rem))] lg:top-32 lg:mt-0 lg:w-[380px]">
            <div className="text-lg font-extrabold text-ink">应付金额</div>
            <div className="mt-5 space-y-3 text-sm">
              <div className="flex justify-between text-muted">
                <span>商品小计</span>
                <span>¥{subtotal.toLocaleString()}</span>
              </div>
              <div className="flex justify-between text-muted">
                <span>会员折扣</span>
                <span>- ¥{memberDiscount.toLocaleString()}</span>
              </div>
              {upgradeCredit > 0 && (
                <div className="flex justify-between text-green">
                  <span>会员升级抵扣</span>
                  <span>已抵扣 ¥{upgradeCredit.toLocaleString()}</span>
                </div>
              )}
              <div className="flex justify-between text-muted">
                <span>优惠码</span>
                <span>- ¥{couponDiscount.toLocaleString()}</span>
              </div>
              <div className="border-t border-line pt-4">
                <div className="flex items-baseline justify-between">
                  <span className="font-bold text-ink">应付总额</span>
                  <span className="text-3xl font-extrabold text-brand">¥{total.toLocaleString()}</span>
                </div>
              </div>
            </div>
            {checkoutStep >= 1 && (
              <label className="mt-5 flex items-start gap-2 text-xs font-bold leading-6 text-muted">
                <input type="checkbox" checked={acceptedTerms} onChange={(event) => setAcceptedTerms(event.target.checked)} className="mt-1 accent-brand" />
                <span>
                  我同意
                  <button type="button" onClick={() => setShowTerms(true)} className="mx-1 font-extrabold text-brand hover:text-brand-dark">
                    《大连市大数据研究院线上购买条款》
                  </button>
                </span>
              </label>
            )}
            <button
              type="button"
              onClick={() => {
                if (checkoutStep === 0) {
                  setCheckoutStep(1)
                  return
                }
                void handlePay()
              }}
              disabled={submitting || items.length === 0 || (checkoutStep === 1 && !acceptedTerms) || Boolean(paymentPanel && paymentPanel.status !== 'expired' && paymentPanel.status !== 'failed')}
              className="mt-6 w-full rounded-[4px] bg-brand py-3 text-sm font-extrabold text-white hover:bg-brand-dark disabled:cursor-not-allowed disabled:bg-line-dark"
            >
              {submitting ? '提交中...' : checkoutStep === 0 ? '下一步' : paymentPanel?.status === 'expired' || paymentPanel?.status === 'failed' ? '重新发起支付' : total > 0 ? `确认支付 ¥${total.toLocaleString()}` : '确认提交'}
            </button>
          </aside>
        </div>
      </section>
      {paymentPanel && (
        <div className="fixed inset-0 z-[90] grid place-items-center bg-ink/45 px-5">
          <div className="w-full max-w-[420px] rounded-[6px] bg-white p-6 shadow-[0_28px_90px_rgba(15,23,42,0.28)]">
            <div className="flex items-start justify-between gap-4 border-b border-line pb-4">
              <div>
                <h2 className="text-xl font-extrabold text-ink">
                  {paymentPanel.status === 'expired' ? '订单支付超时' : paymentPanel.status === 'failed' ? '支付未完成' : '微信扫码支付'}
                </h2>
                <div className="mt-1 text-xs font-bold text-muted">支付单号：{paymentPanel.paymentNo}</div>
              </div>
              <button
                type="button"
                onClick={() => void closePaymentPanel()}
                disabled={closingPayment}
                className="grid h-9 w-9 place-items-center rounded-full border border-line text-lg font-extrabold text-muted hover:border-brand hover:text-brand disabled:opacity-50"
                aria-label="关闭支付弹窗"
              >
                ×
              </button>
            </div>
            <div className="mt-6 grid place-items-center">
              {paymentPanel.status === 'expired' || paymentPanel.status === 'failed' ? (
                <div className="grid h-56 w-56 place-items-center rounded-[4px] bg-bg px-6 text-center">
                  <div>
                    <div className="text-lg font-extrabold text-ink">{paymentPanel.status === 'expired' ? '二维码已过期' : '支付单已关闭'}</div>
                    <div className="mt-2 text-sm font-bold leading-6 text-muted">订单仍为待支付状态，可以重新发起支付。</div>
                  </div>
                </div>
              ) : (
                <div className="rounded-[4px] bg-bg p-5">
                  <QrCodeSvg value={paymentPanel.codeUrl} label="微信支付二维码" className="h-56 w-56" />
                </div>
              )}
            </div>
            <div className="mt-5 text-center text-sm font-bold leading-6 text-muted">
              {paymentPanel.status === 'checking' && '正在确认支付结果，完成后会自动跳转。'}
              {paymentPanel.status === 'waiting' && '请使用微信扫码完成支付。关闭弹窗会取消本次支付单。'}
              {paymentPanel.status === 'expired' && '长时间未完成扫码支付，本次支付单已超时。'}
              {paymentPanel.status === 'failed' && '本次支付未完成，请重新发起支付。'}
            </div>
            {(paymentPanel.status === 'expired' || paymentPanel.status === 'failed') && (
              <button
                type="button"
                onClick={() => setPaymentPanel(null)}
                className="mt-5 h-11 w-full rounded-[4px] bg-brand text-sm font-extrabold text-white hover:bg-brand-dark"
              >
                返回订单重新支付
              </button>
            )}
            {closingPayment && <div className="mt-4 text-center text-xs font-bold text-muted">正在取消本次支付...</div>}
          </div>
        </div>
      )}
      {showTerms && (
        <div className="fixed inset-0 z-[80] grid place-items-center bg-ink/36 px-6">
          <div className="w-full max-w-[720px] rounded-[4px] bg-white p-6 shadow-[0_24px_80px_rgba(15,23,42,0.22)]">
            <div className="flex items-start justify-between gap-4 border-b border-line pb-4">
              <h2 className="text-2xl font-extrabold text-ink">{purchaseAgreement?.title || '大连市大数据研究院线上购买条款'}</h2>
              <button type="button" onClick={() => setShowTerms(false)} className="text-sm font-extrabold text-muted hover:text-brand">关闭</button>
            </div>
            <div className="mt-5 max-h-[56vh] overflow-y-auto whitespace-pre-line pr-2 text-sm leading-7 text-muted">
              {purchaseAgreement?.content || [
                '一、购买人应在提交支付前确认商品名称、金额、联系人、发票信息和服务内容准确无误。',
                '二、课程、活动、数据服务、智能体、专家预约和会员权益等服务的开通方式，以订单页面和个人中心展示为准。',
                '三、数字内容、资料下载、会员权益等虚拟服务一经开通，除法律法规另有规定或平台确认服务无法履行外，订单按实际履约记录处理。',
                '四、专家预约、活动报名等需要确认时间或席位的服务，平台会根据订单信息生成记录；用户应保持联系方式可用。',
                '五、如需发票，应在结算页填写准确抬头、税号和接收邮箱。发票信息错误造成的重开或延迟，由购买人配合处理。',
                '六、平台将根据隐私政策保护订单与联系信息，仅用于交易履约、服务沟通、发票处理和必要的合规留存。',
              ].join('\n')}
            </div>
            <button type="button" onClick={() => setShowTerms(false)} className="mt-6 h-10 rounded-[4px] bg-brand px-5 text-sm font-extrabold text-white">我已阅读</button>
          </div>
        </div>
      )}
    </>
  )
}
