<template>
  <div class="mx-auto max-w-screen-xl px-4 py-12">
    <a-typography-title :level="1" class="!mb-2">创建应用</a-typography-title>
    <a-typography-paragraph class="!text-gray-600 !mb-8">
      选择产品与时长，填写租户与绑定信息，生成订单并支付后自动开通产品并分配管理账号。
    </a-typography-paragraph>

    <a-alert
      class="mb-6"
      type="info"
      show-icon
      message="当前页面已打通前端流程与接口对接点；如你的后端返回字段不同（订单号/二维码/账号信息），我可以按实际接口再调整。"
    />

    <a-steps :current="step" class="mb-8">
      <a-step title="选择产品" />
      <a-step title="选择时长" />
      <a-step title="填写信息" />
      <a-step title="生成订单" />
      <a-step title="支付订单" />
      <a-step title="开通交付" />
    </a-steps>

    <a-card v-if="step === 0" title="选择产品">
      <a-row :gutter="[16, 16]">
        <a-col v-for="p in products" :key="p.code" :xs="24" :md="12" :lg="8">
          <a-card
            hoverable
            :class="selectedProduct?.code === p.code ? 'card-active' : ''"
            @click="selectProduct(p)"
          >
            <template #title>
              <div class="flex items-center justify-between gap-2">
                <span>{{ p.name }}</span>
                <a-tag v-if="p.recommend" color="green">推荐</a-tag>
              </div>
            </template>
            <a-typography-paragraph class="!text-gray-600">
              {{ p.desc }}
            </a-typography-paragraph>
            <div class="flex flex-wrap gap-2">
              <a-tag v-for="t in p.tags" :key="t">{{ t }}</a-tag>
            </div>
            <div class="mt-4 text-sm text-gray-500">
              起步价：¥{{ p.pricePerMonth }}/月
            </div>
          </a-card>
        </a-col>
      </a-row>
      <div class="mt-6 flex justify-end">
        <a-button type="primary" :disabled="!selectedProduct" @click="next()">下一步</a-button>
      </div>
    </a-card>

    <a-card v-else-if="step === 1" title="选择时长">
      <a-row :gutter="[16, 16]">
        <a-col :xs="24" :lg="14">
          <a-segmented v-model:value="durationMonths" :options="durationOptions" block />
          <div class="mt-6">
            <a-descriptions bordered size="small" :column="1">
              <a-descriptions-item label="产品">{{ selectedProduct?.name }}</a-descriptions-item>
              <a-descriptions-item label="购买时长">{{ durationMonths }} 个月</a-descriptions-item>
              <a-descriptions-item label="单价">¥{{ selectedProduct?.pricePerMonth }}/月</a-descriptions-item>
              <a-descriptions-item label="应付金额">
                <span class="text-lg font-semibold text-green-600">¥{{ priceTotal }}</span>
              </a-descriptions-item>
            </a-descriptions>
          </div>
        </a-col>
        <a-col :xs="24" :lg="10">
          <a-card title="支持加购" size="small">
            <a-list size="small" :data-source="addons">
              <template #renderItem="{ item }">
                <a-list-item>{{ item }}</a-list-item>
              </template>
            </a-list>
          </a-card>
        </a-col>
      </a-row>

      <div class="mt-6 flex justify-between">
        <a-button @click="prev()">上一步</a-button>
        <a-button type="primary" @click="next()">下一步</a-button>
      </div>
    </a-card>

    <a-card v-else-if="step === 2" title="填写租户与绑定信息">
      <a-form ref="formRef" layout="vertical" :model="form" :rules="rules" @finish="next">
        <a-row :gutter="16">
          <a-col :xs="24" :md="12">
            <a-form-item label="租户名称" name="tenantName">
              <a-input v-model:value="form.tenantName" placeholder="例如：某某科技有限公司" />
            </a-form-item>
          </a-col>
          <a-col :xs="24" :md="12">
            <a-form-item label="绑定域名" name="domain">
              <a-input v-model:value="form.domain" placeholder="例如：example.com" />
            </a-form-item>
          </a-col>
        </a-row>

        <a-row :gutter="16">
          <a-col :xs="24" :md="12">
            <a-form-item label="邮箱" name="email">
              <a-input v-model:value="form.email" placeholder="用于接收交付信息" />
            </a-form-item>
          </a-col>
          <a-col :xs="24" :md="12">
            <a-form-item label="手机号" name="phone">
              <a-input v-model:value="form.phone" placeholder="用于短信验证与管理员账号" />
            </a-form-item>
          </a-col>
        </a-row>

        <a-row :gutter="16" align="middle">
          <a-col :xs="24" :md="12">
            <a-form-item label="短信验证码" name="smsCode">
              <a-input v-model:value="form.smsCode" placeholder="请输入验证码" />
            </a-form-item>
          </a-col>
          <a-col :xs="24" :md="12" class="flex items-center">
            <a-button :disabled="smsCountdown > 0" :loading="smsSending" @click="onSendSms">
              {{ smsCountdown > 0 ? `${smsCountdown}s 后重试` : '发送验证码' }}
            </a-button>
          </a-col>
        </a-row>

        <a-alert
          class="mb-4"
          type="warning"
          show-icon
          message="短信验证码接口复用登录短信验证码（sendSmsCaptcha）。如你有专用的开通验证码接口，可替换。"
        />

        <div class="flex justify-between">
          <a-button @click="prev()">上一步</a-button>
          <a-button type="primary" html-type="submit">下一步</a-button>
        </div>
      </a-form>
    </a-card>

    <a-card v-else-if="step === 3" title="生成订单">
      <a-descriptions bordered :column="1">
        <a-descriptions-item label="产品">{{ selectedProduct?.name }}</a-descriptions-item>
        <a-descriptions-item label="购买时长">{{ durationMonths }} 个月</a-descriptions-item>
        <a-descriptions-item label="租户名称">{{ form.tenantName }}</a-descriptions-item>
        <a-descriptions-item label="绑定域名">{{ form.domain }}</a-descriptions-item>
        <a-descriptions-item label="邮箱">{{ form.email }}</a-descriptions-item>
        <a-descriptions-item label="手机号">{{ form.phone }}</a-descriptions-item>
        <a-descriptions-item label="应付金额">
          <span class="text-lg font-semibold text-green-600">¥{{ priceTotal }}</span>
        </a-descriptions-item>
      </a-descriptions>

      <a-alert
        class="mt-4"
        type="info"
        show-icon
        message="点击“生成订单”后将创建订单并请求微信 Native 支付二维码。"
      />

      <div class="mt-6 flex justify-between">
        <a-button @click="prev()">上一步</a-button>
        <a-button type="primary" :loading="creatingOrder" @click="createOrderAndPay">生成订单</a-button>
      </div>
    </a-card>

    <a-card v-else-if="step === 4" title="支付订单">
      <a-row :gutter="[24, 24]">
        <a-col :xs="24" :lg="12">
          <a-descriptions bordered size="small" :column="1">
            <a-descriptions-item label="订单号">{{ order?.orderNo || '-' }}</a-descriptions-item>
            <a-descriptions-item label="金额">¥{{ order?.payPrice || priceTotal }}</a-descriptions-item>
            <a-descriptions-item label="支付方式">微信 Native（扫码支付）</a-descriptions-item>
          </a-descriptions>

          <div class="mt-6 flex flex-wrap gap-2">
            <a-button :loading="checkingPay" @click="checkPayStatus">查询支付状态</a-button>
            <a-button @click="rebuildPayCode" :disabled="!order">重新获取二维码</a-button>
            <a-button danger @click="resetAll">取消并重来</a-button>
          </div>

          <a-alert
            class="mt-6"
            type="warning"
            show-icon
            message="支付成功后点击“查询支付状态”，确认到账后自动进入开通交付。"
          />
        </a-col>

        <a-col :xs="24" :lg="12">
          <a-card title="扫码支付" size="small">
            <div class="flex items-center justify-center py-6">
              <a-qrcode v-if="payCodeUrl" :value="payCodeUrl" :size="220" />
              <a-empty v-else description="暂无二维码" />
            </div>
          </a-card>
        </a-col>
      </a-row>
    </a-card>

    <a-card v-else-if="step === 5" title="开通交付">
      <a-result
        v-if="provisioned"
        status="success"
        title="开通成功"
        sub-title="租户已创建并完成初始化，可使用管理员账号登录后台。"
      >
        <template #extra>
          <a-space>
            <a-button type="primary" @click="navigateTo('/contact')">获取后台地址</a-button>
            <a-button @click="resetAll">再创建一个</a-button>
          </a-space>
        </template>
      </a-result>

      <a-alert
        v-else
        type="info"
        show-icon
        message="正在开通中..."
      />

      <a-divider />

      <a-descriptions bordered size="small" :column="1">
        <a-descriptions-item label="TenantId">
          {{ provisionInfo?.user?.tenantId ?? '-' }}
        </a-descriptions-item>
        <a-descriptions-item label="租户名称">{{ form.tenantName }}</a-descriptions-item>
        <a-descriptions-item label="绑定域名">{{ form.domain }}</a-descriptions-item>
        <a-descriptions-item label="管理员账号">
          {{ provisionInfo?.user?.username || form.phone }}
        </a-descriptions-item>
        <a-descriptions-item label="初始密码">
          {{ adminPasswordHint }}
        </a-descriptions-item>
        <a-descriptions-item label="Access Token">
          <a-typography-text
            v-if="provisionInfo?.access_token"
            :copyable="{ text: provisionInfo.access_token }"
          >
            点击复制
          </a-typography-text>
          <span v-else>-</span>
        </a-descriptions-item>
      </a-descriptions>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { message } from 'ant-design-vue'
import { usePageSeo } from '@/composables/usePageSeo'
import { sendSmsCaptcha } from '@/api/passport/login'
import { createWithOrder, getNativeCode, type PaymentCreateResult } from '@/api/system/payment'
import { getOrder } from '@/api/system/order'
import request from '@/utils/request'
import { SERVER_API_URL } from '@/config/setting'
import type { ApiResult } from '@/api'
import type { Order } from '@/api/system/order/model'

type Product = {
  code: string
  name: string
  desc: string
  tags: string[]
  pricePerMonth: number
  recommend?: boolean
}

usePageSeo({
  title: '创建应用 - 选品/支付/自动开通',
  description:
    '选择产品与时长，填写租户信息并短信验证，生成订单并支付后自动创建租户、初始化模块与数据并交付管理账号。',
  path: '/create-app'
})

const step = ref(0)

const products: Product[] = [
  {
    code: 'website',
    name: '企业官网',
    desc: '品牌展示与获客转化，支持模板、SEO 与可视化配置。',
    tags: ['模板', 'SEO', '多语言'],
    pricePerMonth: 199,
    recommend: true
  },
  {
    code: 'shop',
    name: '电商系统',
    desc: '商品/订单/支付/营销基础能力，插件化扩展。',
    tags: ['支付', '插件', '营销'],
    pricePerMonth: 399,
    recommend: true
  },
  {
    code: 'mp',
    name: '小程序/公众号',
    desc: '多端渠道接入与统一管理，适配内容与电商场景。',
    tags: ['多端', '渠道'],
    pricePerMonth: 299
  }
]

const selectedProduct = ref<Product | null>(null)
const durationMonths = ref(12)
const durationOptions = [
  { label: '1个月', value: 1 },
  { label: '3个月', value: 3 },
  { label: '12个月', value: 12 },
  { label: '24个月', value: 24 }
]

const addons = ['模板加购（示例）', '插件加购（示例）', '私有化交付（示例）']

const priceTotal = computed(() => {
  const base = selectedProduct.value?.pricePerMonth || 0
  return base * Number(durationMonths.value || 0)
})

const formRef = ref()
const form = reactive({
  tenantName: '',
  domain: '',
  email: '',
  phone: '',
  smsCode: ''
})

function isDomainLike(v: string) {
  const value = v.trim().toLowerCase()
  return /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/.test(value)
}

function isPhoneLike(v: string) {
  const value = v.trim()
  return /^1\d{10}$/.test(value)
}

function isSmsCodeLike(v: string) {
  const value = v.trim()
  return /^\d{4,8}$/.test(value)
}

const rules = {
  tenantName: [{ required: true, message: '请填写租户名称' }],
  domain: [
    { required: true, message: '请填写绑定域名' },
    { validator: (_: unknown, v: string) => (isDomainLike(v) ? Promise.resolve() : Promise.reject(new Error('域名格式不正确'))) }
  ],
  email: [{ required: true, type: 'email', message: '请填写正确邮箱' }],
  phone: [
    { required: true, message: '请填写手机号' },
    { validator: (_: unknown, v: string) => (isPhoneLike(v) ? Promise.resolve() : Promise.reject(new Error('手机号格式不正确'))) }
  ],
  smsCode: [
    { required: true, message: '请填写短信验证码' },
    { validator: (_: unknown, v: string) => (isSmsCodeLike(v) ? Promise.resolve() : Promise.reject(new Error('验证码格式不正确'))) }
  ]
}

const smsSending = ref(false)
const smsCountdown = ref(0)
let countdownTimer: ReturnType<typeof setInterval> | undefined

async function onSendSms() {
  if (!form.phone) {
    message.warning('请先填写手机号')
    return
  }
  smsSending.value = true
  try {
    await sendSmsCaptcha({ phone: form.phone })
    message.success('验证码已发送')
    smsCountdown.value = 60
    if (countdownTimer) clearInterval(countdownTimer)
    countdownTimer = setInterval(() => {
      smsCountdown.value -= 1
      if (smsCountdown.value <= 0) {
        smsCountdown.value = 0
        if (countdownTimer) clearInterval(countdownTimer)
        countdownTimer = undefined
      }
    }, 1000)
  } catch (e) {
    message.error(String(e))
  } finally {
    smsSending.value = false
  }
}

function selectProduct(p: Product) {
  selectedProduct.value = p
}

function next() {
  if (step.value < 5) step.value += 1
}
function prev() {
  if (step.value > 0) step.value -= 1
}

const creatingOrder = ref(false)
const order = ref<Order | null>(null)
const payCodeUrl = ref<string>('')
const payment = ref<PaymentCreateResult | null>(null)

function pickFirstString(obj: unknown, keys: string[]) {
  if (!obj || typeof obj !== 'object') return ''
  const record = obj as Record<string, unknown>
  for (const key of keys) {
    const value = record[key]
    if (typeof value === 'string' && value) return value
  }
  return ''
}

async function createOrderAndPay() {
  if (!selectedProduct.value) return
  creatingOrder.value = true
  try {
    const orderInfo: Partial<Order> & Record<string, unknown> = {
      type: 0,
      channel: 0,
      realName: form.tenantName,
      phone: form.phone,
      totalNum: durationMonths.value,
      totalPrice: String(priceTotal.value),
      payPrice: String(priceTotal.value),
      description: JSON.stringify({
        product: selectedProduct.value.code,
        months: durationMonths.value,
        tenantName: form.tenantName,
        domain: form.domain,
        email: form.email
      })
    }

    const unifiedPayload = {
      paymentChannel: 'WECHAT_NATIVE',
      paymentType: 1,
      amount: priceTotal.value,
      subject: `${selectedProduct.value.name}（${durationMonths.value}个月）`,
      description: `租户：${form.tenantName}；域名：${form.domain}`,
      goodsId: selectedProduct.value.code,
      quantity: 1,
      orderType: 0,
      buyerRemarks: orderInfo.description,
      extraParams: {
        product: selectedProduct.value.code,
        months: durationMonths.value,
        tenantName: form.tenantName,
        domain: form.domain,
        email: form.email,
        phone: form.phone
      },
      order: orderInfo
    }

    const data = await createWithOrder(unifiedPayload)
    payment.value = data || null

    const orderFromApi = (data as any)?.order || (data as any)?.orderInfo || (data as any)?.orderDTO
    order.value = {
      ...(orderFromApi || {}),
      orderId: (data as any)?.orderId ?? orderFromApi?.orderId,
      orderNo: (data as any)?.orderNo ?? orderFromApi?.orderNo,
      payPrice: (orderFromApi || {})?.payPrice ?? String(priceTotal.value)
    } as Order

    payCodeUrl.value =
      pickFirstString(data, ['codeUrl', 'url', 'payUrl', 'paymentUrl', 'qrcode']) ||
      pickFirstString(order.value, ['qrcode'])

    if (!payCodeUrl.value && order.value?.orderId) {
      await rebuildPayCode()
    }
    if (!payCodeUrl.value) {
      message.warning('后端未返回二维码地址（codeUrl/url/payUrl），请确认统一下单接口返回格式或提供支付二维码接口')
    }
    step.value = 4
  } catch (e) {
    message.error(String(e))
  } finally {
    creatingOrder.value = false
  }
}

async function rebuildPayCode() {
  if (!order.value) return
  try {
    const data = await getNativeCode(order.value)
    payCodeUrl.value = pickFirstString(data, ['codeUrl', 'url', 'payUrl', 'paymentUrl', 'qrcode']) || String(data || '')
    if (!payCodeUrl.value) {
      message.warning('后端未返回二维码地址（codeUrl/url），请确认接口返回格式')
    }
  } catch (e) {
    message.error(String(e))
  }
}

const checkingPay = ref(false)
const provisioned = ref(false)
const adminPasswordHint = '初始密码将通过短信/邮件发送（或由客服提供）'

async function checkPayStatus() {
  if (!order.value?.orderId) {
    message.warning('缺少订单ID，暂无法查询支付状态（请确认统一下单接口是否返回 orderId，或提供按 orderNo/paymentNo 查询的接口）')
    return
  }
  checkingPay.value = true
  try {
    const latest = await getOrder(order.value.orderId)
    order.value = latest
    if (Number(latest.payStatus) === 1) {
      message.success('已支付，开始开通...')
      step.value = 5
      await provision()
    } else {
      message.info('订单未支付或未到账，请稍后重试')
    }
  } catch (e) {
    message.error(String(e))
  } finally {
    checkingPay.value = false
  }
}

async function provision() {
  try {
    const payload = {
      productName: form.tenantName,
      domain: form.domain,
      email: form.email,
      phone: form.phone,
      username: form.phone,
      smsCode: form.smsCode,
      code: form.smsCode,
      description: JSON.stringify({
        product: selectedProduct.value?.code,
        months: durationMonths.value,
        orderNo: order.value?.orderNo
      })
    }

    const res = await request.post<ApiResult<unknown>>(SERVER_API_URL + '/superAdminRegister', payload)
    if (res.data.code !== 0) throw new Error(res.data.message || '开通失败')
    provisionInfo.value = (res.data.data || null) as any
    provisioned.value = true
  } catch (e) {
    provisioned.value = false
    message.error(String(e))
  }
}

type ProvisionUser = {
  tenantId?: number
  tenantName?: string | null
  username?: string
  phone?: string
  email?: string | null
} & Record<string, unknown>

type ProvisionInfo = {
  access_token?: string
  user?: ProvisionUser
} & Record<string, unknown>

const provisionInfo = ref<ProvisionInfo | null>(null)

function resetAll() {
  step.value = 0
  selectedProduct.value = null
  durationMonths.value = 12
  form.tenantName = ''
  form.domain = ''
  form.email = ''
  form.phone = ''
  form.smsCode = ''
  order.value = null
  payCodeUrl.value = ''
  payment.value = null
  provisioned.value = false
  provisionInfo.value = null
}
</script>

<style scoped>
.card-active {
  border-color: #16a34a;
  box-shadow: 0 0 0 2px rgba(22, 163, 74, 0.15);
}
</style>
