import { Checkbox, Image, Input, RichText, ScrollView, Text, Textarea, View } from '@tarojs/components'
import Taro, { useLoad } from '@tarojs/taro'
import { useMemo, useState } from 'react'
import { backend, type BackendExpertApplication, type BackendExpertDirection, type BackendFileRef, type BackendSiteAgreement } from '@/api/backend'
import { BottomDrawer, Page } from '@/components/ui'
import { ensureLoggedIn, getToken, getUser } from '@/stores/storage'
import { tapLight } from '@/utils/feedback'
import { toast } from '@/utils/nav'

type FormState = {
  name: string
  contactPhone: string
  organization: string
  title: string
  projectExperience: string
  representativeAchievements: string
  homepageIntro: string
}

const defaults: FormState = {
  name: '',
  contactPhone: '',
  organization: '',
  title: '',
  projectExperience: '',
  representativeAchievements: '',
  homepageIntro: ''
}

function statusLabel(status?: BackendExpertApplication['status']) {
  if (status === 'pending') return '审核中'
  if (status === 'approved') return '已通过'
  if (status === 'rejected') return '未通过'
  if (status === 'withdrawn') return '已撤回'
  return '未提交'
}

function fileNameFromPath(path: string, fallback: string) {
  const name = path.split('/').pop() || fallback
  return name.includes('.') ? name : fallback
}

function mimeFromName(name: string, fallback = 'application/octet-stream') {
  const lower = name.toLowerCase()
  if (lower.endsWith('.jpg') || lower.endsWith('.jpeg')) return 'image/jpeg'
  if (lower.endsWith('.png')) return 'image/png'
  if (lower.endsWith('.pdf')) return 'application/pdf'
  if (lower.endsWith('.doc')) return 'application/msword'
  if (lower.endsWith('.docx')) return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
  if (lower.endsWith('.zip')) return 'application/zip'
  return fallback
}

function applyToForm(application: BackendExpertApplication | null): FormState {
  const user = getUser()
  return {
    name: application?.name || user?.name || '',
    contactPhone: application?.contactPhone || user?.contactPhone || user?.phone || '',
    organization: application?.organization || user?.organization || '',
    title: application?.title || user?.title || '',
    projectExperience: application?.projectExperience || '',
    representativeAchievements: application?.representativeAchievements || '',
    homepageIntro: application?.homepageIntro || ''
  }
}

export default function ExpertJoinPage() {
  const [directions, setDirections] = useState<BackendExpertDirection[]>([])
  const [agreement, setAgreement] = useState<BackendSiteAgreement | null>(null)
  const [application, setApplication] = useState<BackendExpertApplication | null>(null)
  const [form, setForm] = useState<FormState>(defaults)
  const [selectedDirections, setSelectedDirections] = useState<string[]>([])
  const [photo, setPhoto] = useState<BackendFileRef | null>(null)
  const [attachments, setAttachments] = useState<BackendFileRef[]>([])
  const [acceptedRules, setAcceptedRules] = useState(false)
  const [showRules, setShowRules] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [uploading, setUploading] = useState(false)

  useLoad(() => {
    const user = ensureLoggedIn('/pages/experts/join/index')
    const token = getToken()
    if (!user || !token) return
    setForm((current) => ({
      ...current,
      name: current.name || user.name || '',
      contactPhone: current.contactPhone || user.contactPhone || user.phone || '',
      organization: current.organization || user.organization || '',
      title: current.title || user.title || ''
    }))
    void backend.expertDirections()
      .then((result) => setDirections(result.items.filter((item) => item.status !== 'disabled')))
      .catch(() => setDirections([]))
    void backend.siteAgreement('expert-cooperation-rules').then(setAgreement).catch(() => setAgreement(null))
    void backend.accountExpertApplication(token)
      .then((item) => {
        setApplication(item)
        setForm(applyToForm(item))
        setSelectedDirections(item?.directions || [])
        setAttachments(item?.attachments || [])
      })
      .catch(() => setApplication(null))
  })

  const groupedDirections = useMemo(() => directions.reduce<Record<string, BackendExpertDirection[]>>((result, item) => {
    const group = item.groupName || '专家方向'
    result[group] = [...(result[group] || []), item]
    return result
  }, {}), [directions])

  const readonly = Boolean(application && application.status !== 'rejected')
  const canEdit = !readonly

  function patch(key: keyof FormState, value: string) {
    setForm((current) => ({ ...current, [key]: value }))
  }

  function toggleDirection(name: string) {
    setSelectedDirections((current) => {
      if (current.includes(name)) return current.filter((item) => item !== name)
      if (current.length >= 3) {
        toast('最多选择 3 个专家方向')
        return current
      }
      return [...current, name]
    })
  }

  async function uploadLocalFile(filePath: string, fileName: string, mimeType?: string) {
    const token = getToken()
    if (!token) throw new Error('请先登录')
    return backend.uploadAccountFile(token, filePath, fileName, mimeType || mimeFromName(fileName))
  }

  async function choosePhoto() {
    try {
      setUploading(true)
      const result = await Taro.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['album', 'camera'] })
      const file = result.tempFiles?.[0]
      if (!file?.tempFilePath) return
      const fileName = fileNameFromPath(file.tempFilePath, 'expert-photo.jpg')
      const uploaded = await uploadLocalFile(file.tempFilePath, fileName, mimeFromName(fileName, 'image/jpeg'))
      setPhoto(uploaded)
      toast('照片已上传')
    } catch (error) {
      toast(error instanceof Error ? error.message : '照片上传失败')
    } finally {
      setUploading(false)
    }
  }

  async function chooseAttachments() {
    try {
      setUploading(true)
      const chooser = (Taro as unknown as { chooseMessageFile?: (options: Record<string, unknown>) => Promise<{ tempFiles?: Array<{ path: string; name: string; type?: string }> }> }).chooseMessageFile
      if (!chooser) {
        toast('当前环境不支持选择文件')
        return
      }
      const result = await chooser({ count: 5, type: 'file' })
      const uploaded: BackendFileRef[] = []
      for (const file of result.tempFiles || []) {
        uploaded.push(await uploadLocalFile(file.path, file.name || fileNameFromPath(file.path, 'attachment'), file.type || mimeFromName(file.name || 'attachment')))
      }
      setAttachments((current) => [...uploaded, ...current].slice(0, 8))
      toast('附件已上传')
    } catch (error) {
      toast(error instanceof Error ? error.message : '附件上传失败')
    } finally {
      setUploading(false)
    }
  }

  async function submit() {
    const token = getToken()
    if (!token) return
    if (!acceptedRules) {
      toast('请先同意专家合作规则')
      return
    }
    if (selectedDirections.length === 0 || selectedDirections.length > 3) {
      toast('专家方向需要选择 1-3 个')
      return
    }
    const photoUrl = photo?.url || application?.photoUrl || ''
    const photoFileId = photo?.id || application?.photoFileId || null
    if (!photoUrl) {
      toast('请上传专业照片')
      return
    }
    if (!form.name || !form.contactPhone || !form.organization || !form.title) {
      toast('请补充姓名、电话、机构和职务职称')
      return
    }
    setSubmitting(true)
    try {
      const saved = await backend.submitExpertApplication(token, {
        ...form,
        directions: selectedDirections,
        photoFileId,
        photoUrl,
        attachmentFileIds: attachments.map((item) => item.id)
      })
      setApplication(saved)
      setForm(applyToForm(saved))
      toast('专家申请已提交')
    } catch (error) {
      toast(error instanceof Error ? error.message : '专家申请提交失败')
    } finally {
      setSubmitting(false)
    }
  }

  if (readonly) {
    return (
      <Page title="申请成为专家" subtle={`申请状态：${statusLabel(application?.status)}`}>
        <View className="flow-success">
          <Text className="flow-success-mark">{application?.status === 'approved' ? '✓' : '…'}</Text>
          <Text className="flow-success-title">{application?.status === 'approved' ? '申请已通过' : '申请审核中'}</Text>
          <Text className="flow-success-copy">{application?.status === 'approved' ? '专家档案生成后可进入专家工作台管理排期和预约。' : '运营团队会审核你的方向、项目经验和附件材料。'}</Text>
        </View>
        <View className="flow-section">
          <Text className="flow-section-title">{application?.name || '专家申请'}</Text>
          <Text className="row-sub">{application?.organization} · {application?.title}</Text>
          <Text className="row-sub">专家方向：{(application?.directions || []).join('、') || '-'}</Text>
        </View>
        <View className="bottom-bar">
          <View className="primary-btn" onClick={() => Taro.redirectTo({ url: '/pages/account/expert-home/index' })}>查看专家工作台</View>
        </View>
      </Page>
    )
  }

  return (
    <Page title="申请成为专家" subtle={application?.status === 'rejected' ? `未通过：${application.rejectReason || '请补充资料后重新提交'}` : '提交资料后由运营审核'}>
      <View className="flow-section">
        <TextInput label="姓名" value={form.name} onChange={(value) => patch('name', value)} />
        <TextInput label="联系电话" value={form.contactPhone} onChange={(value) => patch('contactPhone', value)} />
        <TextInput label="所属机构" value={form.organization} onChange={(value) => patch('organization', value)} />
        <TextInput label="职务/职称" value={form.title} onChange={(value) => patch('title', value)} />
      </View>

      <View className="flow-section">
        <Text className="flow-section-title">专家方向</Text>
        <Text className="row-sub">最多选择 3 个。方向来自后台专家方向配置。</Text>
        {Object.entries(groupedDirections).map(([group, items]) => (
          <View key={group} className="direction-group">
            <Text className="flow-label standalone">{group}</Text>
            <ScrollView scrollX className="flow-chip-scroll">
              {items.map((item) => {
                const checked = selectedDirections.includes(item.name)
                return <Text key={item.id} className={checked ? 'flow-chip active' : 'flow-chip'} onClick={() => toggleDirection(item.name)}>{item.name}</Text>
              })}
            </ScrollView>
          </View>
        ))}
      </View>

      <View className="flow-section">
        <Text className="flow-section-title">照片与材料</Text>
        <View className="upload-row">
          {(photo?.url || application?.photoUrl) ? <Image className="expert-photo-preview" src={photo?.url || application?.photoUrl || ''} mode="aspectFill" /> : <View className="expert-photo-placeholder">照片</View>}
          <View className="ghost-btn compact" onClick={canEdit ? choosePhoto : undefined}>{uploading ? '上传中...' : '上传专业照片'}</View>
        </View>
        <View className="ghost-btn" onClick={canEdit ? chooseAttachments : undefined}>上传附件材料（选填）</View>
        {attachments.length > 0 && (
          <View className="file-list">
            {attachments.map((item) => (
              <View key={item.id} className="file-line">
                <Text>{item.fileName || item.id}</Text>
                <Text className="arrow">已上传</Text>
              </View>
            ))}
          </View>
        )}
      </View>

      <View className="flow-section">
        <TextAreaInput label="项目经验" value={form.projectExperience} placeholder="参与过的数字化、数据治理、产业研究或咨询项目" onChange={(value) => patch('projectExperience', value)} />
        <TextAreaInput label="代表成果" value={form.representativeAchievements} placeholder="报告、课题、案例、产品或可公开说明的成果" onChange={(value) => patch('representativeAchievements', value)} />
        <TextAreaInput label="专家主页展示简介" value={form.homepageIntro} placeholder="通过审核后展示在专家主页，可写擅长方向和服务特点" onChange={(value) => patch('homepageIntro', value)} />
      </View>

      <View className="flow-section">
        <View className="flow-check" onClick={() => { tapLight(); setAcceptedRules((value) => !value) }}>
          <Checkbox checked={acceptedRules} value="rules" />
          <Text>我已阅读并同意</Text>
          <Text className="link-text" onClick={(event) => { event.stopPropagation(); setShowRules(true) }}>《专家合作规则》</Text>
        </View>
      </View>

      <View className="detail-spacer" />
      <View className="bottom-bar">
        <View className="primary-btn" onClick={submit}>{submitting ? '提交中...' : application?.status === 'rejected' ? '重新提交申请' : '提交申请'}</View>
      </View>

      {showRules && (
        <BottomDrawer title={agreement?.title || '专家合作规则'} onClose={() => setShowRules(false)} className="agreement-drawer">
          <ScrollView scrollY className="agreement-scroll">
            {agreement?.content ? <RichText nodes={agreement.content} /> : <Text className="row-sub">专家合作规则暂未配置，请联系运营人员确认。</Text>}
          </ScrollView>
        </BottomDrawer>
      )}
    </Page>
  )
}

function TextInput({ label, value, placeholder, onChange }: { label: string; value: string; placeholder?: string; onChange: (value: string) => void }) {
  return (
    <View className="flow-field">
      <Text className="flow-label">{label}</Text>
      <Input className="flow-input" value={value} placeholder={placeholder || label} onInput={(event) => onChange(String(event.detail.value))} />
    </View>
  )
}

function TextAreaInput({ label, value, placeholder, onChange }: { label: string; value: string; placeholder?: string; onChange: (value: string) => void }) {
  return (
    <View className="flow-field">
      <Text className="flow-label">{label}</Text>
      <Textarea className="flow-textarea" value={value} placeholder={placeholder || label} onInput={(event) => onChange(String(event.detail.value))} />
    </View>
  )
}
