import { ScrollView, Text, Textarea, View, Input } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useMemo, useState } from 'react'
import { backend, type BackendExpertProfile, type BackendExpertSlot } from '@/api/backend'
import { EmptyState, MetaRow, Page, ProductImage } from '@/components/ui'
import { ensureLoggedIn, getToken, getUser } from '@/stores/storage'
import { tapLight, tapMedium } from '@/utils/feedback'
import { toast } from '@/utils/nav'

function formatDate(value?: string) {
  if (!value) return '-'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return '-'
  const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return `${date.getMonth() + 1}月${date.getDate()}日 ${weekdays[date.getDay()]}`
}

function formatTimeRange(slot?: BackendExpertSlot) {
  if (!slot) return '-'
  const start = new Date(slot.startsAt)
  const end = new Date(slot.endsAt)
  if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) return '-'
  return `${String(start.getHours()).padStart(2, '0')}:${String(start.getMinutes()).padStart(2, '0')}-${String(end.getHours()).padStart(2, '0')}:${String(end.getMinutes()).padStart(2, '0')}`
}

function groupSlots(slots: BackendExpertSlot[]) {
  const groups = new Map<string, BackendExpertSlot[]>()
  slots.forEach((slot) => {
    const label = formatDate(slot.startsAt)
    groups.set(label, [...(groups.get(label) || []), slot])
  })
  return Array.from(groups.entries()).map(([date, items]) => ({ date, slots: items }))
}

export default function ExpertBookingPage() {
  const [expert, setExpert] = useState<BackendExpertProfile | null>(null)
  const [slots, setSlots] = useState<BackendExpertSlot[]>([])
  const [selectedDate, setSelectedDate] = useState('')
  const [selectedSlotId, setSelectedSlotId] = useState('')
  const [contactName, setContactName] = useState('')
  const [contactPhone, setContactPhone] = useState('')
  const [background, setBackground] = useState('')
  const [question, setQuestion] = useState('')
  const [loading, setLoading] = useState(true)
  const [submitting, setSubmitting] = useState(false)

  useLoad((query) => {
    const slug = String(query.slug || query.expert || '')
    const redirect = `/pages/experts/booking/index?slug=${encodeURIComponent(slug)}`
    const user = ensureLoggedIn(redirect)
    if (!user) return
    setContactName(user.name || '')
    setContactPhone(user.contactPhone || user.phone || '')
    if (!slug) {
      toast('专家信息缺失')
      setLoading(false)
      return
    }
    setLoading(true)
    Promise.all([
      backend.expertDetail(slug),
      backend.expertSlots(slug, 'open')
    ])
      .then(([expertResult, slotResult]) => {
        const futureSlots = (slotResult.items || [])
          .filter((slot) => slot.status === 'open' && new Date(slot.startsAt).getTime() > Date.now())
          .sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime())
        setExpert(expertResult)
        setSlots(futureSlots)
        const first = futureSlots[0]
        if (first) {
          setSelectedDate(formatDate(first.startsAt))
          setSelectedSlotId(first.id)
        }
      })
      .catch((error) => toast(error instanceof Error ? error.message : '专家预约加载失败'))
      .finally(() => setLoading(false))
  })

  const schedules = useMemo(() => groupSlots(slots), [slots])
  const activeSchedule = schedules.find((item) => item.date === selectedDate)
  const selectedSlot = slots.find((slot) => slot.id === selectedSlotId)
  const canBook = Boolean(expert && selectedSlot && contactName.trim() && contactPhone.trim() && background.trim() && question.trim())

  async function submit() {
    const user = getUser()
    const token = getToken()
    if (!user || !token) {
      ensureLoggedIn('/pages/account/expert-bookings/index')
      return
    }
    if (!expert || !selectedSlot) {
      toast('请选择可预约时段')
      return
    }
    if (!contactName.trim() || !contactPhone.trim() || !background.trim() || !question.trim()) {
      toast('请补充联系人、电话、背景和问题')
      return
    }
    setSubmitting(true)
    try {
      const booking = await backend.createExpertBooking(token, {
        expertId: expert.id,
        slotId: selectedSlot.id,
        contactName: contactName.trim(),
        contactPhone: contactPhone.trim(),
        background: background.trim(),
        question: question.trim()
      })
      tapMedium()
      Taro.redirectTo({ url: `/pages/checkout/index?expertBookingId=${encodeURIComponent(booking.id)}` })
    } catch (error) {
      toast(error instanceof Error ? error.message : '预约创建失败')
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <Page title="预约专家" subtle={expert ? `${expert.name} · ${expert.organization || '大连市大数据研究院'}` : loading ? '正在读取专家排期' : undefined}>
      {expert && (
        <View className="booking-expert-head">
          <ProductImage className="booking-expert-photo" src={expert.photoUrl || 'expert'} />
          <View className="booking-expert-copy">
            <Text className="booking-expert-name">{expert.name}</Text>
            <Text className="booking-expert-meta">{expert.title || '专家咨询'} · {expert.organization || '大连市大数据研究院'}</Text>
          </View>
        </View>
      )}

      <View className="booking-step-tabs">
        {['联系信息', '选择时段', '咨询问题'].map((item, index) => <Text key={item} className="booking-step">{index + 1}. {item}</Text>)}
      </View>

      <View className="booking-section">
        <Text className="service-detail-section-title">联系信息</Text>
        <View className="booking-fields">
          <Input className="form-input" value={contactName} onInput={(event) => setContactName(String(event.detail.value))} placeholder="联系人" />
          <Input className="form-input" value={contactPhone} onInput={(event) => setContactPhone(String(event.detail.value))} placeholder="联系电话" />
        </View>
      </View>

      <View className="booking-section">
        <Text className="service-detail-section-title">选择时段</Text>
        {slots.length ? (
          <>
            <ScrollView scrollX className="booking-date-scroll">
              {schedules.map((schedule) => (
                <Text key={schedule.date} className={schedule.date === selectedDate ? 'booking-date active' : 'booking-date'} onClick={() => {
                  tapLight()
                  setSelectedDate(schedule.date)
                  setSelectedSlotId(schedule.slots[0]?.id || '')
                }}>{schedule.date}</Text>
              ))}
            </ScrollView>
            <View className="booking-slot-grid">
              {(activeSchedule?.slots || []).map((slot) => (
                <View key={slot.id} className={slot.id === selectedSlotId ? 'booking-slot active' : 'booking-slot'} onClick={() => {
                  tapLight()
                  setSelectedSlotId(slot.id)
                }}>
                  <Text>{formatTimeRange(slot)}</Text>
                </View>
              ))}
            </View>
          </>
        ) : (
          <EmptyState compact title={loading ? '正在读取时段' : '暂无可预约时段'} text={loading ? undefined : '可以稍后再看，或选择其他专家。'} />
        )}
      </View>

      <View className="booking-section">
        <Text className="service-detail-section-title">咨询问题</Text>
        <Textarea className="form-textarea booking-textarea" value={background} onInput={(event) => setBackground(String(event.detail.value))} placeholder="请简单说明项目背景、当前进展或已有材料" />
        <Textarea className="form-textarea booking-textarea" value={question} onInput={(event) => setQuestion(String(event.detail.value))} placeholder="希望专家重点回答什么问题" />
      </View>

      {selectedSlot && (
        <View className="booking-summary">
          <MetaRow label="预约时间" value={`${formatDate(selectedSlot.startsAt)} ${formatTimeRange(selectedSlot)}`} />
          <MetaRow label="咨询费用" value={expert?.priceAmount ? `¥${Math.round(expert.priceAmount / 100).toLocaleString()}/小时` : '待确认'} />
        </View>
      )}

      <View className="detail-spacer" />
      <View className="bottom-bar" style={{ gridTemplateColumns: '1fr' }}>
        <View className={canBook && !submitting ? 'primary-btn' : 'primary-btn disabled'} onClick={submit}>{submitting ? '提交中...' : '提交预约并支付'}</View>
      </View>
    </Page>
  )
}
