import { Text, View } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useState, type ReactNode } from 'react'
import { MetaRow, Page, ProductImage } from '@/components/ui'
import {
  backend,
  mapAgentProduct,
  mapCourseProduct,
  mapDataProduct,
  mapEventProduct,
  mapExpertProduct,
  type BackendAccessState,
  type BackendAgentProduct,
  type BackendCourseProduct,
  type BackendDataProduct,
  type BackendEventProduct,
  type BackendExpertProfile
} from '@/api/backend'
import { consultingProduct } from '@/constants/services'
import { addToCart, ensureLoggedIn, getUser } from '@/stores/storage'
import { toast } from '@/utils/nav'
import { tapLight, tapMedium } from '@/utils/feedback'
import type { ServiceProduct, UserProfile } from '@/types'

const emptyProduct: ServiceProduct = {
  id: '',
  type: 'course',
  title: '服务详情',
  subtitle: '正在加载',
  summary: '正在从后台加载服务信息。',
  price: 0,
  cover: 'course',
  category: '服务',
}

function servicePrice(item: ServiceProduct) {
  if (item.price === 0) return item.status || '提交需求'
  return `¥${item.price.toLocaleString()}`
}

function formatDateTime(value?: string | null) {
  if (!value) return ''
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return ''
  return `${date.getMonth() + 1}月${date.getDate()}日 ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
}

function compactItems(items?: Array<string | undefined | null>) {
  return (items || []).map((item) => String(item || '').trim()).filter(Boolean)
}

type CommerceMatrixProduct = {
  priceAmount?: number
  memberLevelRequired?: number
  registeredAccess?: BackendAccessState
  juniorAccess?: BackendAccessState
  seniorAccess?: BackendAccessState
  registeredPriceAmount?: number
  juniorPriceAmount?: number
  seniorPriceAmount?: number
}

function accessForLevel(product: CommerceMatrixProduct, level: number): BackendAccessState {
  const access = level >= 2 ? product.seniorAccess : level >= 1 ? product.juniorAccess : product.registeredAccess
  if (access) return access
  if (typeof product.memberLevelRequired === 'number' && level < product.memberLevelRequired) return 'closed'
  return (product.priceAmount || 0) === 0 ? 'free' : 'paid'
}

function priceForLevel(product: CommerceMatrixProduct, level: number) {
  const access = accessForLevel(product, level)
  if (access !== 'paid') return 0
  const cents = level >= 2
    ? product.seniorPriceAmount
    : level >= 1
      ? product.juniorPriceAmount
      : product.registeredPriceAmount
  return Math.round((cents ?? product.priceAmount ?? 0) / 100)
}

function lowestVisibleOffer(product: CommerceMatrixProduct) {
  const values = [0, 1, 2]
    .map((level) => {
      const access = accessForLevel(product, level)
      if (access === 'closed') return null
      return access === 'free' ? 0 : priceForLevel(product, level)
    })
    .filter((value): value is number => value !== null)
  return values.length ? Math.min(...values) : 0
}

function matrixBenefit(product: CommerceMatrixProduct) {
  const registered = accessForLevel(product, 0)
  const junior = accessForLevel(product, 1)
  const senior = accessForLevel(product, 2)
  if (registered === 'free' && junior === 'free' && senior === 'free') return '全员免费'
  if (registered === 'paid' && junior === 'free' && senior === 'free') return '会员免费，注册用户付费'
  if (registered === 'closed' && junior === 'free' && senior === 'free') return '初级/高级会员免费'
  if (registered === 'closed' && junior === 'paid' && senior === 'free') return '初级会员付费，高级会员免费'
  if (registered === 'closed' && junior === 'closed' && senior !== 'closed') return senior === 'free' ? '高级会员免费' : '高级会员开放'
  if (registered === 'paid' || junior === 'paid' || senior === 'paid') return '按身份开放与定价'
  return '限指定身份开放'
}

function membershipBlockLabel(product: CommerceMatrixProduct, level: number) {
  const required = product.memberLevelRequired ?? (accessForLevel(product, 1) !== 'closed' ? 1 : 2)
  if (level >= required) return '暂不可购买'
  return required >= 2 ? '高级会员专享' : '会员专享'
}

function realEventRegistered(eventProduct: BackendEventProduct) {
  return eventProduct.realRegisteredCount ?? Math.max((eventProduct.registeredCount || 0) - (eventProduct.initialRegisteredCount || 0), 0)
}

function commerceState(item: ServiceProduct, product: BackendCourseProduct | BackendEventProduct | null, user?: UserProfile | null) {
  if (!product) {
    return { price: item.price, disabled: false, label: item.price === 0 ? '免费获取' : `立即购买 ¥${item.price.toLocaleString()}`, benefit: item.status || '' }
  }
  const level = user?.membershipLevel || 0
  const access = accessForLevel(product, level)
  const price = priceForLevel(product, level)
  const isEvent = item.type === 'event'
  const eventProduct = isEvent ? product as BackendEventProduct : null
  const courseProduct = !isEvent ? product as BackendCourseProduct : null
  const full = eventProduct
    ? Boolean(eventProduct.capacity && realEventRegistered(eventProduct) >= eventProduct.capacity)
    : Boolean(courseProduct?.capacity && (courseProduct.registeredCount || 0) >= courseProduct.capacity)
  const closed = eventProduct ? eventProduct.registrationStatus === 'closed' || eventProduct.status === 'registration_closed' : false
  if (closed) return { price, disabled: true, label: '报名已关闭', benefit: matrixBenefit(product) }
  if (full) return { price, disabled: true, label: '名额已满', benefit: matrixBenefit(product) }
  if (access === 'closed') return { price, disabled: true, label: membershipBlockLabel(product, level), benefit: matrixBenefit(product) }
  const label = isEvent
    ? price === 0 ? '立即报名' : `报名 ¥${price.toLocaleString()}`
    : price === 0 ? '加入学习' : `立即购买 ¥${price.toLocaleString()}`
  return { price, disabled: false, label, benefit: matrixBenefit(product) }
}

function DetailHero({ item, meta }: { item: ServiceProduct; meta?: string }) {
  return (
    <View className="detail-hero">
      <ProductImage className="service-detail-cover" src={item.cover} />
      <View className="service-detail-head">
        <Text className="service-detail-kicker">{item.category || '服务'}</Text>
        <Text className="service-detail-title">{item.title}</Text>
        <Text className="service-detail-summary">{item.summary}</Text>
        <View className="detail-price-line">
          <Text className="service-detail-price">{servicePrice(item)}</Text>
          {meta && <Text className="detail-meta-text">{meta}</Text>}
        </View>
      </View>
    </View>
  )
}

function DetailSection({ title, children }: { title: string; children: ReactNode }) {
  return (
    <View className="service-detail-section">
      <Text className="service-detail-section-title">{title}</Text>
      {children}
    </View>
  )
}

function TextBlock({ children }: { children?: string }) {
  if (!children) return <Text className="service-detail-empty">暂无补充内容</Text>
  return <Text className="service-detail-text">{children}</Text>
}

function PointList({ items }: { items?: string[] }) {
  const values = compactItems(items)
  if (!values.length) return <Text className="service-detail-empty">暂无补充内容</Text>
  return (
    <View className="detail-point-list">
      {values.map((value, index) => (
        <View key={`${value}-${index}`} className="detail-point">
          <Text className="detail-point-index">{String(index + 1).padStart(2, '0')}</Text>
          <Text className="detail-point-text">{value}</Text>
        </View>
      ))}
    </View>
  )
}

function Tags({ items }: { items?: string[] }) {
  const tags = compactItems(items)
  if (!tags.length) return null
  return (
    <View className="detail-tags">
      {tags.map((tag) => <Text key={tag} className="detail-tag">{tag}</Text>)}
    </View>
  )
}

function MetaList({ rows }: { rows: Array<[string, string | number | undefined | null]> }) {
  return (
    <View className="service-meta-list">
      {rows.map(([label, value]) => <MetaRow key={label} label={label} value={value || '-'} />)}
    </View>
  )
}

function CourseDetail({ course }: { course: BackendCourseProduct }) {
  const modules = course.lessonModules?.length ? course.lessonModules : compactItems(course.modules).map((title, index) => ({
    id: `${index}`,
    title,
    description: '',
    videoUrl: '',
    materialUrl: '',
    durationMinutes: 0,
    sortOrder: index,
    status: 'published'
  }))
  const offer = lowestVisibleOffer(course)
  const capacityText = course.capacity ? `${course.registeredCount || 0}/${course.capacity}` : '不限'
  return (
    <>
      <DetailSection title="课程信息">
        <MetaList rows={[
          ['讲师', course.instructor || '研究院讲师'],
          ['课时', `${course.lessonCount || 0}课时`],
          ['形式', course.courseFormat || '-'],
          ['开课时间', formatDateTime(course.startsAt) || '随时学习'],
          ['地点', course.location || '线上'],
          ['名额', capacityText],
          ['权益', matrixBenefit(course)],
          ['起价', offer === 0 ? '免费' : `¥${offer.toLocaleString()}`]
        ]} />
      </DetailSection>
      <DetailSection title="你将学到">
        <PointList items={course.outcomes} />
      </DetailSection>
      <DetailSection title="课程大纲">
        <View className="detail-timeline">
          {modules.length ? modules.map((module, index) => (
            <View key={module.id || `${module.title}-${index}`} className="detail-timeline-row">
              <Text className="detail-timeline-mark">模块 {index + 1}</Text>
              <View className="detail-timeline-copy">
                <Text className="detail-timeline-title">{module.title}</Text>
                {module.durationMinutes ? <Text className="detail-timeline-sub">{module.durationMinutes} 分钟</Text> : null}
                {module.description ? <Text className="detail-timeline-sub">{module.description}</Text> : null}
              </View>
            </View>
          )) : <Text className="service-detail-empty">暂无课程大纲</Text>}
        </View>
      </DetailSection>
      <DetailSection title="适合人群">
        <TextBlock>{course.audience}</TextBlock>
      </DetailSection>
      <DetailSection title="学习权益">
        <TextBlock>{course.accessNote}</TextBlock>
      </DetailSection>
    </>
  )
}

function EventDetail({ eventProduct }: { eventProduct: BackendEventProduct }) {
  const realRegistered = realEventRegistered(eventProduct)
  const remaining = eventProduct.capacity ? Math.max(eventProduct.capacity - realRegistered, 0) : null
  const offer = lowestVisibleOffer(eventProduct)
  return (
    <>
      <DetailSection title="活动信息">
        <MetaList rows={[
          ['时间', `${formatDateTime(eventProduct.startsAt) || '-'}${eventProduct.endsAt ? ` - ${formatDateTime(eventProduct.endsAt)}` : ''}`],
          ['地点', eventProduct.isOnline ? '线上活动' : eventProduct.location || '-'],
          ['形式', eventProduct.eventFormat || '-'],
          ['主题', eventProduct.topic || '-'],
          ['名额', remaining === null ? '不限' : remaining > 0 ? `剩余 ${remaining}` : '已满'],
          ['报名热度', eventProduct.registeredCount || 0],
          ['权益', matrixBenefit(eventProduct)],
          ['费用', offer === 0 ? '免费' : `¥${offer.toLocaleString()}`]
        ]} />
      </DetailSection>
      <DetailSection title="活动亮点">
        <PointList items={eventProduct.highlights} />
      </DetailSection>
      <DetailSection title="活动安排">
        <View className="detail-timeline">
          {compactItems(eventProduct.agenda).length ? compactItems(eventProduct.agenda).map((item, index) => (
            <View key={`${item}-${index}`} className="detail-timeline-row">
              <Text className="detail-timeline-mark">环节 {index + 1}</Text>
              <Text className="detail-timeline-title">{item}</Text>
            </View>
          )) : <Text className="service-detail-empty">暂无活动安排</Text>}
        </View>
      </DetailSection>
      <DetailSection title="适合人群">
        <TextBlock>{eventProduct.audience}</TextBlock>
      </DetailSection>
    </>
  )
}

function AgentDetail({ agent }: { agent: BackendAgentProduct }) {
  return (
    <>
      <DetailSection title="适用场景">
        <Tags items={agent.scenarioTags} />
        {!agent.scenarioTags?.length && <Text className="service-detail-empty">暂无场景标签</Text>}
      </DetailSection>
      <DetailSection title="能解决什么">
        <TextBlock>{agent.detailDescription || agent.summary}</TextBlock>
      </DetailSection>
      <DetailSection title="交付说明">
        <TextBlock>{agent.deliveryNote || '购买后进入我的智能体，提交资料并查看交付进度。'}</TextBlock>
      </DetailSection>
    </>
  )
}

function DataDetail({ product }: { product: BackendDataProduct }) {
  return (
    <>
      <DetailSection title="案例信息">
        <MetaList rows={[
          ['服务归类', product.category || '-'],
          ['参考格式', product.fileFormat || '-'],
          ['服务方式', '提交需求后沟通报价'],
          ['案例附件', product.fileName || '按需提供']
        ]} />
      </DetailSection>
      <DetailSection title="案例目标">
        <TextBlock>{product.caseGoal || product.summary}</TextBlock>
      </DetailSection>
      <DetailSection title="典型需求">
        <TextBlock>{product.requestOutline}</TextBlock>
      </DetailSection>
      <DetailSection title="交付说明">
        <TextBlock>{product.deliveryOutline || product.serviceNote}</TextBlock>
      </DetailSection>
      <DetailSection title="服务标签">
        <Tags items={product.tags} />
        {!product.tags?.length && <Text className="service-detail-empty">暂无标签</Text>}
      </DetailSection>
    </>
  )
}

function ExpertDetail({ expert }: { expert: BackendExpertProfile }) {
  const directions = compactItems(expert.directions || expert.specialties)
  const status = expert.acceptingOrders === false
    ? '暂不接单'
    : expert.availabilityStatus === 'this-week'
      ? '本周可约'
      : expert.availabilityStatus === 'next-week'
        ? '下周可约'
        : '预约咨询'
  return (
    <>
      <DetailSection title="专家信息">
        <MetaList rows={[
          ['姓名', expert.name],
          ['职务职称', expert.title || '-'],
          ['所属机构', expert.organization || '-'],
          ['可约状态', status],
          ['咨询次数', expert.consultationCount || 0],
          ['参考价', expert.priceAmount ? `¥${Math.round(expert.priceAmount / 100).toLocaleString()}/小时` : '待确认']
        ]} />
      </DetailSection>
      <DetailSection title="专家方向">
        <Tags items={directions} />
      </DetailSection>
      <DetailSection title="专家简介">
        <TextBlock>{expert.homepageIntro || expert.bio}</TextBlock>
      </DetailSection>
      <DetailSection title="项目经验">
        <TextBlock>{expert.projectExperience}</TextBlock>
      </DetailSection>
      <DetailSection title="代表成果">
        <TextBlock>{expert.representativeAchievements}</TextBlock>
      </DetailSection>
    </>
  )
}

function ConsultingDetail() {
  return (
    <>
      <DetailSection title="服务说明">
        <TextBlock>{consultingProduct.summary}</TextBlock>
      </DetailSection>
      <DetailSection title="适用场景">
        <PointList items={['数字化规划与路线图设计', '数据治理、数据资源梳理与制度建设', '智慧城市、产业数字化和专项课题咨询', '项目立项、方案评审和专家论证支持']} />
      </DetailSection>
      <DetailSection title="交付流程">
        <View className="detail-timeline">
          {['提交咨询需求', '顾问联系确认范围', '形成方案与报价', '支付后进入服务执行', '交付报告或方案成果'].map((item, index) => (
            <View key={item} className="detail-timeline-row">
              <Text className="detail-timeline-mark">{index + 1}</Text>
              <Text className="detail-timeline-title">{item}</Text>
            </View>
          ))}
        </View>
      </DetailSection>
    </>
  )
}

export default function ProductDetailPage() {
  const [item, setItem] = useState<ServiceProduct>(emptyProduct)
  const [course, setCourse] = useState<BackendCourseProduct | null>(null)
  const [eventProduct, setEventProduct] = useState<BackendEventProduct | null>(null)
  const [dataProduct, setDataProduct] = useState<BackendDataProduct | null>(null)
  const [agentProduct, setAgentProduct] = useState<BackendAgentProduct | null>(null)
  const [expertProduct, setExpertProduct] = useState<BackendExpertProfile | null>(null)

  useLoad((query) => {
    const id = String(query.id || '')
    void loadProduct(id)
  })

  async function loadProduct(id: string) {
    setCourse(null)
    setEventProduct(null)
    setDataProduct(null)
    setAgentProduct(null)
    setExpertProduct(null)
    if (!id || id === consultingProduct.id || id === 'consulting') {
      setItem(consultingProduct)
      return
    }
    try {
      if (id.startsWith('course-')) {
        const result = await backend.courseProduct(id)
        setCourse(result)
        setItem(mapCourseProduct(result))
        return
      }
      if (id.startsWith('event-')) {
        const result = await backend.eventProduct(id)
        setEventProduct(result)
        setItem(mapEventProduct(result))
        return
      }
      if (id.startsWith('data-')) {
        const result = await backend.dataProduct(id)
        setDataProduct(result)
        setItem(mapDataProduct(result))
        return
      }
      if (id.startsWith('agent-')) {
        const result = await backend.agentProduct(id)
        setAgentProduct(result)
        setItem(mapAgentProduct(result))
        return
      }
      if (id.startsWith('expert-')) {
        const result = await backend.expertDetail(id.replace(/^expert-/, ''))
        setExpertProduct(result)
        setItem(mapExpertProduct(result))
      }
    } catch (error) {
      toast(error instanceof Error ? error.message : '服务详情加载失败')
    }
  }

  function currentCommerceState(user = getUser()) {
    return commerceState(item, course || eventProduct, user)
  }

  function add() {
    const user = ensureLoggedIn(`/pages/services/detail/index?id=${item.id}`)
    if (!user) return
    const state = currentCommerceState(user)
    if (state.disabled) {
      toast(state.label)
      return
    }
    tapLight()
    addToCart({ id: item.id, type: item.type, title: item.title, price: state.price, subtitle: `${item.subtitle} · ${state.benefit}`, cover: item.cover })
    toast('已加入购物车')
  }

  function buy() {
    const user = ensureLoggedIn(`/pages/services/detail/index?id=${item.id}`)
    if (!user) return
    if (item.type === 'data') {
      tapMedium()
      Taro.navigateTo({ url: `/pages/data-service/detail/index?id=${encodeURIComponent(item.id)}` })
      return
    }
    if (item.type === 'consulting') {
      tapMedium()
      Taro.navigateTo({ url: '/pages/consulting/index' })
      return
    }
    if (item.type === 'expert') {
      const slug = expertProduct?.slug || item.id.replace(/^expert-/, '')
      tapMedium()
      Taro.navigateTo({ url: `/pages/experts/booking/index?slug=${encodeURIComponent(slug)}` })
      return
    }
    const state = currentCommerceState(user)
    if (state.disabled) {
      toast(state.label)
      return
    }
    tapMedium()
    addToCart({ id: item.id, type: item.type, title: item.title, price: state.price, subtitle: `${item.subtitle} · ${state.benefit}`, cover: item.cover })
    Taro.navigateTo({ url: '/pages/checkout/index' })
  }

  const commerce = currentCommerceState()
  const heroItem = course || eventProduct
    ? { ...item, price: commerce.price, status: commerce.price === 0 ? commerce.benefit : item.status }
    : item
  const canCart = (item.type === 'course' || item.type === 'event' || item.type === 'agent') && !commerce.disabled
  const primaryText = item.type === 'data'
    ? '我要类似数据'
    : item.type === 'consulting'
      ? '提交咨询需求'
      : item.type === 'expert'
        ? '选择时段预约'
        : commerce.label

  return (
    <Page title="服务详情" subtle={item.subtitle}>
      <View className="service-detail">
        <DetailHero item={heroItem} meta={item.location || item.startsAt || item.duration} />

        {course && <CourseDetail course={course} />}
        {eventProduct && <EventDetail eventProduct={eventProduct} />}
        {agentProduct && <AgentDetail agent={agentProduct} />}
        {dataProduct && <DataDetail product={dataProduct} />}
        {expertProduct && <ExpertDetail expert={expertProduct} />}
        {item.type === 'consulting' && <ConsultingDetail />}
      </View>

      <View className="detail-spacer" />
      <View className="bottom-bar service-bottom-bar" style={{ gridTemplateColumns: canCart ? '1fr 1fr' : '1fr' }}>
        {canCart && <View className="ghost-btn" onClick={add}>加入购物车</View>}
        <View className={commerce.disabled && (item.type === 'course' || item.type === 'event') ? 'primary-btn disabled' : 'primary-btn'} onClick={buy}>{primaryText}</View>
      </View>
    </Page>
  )
}
